Wie würden Sie eine Zahl durch 3 teilen, ohne die *
, /
, +
, -
, %
Operatoren zu verwenden?
Die Zahl kann positiv oder negativ sein.
Wie würden Sie eine Zahl durch 3 teilen, ohne die *
, /
, +
, -
, %
Operatoren zu verwenden?
Die Zahl kann positiv oder negativ sein.
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
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.
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.
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
fwrite
schreibt number
Bytes (number ist im obigen Beispiel 123456).rewind
setzt den Dateizeiger an den Anfang der Datei zurück.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
@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.
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.
Dies könnte tatsächlich funktionieren, wenn es richtig gerundet wird und die Zahl nicht zu groß ist.
@bitmask, mathematische Funktionen werden normalerweise direkt in Assembler implementiert.
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;
}
@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.
@SethCarnegie Die Antwort ist nicht in C geschrieben, das ist mein Punkt. x86 Assembler ist nicht Teil des Standards.
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.
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?8 Stimmen
Der identifizierte Duplikat ist kein Duplikat. Beachten Sie, dass mehrere Antworten hier weder Bitverschiebung noch Addition verwenden, da diese Frage keine Einschränkung auf diese Operationen vorschrieb.
4 Stimmen
BTW: Die andere Frage handelte davon, ob eine Zahl durch 3 teilbar ist. Diese Frage handelt davon, durch 3 zu dividieren.
0 Stimmen
Ich wäre interessiert daran, einige auf Mengen basierende Lösungen für das Problem zu sehen (egal wie ineffizient sie sein mögen). Ein "einfacher" rekursiver CTE sollte ausreichen, denke ich. War die Frage immer mit den Tags
c
undbitwise
markiert?1 Stimmen
Für Interessierte habe ich dieses auf codegolf.stackexchange veröffentlicht.
3 Stimmen
Vielleicht meinte der Interviewer, zu fragen "Wie teilen Sie durch 2, ohne blah blah blah zu verwenden". Das wäre eine vernünftige Frage, die die meisten Entwickler beantworten können sollten.
4 Stimmen
X /= 3; verwendet nicht den /-Operator, /= ist ein anderer Operator.
28 Stimmen
Diese Frage ist offtopic für SO. Sie gehört zu codegolf.stackexchange.com
0 Stimmen
Verwenden Sie die
div_t
Struktur, und dann erhalten Sie diequot
undrem
Mitglieder.3 Stimmen
Ich stimme dafür, diese Frage als off-topic zu schließen, da sie zu weit gefasst und off-topic ist, und auf codegolf.stackexchange.com besser aufgehoben wäre. Die Qualität der aktuellen Antworten ist enttäuschend und dieser Beitrag hat insgesamt sehr wenig Wert.
0 Stimmen
Hinweis: Die Verwendung von sprachspezifischen Herausforderungen wird auf PPCG stark abgeraten. PPCG ist kein Ort, um jede off-topic, aber lustige Stack Overflow-Frage zu veröffentlichen.
0 Stimmen
Ähnliche Antworten sind unter stackoverflow.com/questions/171301 zu finden.