Mam tablicę zawierającą ciągi. Kilka z tych ciągów może być takich samych i to jest w porządku. Mogą być w dowolnej kolejności, ale najprawdopodobniej są w porządku alfabetycznym. Mam następującą funkcję shuffle
, która przetasuje wszystkie elementy. Jednak chcę dodać warunek, że żadne dwa z tego samego ciągu nie mogą przylegać do tablicy.Przetasuj tablicę tak, aby nie było dwóch sąsiednich elementów.
Na przykład jest to w porządku: ook eek ook monkey ook
, ale nie jest to: ook ook eek ook monkey
, ponieważ sąsiadujące są dwa ook
. Zakłada się, że dane wejściowe zostały sprawdzone w taki sposób, że wszystkie duplikaty są mniejsze niż połowa całkowitej liczby elementów, więc istnieje zestaw nie sąsiednich rozwiązań. Na przykład ook ook ook eek
zostanie odrzucony. Łańcuchy mogą zawierać spacje i znaki UTF-8, ale nie nowe linie - ciągi są w rzeczywistości plikami nazw obrazów.
Jak mogę zmienić funkcję shuffle
, aby osiągnąć ten cel?
A może jest lepszy sposób to zrobić?
shuffle() {
# This function shuffles the elements of an array in-place using the
# Knuth-Fisher-Yates shuffle algorithm.
local i tmp size max rand
# $RANDOM % (i+1) is biased because of the limited range of $RANDOM
# Compensate by using a range which is a multiple of the array size.
size=${#array[*]}
max=$((32768/size * size))
for ((i=size-1; i>0; i--)); do
while (((rand=$RANDOM) >= max)); do :; done
rand=$((rand % (i+1)))
tmp=${array[i]} array[i]=${array[rand]} array[rand]=$tmp
done
}
Czy istnieje powód, dla którego robisz to w bash? – 123
@ 123 Tak, reszta skryptu jest w bash. – Sardathrion
@iblamefish Dobry punkt. Pytanie edytowane. – Sardathrion