Was haltet ihr von diesem Program, das zwei strings als Zahlen interpretiert und addiert?
-
Hi,
ich habe dieses Program geschrieben das zwei Zahlen die in strings gespeichert sind zusammenzaehlt:
std::string zahl1 = "15566155151"; std::string zahl2 = "1661"; auto max_str = std::max(zahl1.length(), zahl2.length()); std::string result(max_str.length()+1,'0'); zahl1 = std::string(std::abs((int)(result.length() - zahl1.length())), '0') + zahl1; zahl2 = std::string(std::abs((int)(result.length() - zahl2.length())), '0') + zahl2; bool overflow = false; for (auto ri = zahl1.rbegin(), rb = zahl2.rbegin(), rd = result.rbegin(); ri != zahl1.rend(); ++ri, ++rb, ++rd) { int ir = ((*ri) - 48) + ((*rb) - 48) + (overflow? 1 : 0); overflow = false; auto s = std::to_string(ir); if (ir >= 10) { *rd = s[1]; overflow = true; }else *rd = s[0]; }Was haltet ihr davon? Ist das gut und fehlerfrei? Oder ist es nicht effizient und schlechtes C++?
Vielen Dank
-
Abgesehen vom fehlenden main(), kompiliert, linkt und läuft es?
-
Ja es laeuft:
#include <iostream> #include <string> #include <vector> #include <algorithm> #include <cmath> int main() { std::string zahl1 = "15566155151"; std::string zahl2 = "1661"; auto max_str = std::max(zahl1.length(), zahl2.length()); std::string result(max_str+1,'0'); zahl1 = std::string(std::abs((int)(result.length() - zahl1.length())), '0') + zahl1; zahl2 = std::string(std::abs((int)(result.length() - zahl2.length())), '0') + zahl2; bool overflow = false; for (auto ri = zahl1.rbegin(), rb = zahl2.rbegin(), rd = result.rbegin(); ri != zahl1.rend(); ++ri, ++rb, ++rd) { int ir = ((*ri) - 48) + ((*rb) - 48) + (overflow? 1 : 0); overflow = false; auto s = std::to_string(ir); if (ir >= 10) { *rd = s[1]; overflow = true; }else *rd = s[0]; } return 0; }
-
Hallo.
Was mir auffällt:
- 48 im Programmcode ist unlesbar und unportabel (Implementierungen müssen dem ASCII-Standard nicht Folge leisten). Besser'0'.
- Zeile 18 - 23 dürfte fehlerhaft sein. Wie die schriftliche Addition funktioniert:9 Lhs +9 Rhs 10 Carry ------------ 18 ErgebnisDie niederwertigste Ziffer des Ergebnisses ist also auch die niederwertigste Ziffer der überflossenen (klingt künstlich) Addition.
Hier meine Alternative (die auch den teuren temporären String undstd::tostringvermeidet) für die Zeilen 16 - 23:overflow = ir >= 10; *rd += ir - (overflow ? 10 : 0);Statt dem
?:-Operator kann man auch eineif-Bedingung machen wenn man das lesbarer findet.Edit: Gänzlich ohne Verzweigungen aber dafür unlesbarer wäre:
overflow = ir >= 10; *rd += ir - overflow * 10;Habe aber gerade keine Lust auszumessen, ob das überhaupt irgendetwas bringt oder ob der Compiler sowieso denselben Code generiert.
Edit 2:
<vector>,<algorithm>und<cmath>brauchst du nicht,<cstdlib>hingegen schon. Resp. auch nicht, da du diestd::abs-Aufrufe in den Zeilen 14 und 15 auch nicht brauchst.