У меня возникли некоторые проблемы с выполнением сравнения массива списков для удаления дубликатов. Мой массив состоит из последовательностей тернарных значений, таких как:
{0, 0, 1, 0, 1, 1, 1, 2, 2, 0, 1, 2, 1}
{0, 0, 2, 0, 2, 2, 2, 1, 1, 0, 2, 1, 2}
{0, 1, 0, 1, 1, 1, 2, 2, 0, 1, 2, 1, 0}
{0, 1, 1, 1, 2, 2, 0, 1, 2, 1, 0, 0, 1}
{0, 1, 2, 1, 0, 0, 1, 0, 1, 1, 1, 2, 2}
{0, 2, 0, 2, 2, 2, 1, 1, 0, 2, 1, 2, 0}
{0, 2, 1, 2, 0, 0, 2, 0, 2, 2, 2, 1, 1}
{0, 2, 2, 2, 1, 1, 0, 2, 1, 2, 0, 0, 2}
{1, 0, 0, 1, 0, 1, 1, 1, 2, 2, 0, 1, 2}
{1, 0, 1, 1, 1, 2, 2, 0, 1, 2, 1, 0, 0}
{1, 0, 2, 1, 2, 0, 0, 2, 0, 2, 2, 2, 1}
{1, 1, 0, 2, 1, 2, 0, 0, 2, 0, 2, 2, 2}
{1, 1, 1, 2, 2, 0, 1, 2, 1, 0, 0, 1, 0}
{1, 1, 2, 2, 0, 1, 2, 1, 0, 0, 1, 0, 1}
{1, 2, 0, 0, 2, 0, 2, 2, 2, 1, 1, 0, 2}
{1, 2, 1, 0, 0, 1, 0, 1, 1, 1, 2, 2, 0}
{1, 2, 2, 0, 1, 2, 1, 0, 0, 1, 0, 1, 1}
{2, 0, 0, 2, 0, 2, 2, 2, 1, 1, 0, 2, 1}
Я попытался с помощью цикла while найти дубликаты с помощью подстрочного скрипта testsequence.sh, который представляет собой оболочку скрипта Mathematica для определения того, являются ли две последовательности одинаковыми:
{0, 0, 1, 0, 1, 1, 1, 2, 2, 0, 1, 2, 1}
{0, 1, 0, 1, 1, 1, 2, 2, 0, 1, 2, 1, 0}
Эти два значения идентичны со сдвигом влево; в этом случае мой нижний индекс возвращает 1, а нижний индекс используется следующим образом:
./testsequence.sh "`echo ${foundsequence[0]}`" "`echo ${foundsequence[1]}`"
Моя первая попытка с циклом while сравнила только первую последовательность с другими, удалив только половину дубликатов.
Хороший результат должен быть:
{0, 0, 1, 0, 1, 1, 1, 2, 2, 0, 1, 2, 1}
{0, 0, 2, 0, 2, 2, 2, 1, 1, 0, 2, 1, 2}
Так как это единственные две уникальные последовательности в списке.
Имейте в виду, что последовательности в массиве не имеют фиксированной длины. Они могут варьироваться от 2 до 121 или даже больше. Вот почему я хочу сохранить свои индексы для сравнения двух строк массива.
решение1
Вот цикл bash, который считывает входные данные из файла с именем 'input' в массив с именем input
, затем проходит по этому массиву и проверяет, была ли эта конкретная последовательность замечена ранее; если она не замечена, он выводит значение. Затем он вращает эту последовательность по всем 13 позициям, добавляя эти значения в ассоциативный массив с известным вращением. Я упростил данные, чтобы показать метод; вы можете взять цикл оболочки и настроить входные или выходные данные по мере необходимости.
#!/usr/bin/env bash
readarray -t input < input
declare -A rotations
for((i=0; i < ${#input[*]}; i++))
do
x=${input[i]}
[[ ${rotations[$x]:-0} -eq 0 ]] && printf "%s\n" "$x"
for((r=0; r < 13; r++))
do
new=${x:r}${x:0:r}
rotations[$new]=1
done
done
Пример входных данных (скопирован из вопроса, затем упрощен):
0010111220121
0020222110212
0101112201210
0111220121001
0121001011122
0202221102120
0212002022211
0222110212002
1001011122012
1011122012100
1021200202221
1102120020222
1112201210010
1122012100101
1200202221102
1210010111220
1220121001011
2002022211021
Пример вывода:
0010111220121
0020222110212