Zweitgrößten Wert im Array finden

Zweitgrößten Wert im Array finden

Ich habe ein Array wie dieses:

array=(1 2 7 6)

und möchte nach dem zweitgrößten Wert suchen, wobei die Ausgabe lautet

secondGreatest=6

Gibt es eine Möglichkeit, dies in Bash zu tun?

Antwort1

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

Drucken Sie jeden Wert des Arrays in einer eigenen Zeile, sortieren Sie ihn, holen Sie sich die letzten beiden Werte und entfernen Sie den letzten Wert

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

Legen Sie diesen Wert für die secondGreatestVariable fest.


Glenn Jackman hatte einen hervorragenden Punkt zu doppelten Zahlen, den ich nicht berücksichtigt habe. Wenn Sie nur an eindeutigen Werten interessiert sind, können Sie das -uFlag of Sort verwenden:

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

Antwort2

Eine bash-spezifische Schleife durch das Array könnte dies tun; Sie müssen den größten und den zweitgrößten Wert im Auge behalten. Der einzige andere schwierige Teil ist, beim Initialisieren dieser Werte vorsichtig zu sein; der größte Wert wird mit dem ersten Element initialisiert; der zweitgrößte Wert wird initialisiert, wenn wir zum ersten Mal einen Wert sehen, der kleiner als der größte Wert ist. Anschließend aktualisieren wir den zweitgrößten Wert nur, wenn er strikt kleiner als der aktuell größte Wert ist:

#!/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"

Dies ist immer noch langsamer als der Aufruf von , bietet aber den zusätzlichen Vorteil, dass bei mehreren hohen Werten (wie z. B. und höher) sortder strikt kleinere zweitgrößte Wert ausgewählt wird .77

Antwort3

Es ist ein guter Job für dc:

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

verwandte Informationen