Was ist in C # der beste Weg, um die erste Ziffer in einem Int zu erhalten? Die Methode, die ich mir ausgedacht habe, besteht darin, das int in einen String umzuwandeln, das erste Zeichen des Strings zu finden und es dann wieder in einen int umzuwandeln.
int start = Convert.ToInt32(curr.ToString().Substring(0, 1));
Während dies die Arbeit erledigt, scheint es wahrscheinlich eine gute, einfache, mathematische Lösung für ein solches Problem zu geben. Die Manipulation von Saiten fühlt sich klobig an.
Bearbeiten: Unabhängig von Geschwindigkeitsunterschieden ist mystring [0] anstelle von Substring () immer noch nur eine String-Manipulation
Antworten:
Hier ist wie
und
i
wird enthalten, was Sie brauchenquelle
Benchmarks
Zunächst müssen Sie entscheiden, was Sie unter "bester" Lösung verstehen. Dabei werden natürlich die Effizienz des Algorithmus, seine Lesbarkeit / Wartbarkeit und die Wahrscheinlichkeit berücksichtigt, dass in Zukunft Fehler auftreten. Sorgfältige Komponententests können diese Probleme jedoch im Allgemeinen vermeiden.
Ich habe jedes dieser Beispiele 10 Millionen Mal ausgeführt, und der Ergebniswert ist die Anzahl der
ElapsedTicks
übergebenen Beispiele.Ohne weiteres, vom langsamsten zum schnellsten, sind die Algorithmen:
Nehmen Sie zum Konvertieren in eine Zeichenfolge das erste Zeichen
Ergebnisse:
Verwenden eines Logarithmus
Ergebnisse:
Schleifen
Ergebnisse:
Bedingungen
Ergebnisse:
Abgerollte und optimierte Schleife
Ergebnisse:
Hinweis:
Jeder Test ruft
Random.Next()
an, um den nächsten zu erhaltenint
quelle
char
in a ergibtint
den Codepunkt des Zeichens. Wenn Sie also das Zeichen0
in 48 umwandeln, wird durch Subtrahieren von 48 effektiv eine Konvertierung in eine Ganzzahl durchgeführt. Als weiteres Beispiel ergibt das Wirken des Charakters5
auf eineint
Bewertung von 53 und das Subtrahieren von 48 davon 5.Versuche dies
BEARBEITEN
Mehrere Personen haben die Loop-Version angefordert
quelle
Das Beste, was ich mir einfallen lassen kann, ist:
quelle
Variation von Antons Antwort:
quelle
/10
und lassen/1000
. Sie haben immer noch den Vorteil, aggressiver zu teilen, aber mit etwas weniger Chaos. +1 für Kreativität :)Hatte die gleiche Idee wie Lennaert
Dies funktioniert auch mit negativen Zahlen.
quelle
quelle
Wenn Sie der Meinung sind, dass Keltex 'Antwort hässlich ist, probieren Sie diese aus, sie ist WIRKLICH hässlich und sogar noch schneller. Es führt eine entrollte binäre Suche durch, um die Länge zu bestimmen.
PS MartinStettner hatte die gleiche Idee.
quelle
i=(...moreugly...)i>=100?i>=1000?i/1000:i/100:i>=10?i/10:i;
Ein offensichtlicher, aber langsamer mathematischer Ansatz ist:
quelle
Ergebnis in
temp
quelle
Ich weiß, dass es nicht C # ist, aber es ist überraschend merkwürdig, dass in Python das "Erhalten des ersten Zeichens der Zeichenfolgendarstellung der Zahl" schneller ist!
EDIT : Nein, ich habe einen Fehler gemacht, ich habe vergessen, das Int erneut zu konstruieren, sorry. Die abgerollte Version ist die schnellste.
quelle
Ich bin gerade auf diese alte Frage gestoßen und war geneigt, einen anderen Vorschlag vorzuschlagen, da keine der anderen Antworten bisher das richtige Ergebnis für alle möglichen Eingabewerte liefert und es immer noch schneller gemacht werden kann:
Dies funktioniert für alle vorzeichenbehafteten Ganzzahlwerte einschließlich, wobei
-2147483648
dies die kleinste vorzeichenbehaftete Ganzzahl ist und kein positives Gegenstück hat.Math.Abs( -2147483648 )
löst a ausSystem.OverflowException
und- -2147483648
berechnet zu-2147483648
.Die Implementierung kann als eine Kombination der Vorteile der beiden bisher schnellsten Implementierungen angesehen werden. Es verwendet eine binäre Suche und vermeidet überflüssige Unterteilungen. Ein schneller Benchmark mit dem Index einer Schleife mit 100.000.000 Iterationen zeigt, dass sie doppelt so schnell ist wie die derzeit schnellste Implementierung.
Es endet nach 2.829.581 Zecken.
Zum Vergleich habe ich auch eine korrigierte Variante der derzeit schnellsten Implementierung gemessen, die 5.664.627 Ticks benötigte.
Die akzeptierte Antwort mit der gleichen Korrektur benötigte 16.561.929 Ticks für diesen Test auf meinem Computer.
Einfache Funktionen wie diese können leicht auf ihre Richtigkeit überprüft werden, da das Iterieren aller möglichen ganzzahligen Werte auf der aktuellen Hardware nicht viel länger als einige Sekunden dauert. Dies bedeutet, dass es weniger wichtig ist, sie auf außergewöhnlich lesbare Weise zu implementieren, da es später einfach nie notwendig sein wird, einen Fehler in ihnen zu beheben.
quelle
Sehr einfach (und wahrscheinlich ziemlich schnell, da es sich nur um Vergleiche und eine Unterteilung handelt):
quelle
Ich habe einige Tests mit einem meiner Mitarbeiter hier durchgeführt und festgestellt, dass die meisten Lösungen für Zahlen unter 0 nicht funktionieren.
quelle
Verwenden Sie alle folgenden Beispiele, um diesen Code zu erhalten:
Ich erhalte diese Ergebnisse auf einem AMD Ahtlon 64 X2 Dual Core 4200+ (2,2 GHz):
Aber erhalten Sie diese auf einem AMD FX 8350 Eight Core (4,00 GHz)
Ob Methode 5 oder 6 schneller ist oder nicht, hängt von der CPU ab. Ich kann nur vermuten, dass die Verzweigungsvorhersage im Befehlsprozessor der CPU auf dem neuen Prozessor intelligenter ist, aber ich bin mir nicht sicher.
Ich habe keine Intel-CPUs, vielleicht könnte es jemand für uns testen?
quelle
Überprüfen Sie auch dieses:
Auch gut, wenn Sie mehrere Zahlen möchten:
quelle
-1
.quelle
Nicht iterative Formel:
quelle
Um Ihnen eine Alternative zu bieten, können Sie die Ganzzahl wiederholt durch 10 teilen und dann einen Wert zurücksetzen, sobald Sie Null erreichen. Da String-Operationen im Allgemeinen langsam sind, ist dies möglicherweise schneller als die String-Manipulation, aber keineswegs elegant.
Etwas wie das:
quelle
oder
quelle
Dies ist effizienter als ein ToString () -Ansatz, der intern eine ähnliche Schleife implementieren muss und unterwegs ein String-Objekt erstellen (und analysieren) muss ...
quelle
Sehr einfache Methode, um die letzte Ziffer zu erhalten:
quelle
Dies ist, was ich normalerweise mache, bitte beziehen Sie sich auf meine Funktion unten:
Diese Funktion kann das Auftreten der ersten Nummer aus jeder Zeichenfolge extrahieren, die Sie ändern und entsprechend Ihrer Verwendung verwenden können
quelle
Hier ist ein einfacher Weg, der keine Schleife beinhaltet
Das würde uns 1234 / Math.Pow (10, 4 - 1) = 1234/1000 = 1 geben
quelle
quelle