Laden...

Alle Paare von Zahlen ermitteln, aber ohne (i,i) und ohne (i,j), wenn (j,i) schon vorhanden ist

Erstellt von masterkrueger vor 12 Jahren Letzter Beitrag vor 12 Jahren 2.036 Views
Thema geschlossen
M
masterkrueger Themenstarter:in
2 Beiträge seit 2011
vor 12 Jahren
Alle Paare von Zahlen ermitteln, aber ohne (i,i) und ohne (i,j), wenn (j,i) schon vorhanden ist

Moin moin,

ich habe folgendes Problem, bzw. frage ich mich, ob es eine elegantere Variante gibt (wovon ich mal ausgehe 😉.
Ich habe zwei Werte z.B. X, Y von 0..n. Ich möchte jetzt beide Werte an eine Methode übergeben, dabei sollen aber keine "gleichen" Werte verglichen werden und zwar nicht 1 und 1, aber ebenso ist 1 und 0 gleichbedeutend mit 0 und 1.
Ich habe mir jetzt zur Hilfe ein Integerarray genommen, in dem ich mir die ersten Werte nehme z.B. prüfe ich X1, Y2 und trage in mein Array 12 und 21 ein.
Wenn dann die Prüfung auf X2, Y1 läuft, überspringe ich den Schritt.

Da muss es doch eine viel elegantere Lösung geben oder?

Vielen Dank im Voraus für eure Ideen

Stefan

p.s.: ich habe hier als Test für X und Y einen Wert genommen.


int Number = 4;
int[] used = new int[Number * Number];
int counter = 0;
int toCheck = 0;

for (int i = 0; i < Number; i++)
{
    for (int j = 0; j < Number; j++)
    {                    
        if (i != j)
        {
            toCheck = int.Parse(i.ToString() + j.ToString());
            if (!used.Contains(toCheck)) //combination does not exist?
            {
                Console.WriteLine("Adding:" + i.ToString() + j.ToString() +
                "\nand   :" + j.ToString() + i.ToString());
                used[counter++] = int.Parse(i.ToString() + j.ToString());
                used[counter++] = int.Parse(j.ToString() + i.ToString());
            }
            else 
            {
                Console.WriteLine("DOUBLE:" + toCheck);
            }
        }
    }
}

296 Beiträge seit 2007
vor 12 Jahren

Hallo masterkrueger,

uff, ich habe den Text nun 3x lesen müssen, um eine Ahnung davon zu bekommen, was du vor hast.

Du willst alle Permutation von [0, 0] bis [n, n] berechnen und doppelte (bzw. die die in umgekerhter Reihenfolge schon einmal aufgetaucht sind) aussortieren?

Eine schöne Lösung fände ich, diese Paare [x,y] als Klasse zu kapseln und HashCode() so zu überschreiben, dass [x,y] und [y,x] den gleichen Hashwert liefern. Das würde ich so machen, dass ich diese sortiere (bspw. größere Zahl immer links) und danach eine bijektive Funktion von N² -> N (eigentlich reicht sogar eine injektive) konstruiere. Google sollte dir da helfen.

Weil es mich grad interessiert hat und ich nochmal kurz auffrischen wollte habe ich eine gesucht: hash = 2^(x-1)*(2y-1)

Im Anschluss einfach alle erzeugen und in ein HashSet packen.

Grüße

16.835 Beiträge seit 2008
vor 12 Jahren
toCheck = int.Parse(i.ToString() + j.ToString());

ist auf alle Fälle nicht elegant 😉

2.891 Beiträge seit 2004
vor 12 Jahren

Soweit ich das sehe, sollte es reichen, wenn du nur das Paar nimmst, bei dem x kleiner ist als y (oder anderes herum).
Also z.B. folgendermaßen:


int Number = 4;
for (int i = 0; i < Number; i++)
    for (int j = 0; j < Number; j++)
        if (i!=j && i<j)
        {
            Console.WriteLine(i+";"+j);
        }

Ergibt für dein Beispiel: 0;1 0;2 0;3 1;2 1;3 2;3

3.170 Beiträge seit 2006
vor 12 Jahren

Hallo,

toCheck = int.Parse(i.ToString() + j.ToString());

ist nicht nur nicht elegant, es funktioniert auch nur, solange alle verglichenen Zahlen immer nur einstellig sind. Denn "123" könnte sowohl bei (1;23) als auch bei (12;3) entstehen.

Bei der Methode mit dem Hashwert müsste ebenfalls darauf geachtet werden, dass dieser Wert bei allen erdenklichen Kombinationen immer ein eindeutiges Ergebnis liefert.

Ich würde daher bei den ursprünglichen Zahlen bleiben, man könnte z.B. mit einem Dictionary<int,List<int>> arbeiten, wo man dann den kleineren der verglichenen Werte als Key nimmt und in der Liste des Value alle bereits mit diesem Wert verglichenen Zahlen aufnimmt.

EDIT: Dann bei einem neuen Paar erst mal schauen, ob einer der beiden Werte bereits als Key im Dictionary steckt -> falls ja, dessen Liste durchlaufen und wenn der andere Wert nicht gefunden wird, diesen dort eintragen.

Gruß, MarsStein

@dN!3L: Geht aber nur, wenn alle Paare auch doppelt in vertauschter Form vorkommen.

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

296 Beiträge seit 2007
vor 12 Jahren

Bei der Methode mit dem Hashwert müsste ebenfalls darauf geachtet werden, dass dieser Wert bei allen erdenklichen Kombinationen immer ein eindeutiges Ergebnis liefert.

Deshalb meinte ich ja eine injektive Funktion. Ich habe mal eine reineditiert.

2.891 Beiträge seit 2004
vor 12 Jahren

@dN!3L: Geht aber nur, wenn alle Paare auch doppelt in vertauschter Form vorkommen.

Wie es im von masterkrueger geposteten Beispiel ja der Fall ist.

M
masterkrueger Themenstarter:in
2 Beiträge seit 2011
vor 12 Jahren

Wow, vielen Dank für die ganzen Antworten, ich werde meine Funktion wohl erstmal an die von dN!3L angleichen, das trifft genau mein Beispiel, obwohl ich das Dictionary auch gut finde.
Aber indem gleich geprüft wird, dass keine größeren Werte verglichen werden, macht die Sache ja schonmal um einiges schlanker.

Danke!!!

Stefan

P
157 Beiträge seit 2010
vor 12 Jahren

Mal eine frage zu der Funktion von dN!3L
Wäre es nicht deutlich besser


int Number = 4;
for(int a = 0; a < Number; a++)
   for(int b = a +1 ; b < Number; b++)
       Console.WriteLine("{0};{1}",a,b);

107 Beiträge seit 2011
vor 12 Jahren

Ja, aber nur solange der Wertbereich gleich bzw. in b größer als in a ist.

q.e.d.

771 Beiträge seit 2009
vor 12 Jahren

Bezogen auf den Eingangsbeitrag ist aber die Lösung von PPK eindeutig die beste.

Und bei der Lösung von dN!3L sollte man die Abfrage noch zu


if (i<j)

verkürzen (denn wenn i<j, dann ist ja automatisch i!=j).

Wenn man jedoch zwei Listen von Zahlen hätte und anhand der Inhalte (anstatt der Indizes) vergleichen möchte, dann kommt man um die Abfrage nicht herum.

Hinweis von herbivore vor 12 Jahren

Obwohl es hier für eine Lösung fors (und teilweise ifs) braucht, bewegt sich die Aufgabenstellung noch klar im Bereich von [Hinweis] Wie poste ich richtig? Punkt 1.1.1.

Thema geschlossen