Problem beim Filtern eines Sequenz-Arrays zum Entfernen von Duplikaten mit verschobenen Sequenzen

Problem beim Filtern eines Sequenz-Arrays zum Entfernen von Duplikaten mit verschobenen Sequenzen

Ich hatte einige Probleme, einen Array-Vergleich von Listen durchzuführen, um Duplikate zu entfernen. Mein Array besteht aus Sequenzen ternärer Werte wie diesen:

{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}

Ich habe versucht, mit einer While-Schleife Duplikate mithilfe des Index „testsequence.sh“ zu finden. Dabei handelt es sich um einen Mathematica-Skript-Wrapper, der ermittelt, ob zwei Sequenzen gleich sind:

{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}

Diese beiden sind gleich, allerdings mit einer Verschiebung nach links. In diesem Fall gibt mein Index 1 zurück und der Index wird folgendermaßen verwendet:

./testsequence.sh "`echo ${foundsequence[0]}`" "`echo ${foundsequence[1]}`"

Bei meinem ersten Versuch mit der While-Schleife habe ich nur die erste Sequenz mit den anderen verglichen und nur die Hälfte der Duplikate entfernt.

Das gute Ergebnis muss sein:

{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}  

Da es sich um die einzigen beiden eindeutigen Sequenzen in der Liste handelt.

Beachten Sie, dass die Sequenzen im Array keine feste Länge haben. Ihre Länge kann zwischen 2 und 121 oder sogar noch länger variieren. Deshalb möchte ich meine Indizes beibehalten, um zwei Zeilen des Arrays zu vergleichen.

Antwort1

Hier ist eine Bash-Schleife, die Eingaben aus einer Datei namens „input“ in ein Array namens liest input, dann eine Schleife über dieses Array durchläuft und prüft, ob diese bestimmte Sequenz schon einmal gesehen wurde; wenn nicht, wird der Wert gedruckt. Dann rotiert sie diese Sequenz durch alle 13 Positionen und fügt diese Werte einem assoziativen Array mit bekannter Rotation hinzu. Ich habe die Daten vereinfacht, um die Methode zu zeigen; Sie können die Shell-Schleife nehmen und die Eingabe oder Ausgabe nach Bedarf anpassen.

#!/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

Beispiel-Eingabedaten (aus der Frage kopiert und dann vereinfacht):

0010111220121
0020222110212
0101112201210
0111220121001
0121001011122
0202221102120
0212002022211
0222110212002
1001011122012
1011122012100
1021200202221
1102120020222
1112201210010
1122012100101
1200202221102
1210010111220
1220121001011
2002022211021

Beispielausgabe:

0010111220121
0020222110212

verwandte Informationen