我需要在数组中找到最常见的数字。我这样做了:
# 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[@]}"