找出數組中第二大的值

找出數組中第二大的值

我有一個像這樣的陣列:

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'

相關內容