Нахождение перестановок числа с помощью bash-скрипта
Можно ли написать сценарий bash, который принимает четырехзначное число в качестве аргумента командной строки и производит все перестановки этого числа с использованием только чистого bash?
2 ответа
Возможно. Вот функция, которая будет делать то, что вы просите.
function permutate {
if [ "${#1}" = 1 ]; then
echo "${2}${1}"
else
for i in $(seq 0 $((${#1}-1)) ); do
pre="${2}${1:$i:1}"
seg1="${1:0:$i}"
seg2="${1:$((i+1))}"
seg="${seg1}${seg2}"
permutate "$seg" "$pre"
done
fi
}
Запустите это так:
$ permutate 1234
Это работает с помощью рекурсии. Каждый вызов функции берет один символ из строки и рекурсивно передает остаток самому себе. Таким образом, если ввод 1234, он разбивается на префикс и оставшийся сегмент четыре раза, как это: 1 234
2 134
3 124
4 123
, Затем три символьных сегмента обрабатываются одинаково, затем два символьных сегмента, а затем рекурсия останавливается, когда сегмент состоит только из одного символа.
Массовое злоупотреблениеshuf
команда, которая, как я понимаю, делает ее не чистым bash:
damson$ cat shell-combinations
#!/bin/bash
R=1000
PERM_OR_COMB=perm
if [ $PERM_OR_COMB = perm ]; then
C_RANGE=$#
else
C_RANGE=$(seq 0 $#)
fi
for C in $C_RANGE; do
for I in $(seq 1 $R); do
echo "$(for X in "$@"; do echo "$X"; done | shuf -n $C | paste -s -d' ')"
done | sort -u
done
damson$ ./shell-combinations 1 2 3 4
1 2 3 4
1 2 4 3
1 3 2 4
1 3 4 2
1 4 2 3
1 4 3 2
2 1 3 4
2 1 4 3
2 3 1 4
2 3 4 1
2 4 1 3
2 4 3 1
3 1 2 4
3 1 4 2
3 2 1 4
3 2 4 1
3 4 1 2
3 4 2 1
4 1 2 3
4 1 3 2
4 2 1 3
4 2 3 1
4 3 1 2
4 3 2 1
damson$
Очевидно, что это медленно и теоретически ненадежно, но в зависимости от вашего варианта использования и размераR
сравнивается с$#
, это может удовлетворить ваши потребности. ИзменятьPERM_OR_COMB=perm
кPERM_OR_COMB=comb
чтобы получить все комбинации вместо всех перестановок.