k-a-v Asked: 2019-01-24 05:05:54 +0800 CST2019-01-24 05:05:54 +0800 CST 2019-01-24 05:05:54 +0800 CST 查找数组中的第二大值 772 我有一个这样的数组: array=(1 2 7 6) 并想搜索第二大值,输出为 secondGreatest=6 有没有办法在bash中做到这一点? bash bash-array 3 个回答 Voted Best Answer jesse_b 2019-01-24T05:16:47+08:002019-01-24T05:16:47+08:00 printf '%s\n' "${array[@]}" | sort -n | tail -2 | head -1 在自己的行上打印数组的每个值,对其进行排序,获取最后两个值,删除最后一个值 secondGreatest=$(printf '%s\n' "${array[@]}" | sort -n | tail -2 | head -1) 将该值设置为secondGreatest变量。 格伦杰克曼对重复数字有一个很好的观点,我没有考虑过。如果您只关心唯一值,则可以使用-u排序标志: secondGreatest=$(printf '%s\n' "${array[@]}" | sort -nu | tail -2 | head -1) Jeff Schaller 2019-01-24T06:38:01+08:002019-01-24T06:38:01+08:00 通过数组的特定于 bash 的循环可以做到这一点;您必须跟踪最大的和第二大的。唯一另一个棘手的部分是在初始化这些值时要小心。最大值被初始化为第一个元素;当我们第一次看到小于最大值的值时,第二大的值被初始化。随后对于第二大值,我们仅在严格小于当前最大值时才更新它: #!/bin/bash array=(7 7 6 2 1) if [ "${#array[@]}" -lt 2 ] then echo Incoming array is not large enough >&2 exit 1 fi largest=${array[0]} secondGreatest='unset' for((i=1; i < ${#array[@]}; i++)) do if [[ ${array[i]} > $largest ]] then secondGreatest=$largest largest=${array[i]} elif (( ${array[i]} != $largest )) && { [[ "$secondGreatest" = "unset" ]] || [[ ${array[i]} > $secondGreatest ]]; } then secondGreatest=${array[i]} fi done echo "secondGreatest = $secondGreatest" 它仍然比调用 慢sort,但它具有在面对多个高值(例如7及7以上)时选择严格较小的第二大值的额外好处。 ctac_ 2019-01-24T11:32:18+08:002019-01-24T11:32:18+08:00 这对 dc 来说是个好工作: array=(1 2 7 6) echo ${array[*]} | dc -f - -e ' [lasbdsa]sB [dla!>Bsc1z>A]sA lAx [secondGreatest=]nlbp'
在自己的行上打印数组的每个值,对其进行排序,获取最后两个值,删除最后一个值
将该值设置为
secondGreatest
变量。格伦杰克曼对重复数字有一个很好的观点,我没有考虑过。如果您只关心唯一值,则可以使用
-u
排序标志:通过数组的特定于 bash 的循环可以做到这一点;您必须跟踪最大的和第二大的。唯一另一个棘手的部分是在初始化这些值时要小心。最大值被初始化为第一个元素;当我们第一次看到小于最大值的值时,第二大的值被初始化。随后对于第二大值,我们仅在严格小于当前最大值时才更新它:
它仍然比调用 慢
sort
,但它具有在面对多个高值(例如7
及7
以上)时选择严格较小的第二大值的额外好处。这对 dc 来说是个好工作: