轨道
/
AWK
AWK
/
练习
/
高分榜
高分榜

高分榜

简单

说明

管理游戏玩家的最高分列表。

你的任务是为经典游戏 Frogger 构建一个最高分组件。Frogger 是有史以来最畅销、最容易让人上瘾的游戏之一,也是街机时代的经典之作。 你的任务是编写方法,返回数组中的最高分、最后添加的分数和三个最高分。

在 AWK 中排序

这个练习要求输出按特定方式排序。 和许多编程语言一样,遍历数组的顺序取决于具体实现,看起来像是随机的。 这通常不是人希望看到的结果。 GNU awk 提供了一些排序功能。

  1. asort:根据数组的_值_对以数字索引的数组进行排序。

    #!gawk 
    BEGIN {
        for (i = 1; i <= 5; i++)
            nums[i] = int(100 * rand())
    
        # returns the array size
        n = asort(nums, sorted)
    
        for (i = 1; i <= n; i++)
            print i, nums[i], sorted[i]
    }
    

    输出如下

    1 92 30
    2 59 57
    3 30 59
    4 57 74
    5 74 92
    

    n = asort(array) 这种形式会就地排序指定的数组。

    这对以数字索引的数组最有用。 填充sorted数组的过程会丢弃原数组的下标: sorted数组的下标从 1 到n。

  2. asorti:根据数组的_下标_对数组进行排序。

    asorti 函数会填充一个“目标”数组,其中包含排好序的“源”数组下标。

    #!gawk
    BEGIN {
        nums["foo"] = int(100 * rand())
        nums["bar"] = int(100 * rand())
        nums["qux"] = int(100 * rand())
    
        print "unordered"
        for (i in nums)
            print i, nums[i]
    
        print "ordered by index"
        n = asorti(nums, sorted)
        for (i = 1; i <= n; i++)
            print sorted[i], nums[sorted[i]]
    }
    

    输出如下

    unordered
    foo 92
    qux 30
    bar 59
    ordered by index
    bar 59
    foo 92
    qux 30
    
  3. PROCINFO["sorted_in"]:按指定顺序遍历数组。

    内置的 PROCINFO 数组包含大量关于当前运行的 awk 进程的信息。 这个数组中有一个有趣的元素是sorted_in。 这个数组键的值是一个函数的名称,该函数控制 for (indx in array) 循环处理数组下标的顺序。

    这个函数可以是用户自定义函数的名称,也可以是一些方便的预定义排序函数,包括:

    • "@ind_str_asc"、"@ind_str_desc":按下标排序;采用字母顺序;可升序或降序。
    • "@ind_num_asc"、"@ind_num_desc":按下标排序;采用数值顺序;可升序或降序。
    • "@val_str_asc"、"@val_str_desc":按值排序;采用字母顺序;可升序或降序。
    • "@val_num_asc"、"@val_num_desc":按值排序;采用数值顺序;可升序或降序。

    上面的 asort 示例可以这样实现:

    PROCINFO["sorted_in"] = "@val_num_asc"
    for (idx in nums)
        print idx, nums[idx]
    
    3 30
    4 57
    2 59
    5 74
    1 92
    

    asorti 示例可以写成:

    PROCINFO["sorted_in"] = "@ind_str_asc"
    for (idx in nums)
        print idx, nums[idx]
    
    bar 59
    foo 92
    qux 30
    

    这种方法让我们无需使用临时的sorted数组和n返回值。 干净利落。

用户自定义排序函数

用户自定义排序函数接受 4 个参数: 一个数组元素的下标和值,以及另一个数组元素的下标和值:

function compare(idx1, val1, idx2, val2) {...}

返回值是:

  • 小于零:idx1 排在 idx2 前面
  • 大于零:idx1 排在 idx2 后面
  • 等于零:两个下标具有相同的排序优先级,但它们的相对顺序是不确定的。

除了用 PROCINFO["sorted_in"] 控制 for (idx in array) 的顺序之外,asort 和 asorti 都可以把一个比较函数的名称作为第 3 个参数。

参考资料


来源

致敬八十年代的街机游戏 Frogger
通过 GitHub 编辑 链接将在新窗口或新标签页中打开
AWK Exercism

准备好开始 高分榜 了吗?

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