我正在尝试为 awk 语言编写一段代码来计算两个自然数的最大公约数,但到目前为止我的尝试失败了。
我将非常感谢您的帮助。
我的尝试:
awk '{ a = 5, b = 10
while (a!=0 and b!=0){
if (a > b) { a = a % b }
else { b = b % a}
}
}'
print (a+b)
来自 https://rosettacode.org/wiki/类别:AWK
function gcd(p,q){return(q?gcd(q,(p%q)):p)}
修复脚本中的语法和语义错误会产生:
awk '
BEGIN {
a = 5
b = 10
while ( (a!=0) && (b!=0) ) {
if (a > b) {
a = a % b
}
else {
b = b % a
}
}
print (a+b)
}
'
5
如果算法错误,则在 https://www.programiz.com/c-programming/examples/hcf-gcd 上搜索“两个自然数代码的最大公约数”会生成多个示例,其中包括 3 个示例。只需对其中一个进行非常小的调整(即去掉变量声明、第一个 printf 和 scanf),以使用 awk 而不是 C 语法来处理硬编码值。
这是我在自己的图书馆中使用的。额外的复杂性是由于标准
gcd()
算法的递归和迭代变体花费了相当多的循环周期非常接近于零,尽管它相对直接地推导出正确的结果。
添加的优化指示此
do { ... } while(..)
函数中的主 awk
循环在较小绝对值小于 6 时结束,在 return
语句中用几个循环周期换取三元。
function gcd(_, __, ___) {
# _| 1st value \
# | number or numeric-string, auto integer truncated
# __| 2nd value /
# |
# |--> gcd(abs(_), abs(__))
if ((___ = ((__ = int(__)) >= !!__ ? __ : __ = -__) \
) <= ((_ = int(_)) < !_ ? _ = -_ : _) &&
(__ = _) == (_ = ___))
return _
if ((___ += (___ = !!__) + ++___) < _)
do _ = __ % (__ = _)
while (___ < _)
return _ - !!_ ? (_ == (__ %= _) * __) + _^!__ : __^!_
}
awk
没有“元组”的概念,推而广之,不能在每一步使用元组赋值来交换被除数和除数。使用这个
POSIX
兼容的
awk
构造可以实现类似的交换,无需分支或任何临时变量:
a = b % (b = a)
Dividend b
始终使用其预先覆盖的值,如
POSIX
规范中的关联性规则所保证。