初学者Shell,找不到问题(数组排序)

Beginner Shell, can't find the issue (array sorting)

正在编写一个小脚本,将随机数放入一个 10 000 大小的数组中,然后在课程中使用方法 ask 对所有数组进行排序。

我已经完成了这段代码,但它似乎开始排序(当我测试时,我打印了一些 "a" 但没有预期的那么多,我不明白为什么)

我相信问题出在我对 val 数组的测试上,这可能是一个初学者错误,但我真的不知道如何在网上找到问题,因为我现在真的不知道哪一行是问题。

我不一定需要答案,只要找到一些线索就可以了:)

这是我的代码:(Whosebug 的新手所以我不知道如何直接放置一个好的代码视图,如果有人可以告诉我的话)

for i in `seq 1 10000`;
do
    val[${i}]=$RANDOM
done
echo `date +"%M.%S.%3N"`

FLAG=0
until [ $FLAG -eq 1 ]
do
    FLAG=1
    for j in `seq 1 9999`;
    do
        if [ ${val[${j}]} -gt ${val[${j+1}]} ]
        then
            TMP=${val[${j}]}
            val[${j}]=${val[${j+1}]}
            val[${j+1}]=$TMP
            FLAG=0
            echo a
        fi
    done
done

echo `date +"%M.%S.%3N"`

正如所问,我真的无法获得有用的输出,因为我只想要排序操作前后的日期。但是这种排序只是应该通过将值两个两个地从低到高放在一起,并在必要时反转它们。这样做直到没有数字被反转。

编辑:我尝试使用手册编号: 10 3 6 9 1

当 运行 通过将 echo ${val[*]} 放入 for 循环时,它只会以相同的顺序打印 4 次相同的列表,所以我猜它不起作用所有...我对 "if" 的使用是错误的吗?

编辑2:一开始是用C#做的,后来想用shell做,一是想练习一下shell,二是想比较效率和做同一件事所需的时间。这是正在运行的 C# 代码。

            Random random = new Random();
            int[] _tab = new int[100000];
            for (int i = 0; i < _tab.Length; i++)
            {
                _tab[i] = random.Next(1, _tab.Length);
            }

            bool perm;
            int tmp;
            DateTime dt = DateTime.Now;
            do
            {
                perm = false;
                for (int i = 0; i < (_tab.Length - 1); i++)
                {
                    if (_tab[i] > _tab[i + 1])
                    {
                        tmp = _tab[i];
                        _tab[i] = _tab[i + 1];
                        _tab[i + 1] = tmp;
                        perm = true;
                    }
                }
            }
            while (perm == true);

            Console.WriteLine((DateTime.Now - dt).TotalMilliseconds);
            Console.Read();

谢谢:)

如果我的理解是您想知道为什么这个脚本没有生成一个“a”来指示最初在“for”循环中生成的数字数组的顺序是正确的,那么这里是一个解决方案:

您的变量扩展语法不正确${var} 大括号内不能有数学运算符,因为它们在这里有不同的含义。在普通的非关联数组中,Zsh 处理具有一些基本数学支持的下标,因此您可以像以前那样使用 ${array[var+1]} 而不是 ${array[${var+1}]}

我怀疑出现这种情况的原因 - 复杂、容易出错的 POSIX 语法 - 可以通过使用简化的 Zsh 语法来避免,但正如之前评论中所述,它不能移植到其他 shell .

一些 shell 支持类似的功能:Bash 支持大多数,但不支持裸下标 ($array[var])。 Zsh 中的字符串可能以类似的方式排序,但是数学上下文括号 (()) 必须替换为正常的测试括号 [[]] 以及数组 $val 可能必须使用特殊的 typeset 选项来定义,以使字符串以所需的方式进行比较;也就是说,它们可能必须被填充并右对齐或左对齐。对于枚举类型的比较,例如 Jan - Feb,使用关联数组和大小写转换会稍微复杂一些。

这是经过适当更改的脚本,然后再次使用简化的 Zsh:

#!/bin/sh
for i in `seq 1 10000`;
do
    val[$((i))]=$RANDOM
done
echo `date +"%M.%S.%3N"`

FLAG=0
until [ $FLAG -eq 1 ]
do
    FLAG=1
    for j in `seq 1 9999`;
    do
        if [ ${val[$((j))]} -gt ${val[$((j+1))]} ]
        then
            TMP=${val[$((j))]}
            val[$((j))]=${val[$((j+1))]}
            val[$((j+1))]=$TMP
            FLAG=0
            echo a
        fi
    done
done

echo `date +"%M.%S.%3N"`

Zsh:

#!/bin/zsh
foreach i ( {1..10000} )
    val[i]=$RANDOM
end
echo `date +"%M.%S.%3N"`

FLAG=0
until ((FLAG))
do
    FLAG=1
    foreach j ( {1..9999} )
        if (( val[j] > val[j+1] ))
        then
            TMP=$val[j]
            val[j]=$val[j+1]
            val[j+1]=$TMP
            FLAG=0
            echo a
        fi
    end
done

echo `date +"%M.%S.%3N"`