Нахождение перестановок числа с помощью 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 2342 1343 1244 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чтобы получить все комбинации вместо всех перестановок.

Другие вопросы по тегам