702 Stimmen

Teilen Sie eine Zahl durch 3, ohne * , / , + , - , % Operatoren zu verwenden

Wie würden Sie eine Zahl durch 3 teilen, ohne die *, /, +, -, % Operatoren zu verwenden?

Die Zahl kann positiv oder negativ sein.

2 Stimmen

Dies ist schwer, da Sie + oder - nicht verwenden können. Sie könnten technisch gesehen einen Addierer nur unter Verwendung von logischen Operatoren implementieren...

1 Stimmen

Sind Sie zu 100% sicher, dass + in der Liste der nicht verwendbaren Elemente stand?

0 Stimmen

Ist der unäre +, - erlaubt?

555voto

qwertz Punkte 14434

Dies ist eine einfache Funktion, die die gewünschte Operation ausführt. Es erfordert jedoch den + Operator, sodass Sie nur die Werte mit den Bit-Operatoren hinzufügen müssen:

// ersetzt den + Operator
int add(int x, int y)
{
    while (x) {
        int t = (x & y) << 1;
        y ^= x;
        x = t;
    }
    return y;
}

int divideby3(int num)
{
    int sum = 0;
    while (num > 3) {
        sum = add(num >> 2, sum);
        num = add(num >> 2, num & 3);
    }
    if (num == 3)
        sum = add(sum, 1);
    return sum; 
}

Wie Jim kommentierte, funktioniert dies, weil:

  • n = 4 * a + b

  • n / 3 = a + (a + b) / 3

  • Also sum += a, n = a + b, und iteriere

  • Wenn a == 0 (n < 4), sum += floor(n / 3); d.h. 1, wenn n == 3, ansonsten 0

96 Stimmen

Das ist wahrscheinlich die Antwort, die Oracle sucht. Es zeigt, dass Sie wissen, wie die +, -, * und / Operatoren tatsächlich auf der CPU implementiert sind: einfache bitweise Operationen.

0 Stimmen

+1, obwohl es etwas zusätzliche Logik benötigt, um negative Zahlen zu behandeln.

21 Stimmen

Dies funktioniert, weil n = 4a + b, n/3 = a + (a+b)/3, also sum += a, n = a + b, und iteriere. Wenn a == 0 (n < 4), sum += Boden(n/3); d.h., 1, wenn n == 3, sonst 0.

441voto

Matteo Italia Punkte 119470

Idiotische Bedingungen erfordern eine idiotische Lösung:

#include 
#include 

int main()
{
    FILE * fp=fopen("temp.dat","w+b");
    int number=12346;
    int divisor=3;
    char * buf = calloc(number,1);
    fwrite(buf,number,1,fp);
    rewind(fp);
    int result=fread(buf,divisor,number,fp);
    printf("%d / %d = %d", number, divisor, result);
    free(buf);
    fclose(fp);
    return 0;
}

Wenn auch der Dezimalteil benötigt wird, deklarieren Sie einfach result als double und fügen Sie das Ergebnis von fmod(number,divisor) hinzu.

Erklärung, wie es funktioniert

  1. Das fwrite schreibt number Bytes (number ist im obigen Beispiel 123456).
  2. rewind setzt den Dateizeiger an den Anfang der Datei zurück.
  3. fread liest maximal number "Datensätze" der Länge divisor aus der Datei und gibt die Anzahl der gelesenen Elemente zurück.

Wenn Sie 30 Bytes schreiben und die Datei in Einheiten von 3 zurücklesen, erhalten Sie 10 "Einheiten". 30 / 3 = 10

1 Stimmen

Ich mag die Tatsache, dass der memset()-Aufruf zwei (unwesentliche) Fehler hat.

2 Stimmen

@Matteo: Ich weiß es nicht - ich denke, es war technisch bereits korrekt (ein memset(), das nichts mit einem Puffer tut, der nichts braucht, ist in Ordnung, oder?) und es könnte dem Bewerber helfen, etwas über den Interviewer herauszufinden.

1 Stimmen

Etwas anderes Interessantes: Diese Lösung funktioniert nicht zuverlässig unter Windows (zumindest Win7 x64). Ich denke jedoch, dass das gut ist, denn es hat mich dazu gebracht, etwas Neues über Windows zu lernen. Es wird 0 für den fread()-Aufruf zurückgeben, da die ReadFile() Win32-API überprüft, ob der von Ihnen bereitgestellte Puffer groß genug ist (mindestens aus Sicht des Betriebssystems 'gültiger Speicher'), bevor sie versucht, Daten aus der Datei zu lesen. Da ReadFile() aufgefordert wird, 3-mal mehr Daten zu lesen, als mit malloc() allokiert wurden, besteht eine gute Chance, dass der Speicher möglicherweise nicht gültig ist.

310voto

Alan Curry Punkte 13865
protokoll(pow(exp(nummer),0.33333333333333333333)) /* :-) */

2 Stimmen

Dies könnte tatsächlich funktionieren, wenn es richtig gerundet wird und die Zahl nicht zu groß ist.

254 Stimmen

Verbesserte Version: log(pow(exp(Zahl),sin(atan2(1,sqrt(8)))))

0 Stimmen

@bitmask, mathematische Funktionen werden normalerweise direkt in Assembler implementiert.

209voto

nos Punkte 214143
#include 
#include 

int main(int argc, char *argv[])
{

    int num = 1234567;
    int den = 3;
    div_t r = div(num,den); // div() ist eine Standard-C-Funktion.
    printf("%d\n", r.quot);

    return 0;
}

113voto

moooeeeep Punkte 29848

Sie können (plattformabhängiges) Inline-Assembly verwenden, z.B. für x86: (funktioniert auch für negative Zahlen)

#include 

int main() {
  int dividend = -42, divisor = 5, quotient, remainder;

  __asm__ ( "cdq; idivl %%ebx;"
          : "=a" (quotient), "=d" (remainder)
          : "a"  (dividend), "b"  (divisor)
          : );

  printf("%i / %i = %i, Rest: %i\n", dividend, divisor, quotient, remainder);
  return 0;
}

0 Stimmen

Das scheitert unter der Annahme, dass die Antwort in C geschrieben sein muss.

2 Stimmen

@JeremyP, scheitert Ihr Kommentar nicht an der Annahme, dass die Antwort nicht in C geschrieben werden kann? Schließlich ist die Frage mit "C" getaggt.

1 Stimmen

@SethCarnegie Die Antwort ist nicht in C geschrieben, das ist mein Punkt. x86 Assembler ist nicht Teil des Standards.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X