it-swarm.com.de

Wie kann man zwei Zahlen tauschen, ohne temporäre Variablen oder arithmetische Operationen zu verwenden?

Diese Gleichung vertauscht zwei Zahlen ohne temporäre Variable, verwendet jedoch arithmetische Operationen:

a = (a+b) - (b=a);

Wie mache ich das ohne Rechenoperationen? Ich dachte an XOR.

31
mr_eclair
a=a+b;
b=a-b;
a=a-b;

Das ist einfach, aber effektiv.

21
sreejith k s

Warum nicht die Standard-Libs verwenden?

std::swap(a,b);
18
Martin York

In C sollte dies funktionieren:

a = a^b;
b = a^b;
a = a^b;

ODER ein cooler/geekier suchen:

a^=b;
b^=a;
a^=b;

Für weitere Details schauen Sie in this . XOR ist eine sehr mächtige Operation, die hier und dort viele interessante Anwendungen hervorbringt.

16
BiGYaN

Um zwei Zahlen zu wechseln, ohne temporäre Speicher- oder Arithmetikoperationen zu verwenden, laden Sie beide Variablen in Register und verwenden Sie die Register umgekehrt.

Sie können das nicht direkt von C aus tun, aber der Compiler ist wahrscheinlich in der Lage, dies für Sie herauszufinden (zumindest wenn die Optimierung aktiviert ist) - wenn Sie einfachen, offensichtlichen Code schreiben, wie ihn KennyTM in seinem Kommentar vorgeschlagen hat .

z.B.

void swap_tmp(unsigned int *p)
{
  unsigned int tmp;

  tmp = p[0];
  p[0] = p[1];
  p[1] = tmp;
}

kompiliert mit gcc 4.3.2 mit dem -O2-Optimierungsflag ergibt:

swap_tmp:
        pushl   %ebp               ;  (prologue)
        movl    %esp, %ebp         ;  (prologue)
        movl    8(%ebp), %eax      ; EAX = p
        movl    (%eax), %ecx       ; ECX = p[0]
        movl    4(%eax), %edx      ; EDX = p[1]
        movl    %ecx, 4(%eax)      ; p[1] = ECX
        movl    %edx, (%eax)       ; p[0] = EDX
        popl    %ebp               ;  (epilogue)
        ret                        ;  (epilogue)
14

Ich habe diese C-Lösung noch nicht gesehen, aber ich bin sicher, dass jemand daran gedacht hat. Und hatte vielleicht mehr Selbstbeherrschung als ich.

fprintf(fopen("temp.txt", "w"), "%d", a);
a = b;
fscanf(fopen("temp.txt", "r"), "%d", &b);

Keine zusätzlichen Variablen!

Es funktioniert für mich, aber abhängig von der stdio-Implementierung müssen Sie möglicherweise etwas für die Ausgabepufferung tun.

a = ((a = a + b) - (b = a - b));

4
Syed Raza Mehdi

XOR verwenden,

void swap(int &a, int &b)
{
    a = a ^ b;
    b = a ^ b;
    a = a ^ b;
}

Ein Liner mit XOR,

void swap(int &a, int &b)
{
    a ^= b ^= a ^= b;
}

Diese Methoden scheinen sauber zu sein, weil sie für keinen Testfall fehlschlagen, aber da (wie in Methode 2) der Wert der Variablen zweimal innerhalb desselben Sequenzpunkts geändert wird, wird angegeben, dass undefiniertes Verhalten von deklariert wird ANSI C.

3
Shubham A.

C++11 ermöglicht:

  • Werte tauschen :

    std::swap(a, b);
    
  • Tauschbereiche :

    std::swap_ranges(a.begin(), a.end(), b.begin());
    
  • Erstelle LValue Tuple mit tie :

    std::tie(b, a) = std::make_Tuple(a, b);
    
    std::tie(c, b, a) = std::make_Tuple(a, b, c);
    
1
k06a

Einfache Lösung, an die ich mich von meinen Junggesellen erinnere :-)

a = a+b-(b=a);

 Example

0
Reddy

Multiplikation und Division können ebenfalls verwendet werden. 

 int x = 10, y = 5;

 // Code to swap 'x' and 'y'
 x = x * y;  // x now becomes 50
 y = x / y;  // y becomes 10
 x = x / y;  // x becomes 5
0
Moiz Sajid

Zusätzlich zu den obigen Lösungen für einen Fall, in dem, wenn einer der Werte außerhalb des Bereichs für eine vorzeichenbehaftete Ganzzahl liegt, die beiden Variablenwerte auf diese Weise ausgetauscht werden können

a = a+b;
b=b-(-a);
a=b-a;
b=-(b);
0
Khushi