在bash中找出排序数组中数字之间的最小差异

时间:2015-12-19 17:28:22

标签: arrays bash optimization puzzle

我正在进行代码挑战,给定数字,我必须找到最小的差异。例如:

[3,5,8,9]

Result : 1 (9-8)

问题在于,实现拼图的最终测试使用了大量的数字而且我的代码不够优化。

在找到最小差异之前,我按如下方式对数组进行排序:

IFS=$'\n' sorted=($(sort -n <<<"${array[*]}"))

然后,我在数组上执行for循环以找到最小但是花费太多时间,所以我尝试i+4而不是i++,但我不认为这是真正的问题。

这是我找到最小的代码:

smallest=5000
for (( i=2; i<N; i=$((i+1)) ));do
    diff=$((${sorted[i]}-${sorted[i-1]}))
    if [ $diff -lt $smallest ]; then
        smallest=$diff
    fi
done

你知道我能做些什么才能有足够的资源来完成测试吗?顺便说一句,我对Bash几乎一无所知,我在python中使用代码。

2 个答案:

答案 0 :(得分:3)

我怀疑这会有所帮助; shell根本不适合快速数值计算。唯一的区别是我将数组索引操作的数量减少了一半。

# No need to guess at an upper bound
N=${#sorted[@]}
smallest=$((${sorted[N-1]} - ${sorted[0]}))

current=${sorted[0]}
for next in "${sorted[@]:1}"; do
    diff=$(($next - $current))
    if [ $diff -lt $smallest ]; then
        smallest=$diff
    fi
    current=$next
done

我不认为使用C风格的循环比迭代数组元素更快,但如果是,请按照以下说明操作:

# Indices run from 0 to N-1
# No need for $((...)); ((...)) is already an arithmetic context
current=${sorted[0]}
for ((i=1; i<N; i++)); do
    next=${sorted[i]}
    diff=$(($next - $current))
    if [ $diff -lt $smallest ]; then
        smallest=$diff
    fi
    current=$next
done

最后,您可能会尝试根本不使用数组,而只是从标准输入中读取数据。

sort -n <<EOF |
5
3
9
8
EOF
| {
    smallest=5000   # Now you do have to guess again
    read current
    while read next; do
        diff=$((next - current))
        if [ $diff -lt $smallest ]; then
            smallest=$diff
        fi
        current=$next
    done
}

答案 1 :(得分:1)

array=(5 3 9 8)
IFS=$'\n' sorted=($(sort -n <<<"${array[*]}"))
for ((i=0;i<${#sorted[@]}-1;i++)); do 
  diff[$i]="$((${sorted[$i+1]}-${sorted[$i]})) (${sorted[$i+1]}-${sorted[$i]})"
done
IFS=$'\n' result=($(sort -n <<<"${diff[*]}"))
echo "Result : ${result[0]}"

输出:

Result : 1 (9-8)