查找数组中最常出现的项目

时间:2019-01-07 05:44:27

标签: bash

如何在Bash中找到一系列数字中最频繁出现的数字?

例如:

#!/bin/bash

frequent=0

analog=(889 890 884 880 889 889 884 885 890 890)

for i in ${analog[@]}; do
    # what to do whit this $i ?
done

由于结果为2,即3x 889和3x 890,因此我更希望结果应为890(最高)而不是889。

2 个答案:

答案 0 :(得分:1)

最简单的方法是使用关联数组和后递增运算符来对analog索引数组(例如

)中每个数字的计数进行递增
#!/bin/bash

analog=(889 890 884 880 889 889 884 885 890 890)
declare -A frequent

for i in ${analog[@]}; do
    ((frequent[$i]++))
done

for i in "${!frequent[@]}"; do
    printf "%s\t%s\n" "$i ==> ${frequent[$i]}"
done

使用/输出示例

$ bash ~/scr/array/freqarray.sh
880 ==> 1
884 ==> 2
885 ==> 1
889 ==> 3
890 ==> 3

您可以在迭代关联数组时仅保留max个计数,并输出与key频繁值相关联的max(您必须确定如何处理联系,例如889, 890都是3。)

要识别模拟中出现次数最多的值,可以在出现次数循环时添加maxkeymaxval变量,然后进行类似于以下内容的最终循环:

declare -i maxkey=0 maxval=0
for i in "${!frequent[@]}"; do
    printf "%s\t%s\n" "$i ==> ${frequent[$i]}"
    if (( ${frequent[$i]} > maxval )); then
        maxval=${frequent[$i]}
        maxkey=$i
    fi
done

printf "\nmaximum occurences in analog:\n\n"
for i in "${!frequent[@]}"; do
    if (( ${frequent[$i]} == maxval)); then
        printf "%s\t%s\n" "$i ==> ${frequent[$i]}"
    fi
done

然后将产生以下输出:

使用/输出示例

$ bash ~/scr/array/freqarray.sh
880 ==> 1
884 ==> 2
885 ==> 1
889 ==> 3
890 ==> 3

maximum occurences in analog:

889 ==> 3
890 ==> 3

根据您的编辑内容,以查找出现次数最多的最高价值

要查找出现次数最多的最大值,只需在第二个循环中添加一个附加检查,并将maxkey的值设置为frequent中具有{{1}的最大值}。例如,您可以重新排列最终循环并按如下所示添加输出:

maxval

使用/输出示例

printf "\nmaximum occurences in analog:\n\n"
for i in "${!frequent[@]}"; do
    if (( ${frequent[$i]} == maxval)); then
        printf "%s\t%s\n" "$i ==> ${frequent[$i]}"
        (( i > maxkey)) && maxkey=i
    fi
done

printf "\nhighest value with maximum occurrence:\n\n"
printf "%d\n" $maxkey

答案 1 :(得分:0)

有人问了一个类似的问题here,尽管PSkocik的解决方案找到了最小值,而不是平局的最大值。从if(what>$1)到的简单不等式翻转 if(what< $1)可以解决此问题。