查找数组中第二大的值

查找数组中第二大的值

我有一个像这样的数组:

array=(1 2 7 6)

并想搜索第二大的值,输出为

secondGreatest=6

有什么办法可以在 bash 中做到这一点吗?

答案1

printf '%s\n' "${array[@]}" | sort -n | tail -2 | head -1

在其自己的行上打印数组的每个值,对其进行排序,获取最后 2 个值,删除最后一个值

secondGreatest=$(printf '%s\n' "${array[@]}" | sort -n | tail -2 | head -1)

将该值设置为secondGreatest变量。


格伦·杰克曼(Glenn Jackman)关于重复数字的观点非常精彩,但我没有考虑到。如果您只关心唯一值,您可以使用-u排序标志:

secondGreatest=$(printf '%s\n' "${array[@]}" | sort -nu | tail -2 | head -1)

答案2

通过数组进行特定于 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"

它仍然比调用 to 慢sort,但它具有在面对多个高值(例如77以上)时选择严格较小的第二大值的额外好处。

答案3

这对 dc 来说是一份好工作:

array=(1 2 7 6)
echo ${array[*]} | dc -f - -e '
  [lasbdsa]sB
  [dla!>Bsc1z>A]sA
  lAx
  [secondGreatest=]nlbp'

相关内容