在bash阵列中获取最常见的数字



我需要在数组中找到最常见的数字。我这样做了:

# our array, the most frequent value is 55
declare -a array=(44 55 55 55 66 66)
# counting unque string with uniq and then sorting as numbers
array=($(printf "%sn" "${array[@]}"| uniq -c | sort -n -r))
# printing 2nd element of array, as the first one - number of occurencies
printf ${array[1]}

这是一种更好/更美丽的方法,而不是构建一个奇怪的数组(第二步(,而怪异的数组则构成了混合的数字和数字?

我做得正确吗?(uniq在2列中返回值,因此我不确定它如何选择列(

如果我必须在 bash中这样做,我会使用 awk跳过任何东西,只计算元素:

printf '%sn' "${array[@]}" | awk '{
     if (++arr[$0] > max) {
       max=arr[$0];
       ans=$0
     }
   } 
   END {print ans}'

您还可以使用关联数组在bash 4或更高版本中实现相同的算法:

# These don't strictly need to be initialized, but it's safer
# to ensure they don't already have values.
declare -A counts=()
max=0
ans=
for i in "${array[@]}"; do
  if ((++counts[$i] > max)); then
    max=${counts[$i]}
    ans=$i
  fi
done
printf '%sn' "$ans"

如果您不想使用 awk 来执行此操作,您仍然可以使用 sort uniq 但要小心,您需要在计数之前对已输入已经对其进行排序。否则它将不起作用。例如:

declare -a array=(34 3 45 45 66 55 44 55 55 55 66 45 45 8 6 45 45 66 32 9 18)
printf "%sn" "${array[@]}" | sort -n -r | uniq -c | sort -n -r | head -1 | awk '{print $2}'

在给定输入中,代码正确提取最重复的数字,但是在示例中,您给出的数字无效,并且它将说55是最重复的数字,尽管那是错误的,因为它显然是45,但是 uniq 仅计数连续项目,如果它们稀疏,则会错误地计算它们。

regads!

使用bash V4 上的关联数组的Chepner逻辑的更多详细版本。我们将关联数组hashMap构建为键作为数组元素及其事件的数量作为值。构建数组后,我们从具有最大计数并检索其值的数组中找到。

#!/usr/bin/env bash
declare -a array=(44 55 55 55 66 66)
declare -A hashMap
declare -i max=0
for element in "${array[@]}"; do
    ((hashMap["$element"]++))
done
for key in "${!hashMap[@]}"; do
    (( "${hashMap[$key]}" > max )) && { max="${hashMap[$key]}"; element="$key" ; }
done
printf '%dn' "$element"

另一种极简主义awk

$ awk '{for(mi=i=1;i<=NF;i++) if(a[$mi]<++a[$i]) mi=i; print $mi}' <<< "${array[@]}"

最新更新