Ottengo le stringhe di input dalla console in questo modo:
while ((currentLine = bufferedReader.readLine()) != null ) {
StringTokenizer string = new StringTokenizer(currentLine, " ");
while (string.hasMoreTokens()) {
// Create a new LinkedHashSet for every token and then add it to the ArrayList.
LinkedHashSet<String> linkedHashSet = new LinkedHashSet<String>();
linkedHashSet.add(string.nextToken());
setOfStrings.add(linkedHashSet);
}
}
Ricevo sempre stringhe diverse dall'input, mai lo stesso. Dopo aver terminato di compilare le strutture dati, ho questa situazione:
- Un
ArrayList<LinkedHashSet<String>>
che contiene un LinkedHashSet per ogni divisione di stringhe. -
All'interno di ogni
LinkedHashSet
ho una stringa che è diversa da qualsiasi altra stringa presente negli altri LinkedHashSet - in altre parole, è unica. Ad esempio, non posso avere questo all'interno di ArrayList:Set x : [foo] ... Set y : [foo]
Dopo averlo fatto, chiamo la funzione qui sotto molte volte per fare diverse fusioni.
public void mergeSets(ArrayList<String> operations, ArrayList<LinkedHashSet<String>> setOfStrings) {
String toMerge = operations.get(1);
String fromMerge = operations.get(2);
boolean enteredFirstToMerge = false;
boolean enteredFirstFromMerge = false;
// Temporary LinkedHashSet reference used to merge two sets.
LinkedHashSet<String> subSetToMerge = null;
LinkedHashSet<String> subSetFromMerge = null;
for (Iterator<LinkedHashSet<String>> iterator = setOfStrings.iterator();
iterator.hasNext(); ) {
LinkedHashSet<String> subSet = iterator.next();
if (subSet.contains(toMerge) && subSet.contains(fromMerge))
break;
else {
if (subSet.contains(toMerge) && !enteredFirstToMerge) {
enteredFirstToMerge = true;
subSetToMerge = subSet;
iterator.remove();
} else if (subSet.contains(fromMerge) && !enteredFirstFromMerge) {
enteredFirstFromMerge = true;
subSetFromMerge = subSet;
}
}
if (enteredFirstFromMerge && enteredFirstToMerge)
break;
}
if (enteredFirstFromMerge && enteredFirstToMerge) {
subSetFromMerge.addAll(subSetToMerge);
}
}
Spiegazione:
Ad esempio, se ho come operazione merge foo bar
, devo fare questi passaggi:
-
Prima di tutto, devo trovare dove si trovano
foo
ebar
:-
Dentro
setOfStrings
, posso avere questa situazione:position x : [bar, tree, hotel] ... position y : [foo, lemon, coffee]
-
Quando li trovo, devo combine the set which contains foo with the set that contains bar
in questo modo:
position x : {bar tree hotel foo lemon coffee}
...
position y : {} -> deleted from the arrayList
Questa funzione prende come parametri un arrayList
di operazioni e un arrayList<LinkedHashSet<String>>
:
Per il ArrayList
di operations
, ottengo sempre una posizione specifica:
-
operations.get(1)
fa riferimento al set da unire (foo in questo esempio) -
operations.get(2)
fa riferimento al set in cui aggiungere il set foo (barra in questo esempio)
Con questo ciclo for, I iterate su ArrayList per cercare i set da, for (Iterator<LinkedHashSet<String>> iterator = setOfStrings.iterator(); iterator.hasNext(); )
Questa dichiarazione if
controlla se l'iteratore si trova nel set specifico:
if (subSet.contains(toMerge) && !enteredFirstToMerge) {
enteredFirstToMerge = true;
subSetToMerge = subSet;
iterator.remove();
} else if (subSet.contains(fromMerge) && !enteredFirstFromMerge) {
enteredFirstFromMerge = true;
subSetFromMerge = subSet;
}
La mia domanda è: potrei avere collisioni con questo tipo di algoritmo che ho implementato?
Se non la complessità temporale è solo O (n) - > la dimensione di arrayList.