轨道
/
AWK
AWK
/
练习
/
矩阵
矩阵

矩阵

中等

说明

给定一个表示数字矩阵的字符串,返回该矩阵的行和列。

例如,给定下面这个包含换行符的字符串:

9 8 7
5 3 2
6 6 7

它表示这个矩阵:

    1  2  3
  |---------
1 | 9  8  7
2 | 5  3  2
3 | 6  6  7

你的代码应该能输出:

  • 一个包含所有行的数组,从上到下逐行移动,每行从左到右读取,
  • 一个包含所有列的数组,从左到右逐列移动,每列从上到下读取。

我们这个示例矩阵的行:

  • 9, 8, 7
  • 5, 3, 2
  • 6, 6, 7

它的列:

  • 9, 5, 6
  • 8, 3, 6
  • 7, 2, 7

AWK 的新概念

这是第一个提交的解答不是“main”脚本的练习。 目标是写一个函数库,供其他 awk 程序引入。 这个练习里有几个有意思的新概念。

下面标记为“(gawk)”的小节都是 GNU awk 特有的扩展。

从文件读取

在这个练习里,你要从文件读取数据,而不是从主输入流。 阅读 Gnu awk 手册里关于 getline 的内容,尤其是 Getline/File 和 Getline/Variable/File 这两种形式。

关于数组的更多内容

二维数组也许是实现这个提交的解答的一种方式。 GNU awk 有两种表示方式:

引入文件 (gawk)

注意测试文件里的 @include 指令。
它会指示 gawk 读取并求值指定的文件。

命名空间 (gawk)

所有 awk 变量都是全局的(函数形参除外,它们是函数局部的)。 出现命名冲突的可能性很大,尤其是在引入第三方库的时候。 命名空间 是划分变量存储位置的一种方式。 注意练习文件里的 @namespace 指令。

默认命名空间的名字是“awk”。 有了默认命名空间,程序员就可以在另一个命名空间的函数里调用 awk 的内置函数。

函数参数是如何传递的

数组参数是按引用传递的。 函数里对数组所做的修改,调用方是看得见的。

非数组参数是按值传递的。

对于_未定类型_的参数,要看函数拿它们做什么:

  • 如果函数把它初始化成数组,它就变成按引用传递的参数,
  • 如果函数把它初始化成标量值(数字或字符串),那它就不是引用。

完整细节见手册中的按值或按引用传递函数参数。

局部变量

用“按值传递”的形参可以创建函数作用域(局部)的变量。 传给函数的值比形参列表里的形参少并不算错误;多出来的那些形参在被使用之前都是“未定类型”的。 它们可以在函数里被赋标量值,而这些值不会存进全局命名空间。

  • 如果你给某个形参赋标量值,那它是函数局部的。
  • 如果你给一个不在形参列表里的变量赋标量值,那个变量就是全局的。

按惯例,函数签名里先写要用的形参,然后是若干空白,接着是局部参数。 例如:

function add(a, b,    total) {
    # here, `typeof(total)` is "untyped"
    total = a + b
    # now, `typeof(total)` is "number"
    return total
}

BEGIN {
    sum = add(5, 10)
    print sum             # 15
    print typeof(total)   # untyped, meaning "total" is unused in this scope
}
通过 GitHub 编辑 链接将在新窗口或新标签页中打开
AWK Exercism

准备好开始 矩阵 了吗?

注册 Exercism,借助 3 个概念92 个练习 和真人导师指导,学习并掌握 AWK,全部免费。