初学者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"`
正在编写一个小脚本,将随机数放入一个 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"`