You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWK脚本提取质数异常:输出结果不符预期求排查

AWK质数检测脚本问题排查

我编写了一段AWK脚本,用于提取文件中的质数并打印,代码如下:

#!/bin/awk -f

function is_prime(n) {
    if (n <= 1) return 0;
    if (n == 2) return 1;
    for (i = 2; i <= sqrt(n); i++) {
        if (n % i == 0) {
            return 0;
        }
    }
    return 1;
}

{
    gsub(/[^[:digit:]]/, " ");
    for (i = 1; i <= NF; i++) {
        if (is_prime($i)) {
            print $i;
        }
    }
}

测试文件内容:

Math is179day foun193dary 
18
nachum17
19

预期输出:

179
193
17
19

实际输出:

14
5
5

补充:调整print语句后,甚至只输出3行空白,没有数字。


问题根源

  1. 变量作用域冲突:AWK中函数内未声明的变量默认是全局变量。is_prime函数使用了全局变量i,而主循环中也用i作为字段索引。调用is_prime时,函数会修改全局i的值,导致主循环遍历逻辑混乱,这是输出错误数字的核心原因。
  2. 浮点精度问题:使用sqrt(n)作为循环上限,sqrt返回浮点数,可能因精度丢失导致循环提前终止,无法正确判断质数。

修正后的代码

#!/bin/awk -f

function is_prime(n,    i) {  # 声明局部变量i,避免全局作用域冲突
    if (n <= 1) return 0;
    if (n == 2) return 1;
    if (n % 2 == 0) return 0;  # 提前排除偶数,优化性能
    for (i = 3; i*i <= n; i += 2) {  # 用i*i <=n替代sqrt,消除浮点精度问题
        if (n % i == 0) {
            return 0;
        }
    }
    return 1;
}

{
    gsub(/[^[:digit:]]/, " ");
    for (j = 1; j <= NF; j++) {  # 主循环改用j作为索引,彻底避免变量重名
        if (is_prime($j)) {
            print $j;
        }
    }
}

修正说明

  • 在is_prime函数参数列表后添加, i,将i声明为局部变量,隔绝全局作用域干扰。
  • 主循环索引改用j,彻底避免和函数内变量重名的问题。
  • 用i*i <= n替代i <= sqrt(n),消除浮点计算带来的精度误差。
  • 新增偶数判断逻辑,提前排除大于2的偶数,优化质数判断的执行效率。

内容的提问来源于stack exchange,提问作者Nessya Nakache

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 05:22:09