PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Wo ist mein Fehler? C++



lolly
07.04.2010, 22:37
Hey Leute,
sorry für den doofen Threadtitel, mir ist kein besserer eingefallen.
Das Problem ist folgendes:

Wenn man alle Zahlen von 1 - 1000000 aneinanderreiht, und aus der dann entstehenden Zahl die Quersumme nehmen will, was ist das Ergebnis?
Naja ich gebe zu, ich bin kein Mathejunky und habe deshalb die Aufgabenstellung genutzt um mein C++ ein bisschen zu verbessern. Ich schätze mein Stil ist grauenhaft und irgendwo muss ein Fehler in meinem Denken gewesen sein. Es wäre super nett wenn irgendwer mal über den Source guckt und vielleicht meinen Denkfehler entdeckt. Ich persönlich komme gar nicht mehr klar :confused:


#include <iostream>
#include <math.h>

int Ziffern(int zahl){

int stellen = 0;
while(zahl > 0){

zahl /= 10;
stellen++;

}
return stellen;
}

int qsum(int zahl){

int stellen = 0, mod = 10,a = 0, b = 0, qsum = 0;
stellen = Ziffern(zahl);
while(stellen > 0){
a = (int)pow(mod,stellen);
b = (zahl % a) / (a/mod);
qsum += b;
stellen -= 1;
}

return qsum;
}

int main(void){

int i,a;
i = 0;
a = 0;
while(i < 1000000){
a += qsum(i);
i++;
}
std::cout << a << std::endl;
return 0;

}

Ich möchte keine Lösung für die Aufgabe, sondern eine Hilfestellung für den Quelltext. :)

MfG
lolly

sp1nny
07.04.2010, 22:57
Könntest du nochmals erläutern wie genau die Aufgabe lautet? Die wird mir nicht wirklich klar. Desweiteren könnte der Typ Int zu klein werden, was zu Problemen führen wird und du hast wirklich einen sehr "merkwürdigen" Stil.

Beispiele:
- keine Funktionsprototypen, sondern Funktionen über der Main Funktion
- while-Schleifen bei denen For-Schleifen viel besser passen würde
...und und und.

Ich würde dir empfehlen ein Buch zu kaufen und dir dann eine ordentlichen Stil anzugewöhnen. Insgesamt hilft ein Buch auch für viel besseres Verständnis.

lolly
07.04.2010, 23:01
Ja sorry^^ Habe seit >1Jahr kein C++ mehr geschrieben und dachte ich schaus mir mal wieder an...

Also du schreibst alle Zahlen von 1-1000000 aneinander ohne Punkt und Komma.
123456789101112...1000000
Und nimmst daraus die Quersumme. Ich lasse in der Funktion qsum jedes mal die Quersumme einzeln berechnen gerade aus dem von dir genannten Problem mit der Größe des Integer.

Ich hoffe die Erklärung war besser.

GregorSamsa
07.04.2010, 23:02
Ich verstehe gerade nicht so ganz die Aufgabe, wie sp1nny schon sagte.

Und was genau rechnest du da? Das Ergebnis wäre 50000 - wenn ich mich gerade nicht Vertue.

Du kannst mithilfe der Gauß'schen Summenformel alle Zahlen von 1-1000000 addieren, und dann durch 1000000 teilen. Das ist doch einfacher... Oder?

//Edit: Sorry, ich hab gepostet während du gepostet hast ^^

Ich hatte mal eine ähnliche Aufgabenstellung - die Lösung weiß ich nicht mehr, aber du konntest das "Problem" logisch lösen und nicht mit Mathe. Denk nochmal drüber nach, wie die bloße Anordnung der Zahlen sich zueinander verhält...

lolly
07.04.2010, 23:19
Ich glaube die Gauß'sche Summenformel ist nicht ganz passend, oder ich bin noch ein wenig durcheinander. Ich habe das Ganze mal anhand der Zahlen von 1-10 durchgespielt. Ich addiere alle zahlen und erhalte 55 teile das durch 10 und habe 5... meine gesuchte Zahl war aber 46.

Oder drehe ich grad komplett durch? :D

sp1nny
07.04.2010, 23:30
Ich habe hier mal ein Beispiel gemacht wie ich Quersummen bilden würde ( keine Ahnung was du für eine Akrobatik machst ;) ):



#include <iostream>
using namespace std;

//--------------------------------------------------------------------------

int csum(int);

//--------------------------------------------------------------------------

int main(void){

int iNumber;

cout << "Bitte eine Zahl eingeben zu der die Quersumme berechnet werden soll!" << endl;
cout << "Zahl: " ;

if(!(cin >> iNumber))
exit(1);

cout << "\n\nDie Quersumme von " << iNumber << " ist : " << csum(iNumber) << endl;

cin.ignore();
cin.get();

return 0;
}

//--------------------------------------------------------------------------

int csum(int iNumber){

int iChecksum = 0;

do{
iChecksum += iNumber % 10;
iNumber /= 10;
}while(iNumber > 0);

return iChecksum;
}

GregorSamsa
07.04.2010, 23:33
Nene, ich hatte geschrieben, während lolly gepostet hat - daher hab ich das "richtige" nicht mitbekommen.. ^^

Man beachte meinen Edit...

rogger
07.04.2010, 23:36
So wie ich dem Fragensteller verstehen geht es eher um ein aneinanderreihen á la String ( "1" + "2"= "12" ) und kein addiren.
deswegen würde ich eher sowas mit vorschlagen:
python (ungetestet):


grossezahlstr=""
for i in range(0,100000):
grossezahlstr+=str(i)
grossezahl=int(grossezahlstr)
quersumme=qsum(grossezahl)
ich bin doch einfach python fan

//edit
wobei mir gerade noch einfällt, dass es vielleicht bei sehr grossen Zahlen schneller geht wenn man in der schleife die quersummer der einzelnen Zahl berechnet und aufaddiert so muss man nicht die quersummer von der großen Zahlberechnen, wobei das ja eigentlich auch keine großen unterschied ausmachen müsste...
ich glaube es ist heute schon etwas zu spät für Matheakrobatik...
weil so ganz sicher bin ich mir jetzt da auch nicht

sp1nny
07.04.2010, 23:40
Und wie bildet man Quersummen ohne zu addieren? :)
Von der langen Zahl soll dieser nämlich gebildet werden.

rogger
07.04.2010, 23:44
@sp1nny bezieht sich deine Antwort auf meinen Post?
weil ich ja nur die Quersummen funktion aufrufe ich habe ja jetzt keine selber geschrieben.

aber ich finde so eine Aufgabenstellung ist einfach prädestiniert dazu in Python umgesetzt zu werden...

lolly
07.04.2010, 23:50
@GregorSamsa: Okay mein Fehler^^

@sp1nny: Okay ich dachte mir schon, dass es schöner geht. Habe wohl irgendwas falsch verstanden^^ Letztendlich kommen wir aber auf das selbe Ergebnis mit den Quersummen :) Wobei das Ergebnis immernoch falsch ist >.< *grübel*
Aber wenn ich die Quersummen der einzelnen Zahlen, zu meiner Summe addiere, bin ich doch auf dem richtigen Weg?

Argh ich seh es kommen, ich bekomme heute Nacht kein Auge zu :D
Trotzdem danke für den schöneren Beispielsource.

sp1nny
07.04.2010, 23:55
Freut mich geholfen zu haben, wenn ich morgen Zeit finde, werde ich mich nochmals hiermit auseinandersetzen und den Fehler suchen. Viel Glück noch. :)

MfG

GregorSamsa
08.04.2010, 00:04
Noch mal was "logisches" zu Quersummen.

Normalerweise kannst du davon ausgehen, dass du alle Zahlen, die in der Summe 9 ergeben, effektiv eine 1 ergeben:
197821 = 1 + 9 + (7+2 = 9) + (8+1 = 9)
1 + 9 = 10 = 1
ergo:
1 + 9 = 1; 1 + (7 + 2) = 1; 1 + (8+1) = 1;
Die Quersumme von 197821 ist 1

So, jetzt fängst du an zu überlegen:
123456789101112131415
Dann "Wegnehmen" aller Zahlen von 1-9, die zusammen eine 9 Ergeben. Das Ergebnis währe:
1 101112131415
14+15 = 1+1+(5+6 = 9, also entfernen) = 2
Übrig:
1101112132
So, jetzt kannst du "Weiterrechnen" - alles was zusammen 9 Ergibt, streichen.
3+2+2+1+1 = 0
Stand: 1111
1+1+1+1 = 4

So kannst du relativ effektiv Zahlen ausschließen - wenn du jetzt das ein bisschen weiter denkst, könntest du ohne große Rechenoperationen/Schleifen/große Zahlen zu einem Ergebnis kommen... ;)

(Sry, vorhin hatte ich was verwechselt... ^^)

$_staX
08.04.2010, 00:10
http://mibs-challenges.de/challenge.php?id=41

lolly, ich mag Menschen wie dich nicht!

GregorSamsa
08.04.2010, 00:11
Ööhhmmm... war das auf mich bezogen oO?

Also das "Lösungssystem" hab ich mir selber so ausgedacht... Nix kopiert...

$_staX
08.04.2010, 00:15
Nein GregorSamsa, das ist eine Seite mit Challenges und lolly bettelt ja offensichtlich um eine Lösung, auch wenn er schreibt, dass er keine Lösung will ;)

btw ist die Aufgabe wirklich nicht schwer

lolly
08.04.2010, 00:18
$_StaX:

Es geht um das Problem richtig. Deswegen habe ich in meinem ersten Post geschrieben, dass ich keine Lösungen möchte. Ich habe versucht das Problem programmiertechnisch zu lösen. Meine Erfahrungen haben nicht ausgereicht und ich habe hier um Hilfestellung für mein Problem gebeten. Ich habe keine Lösungen erhalten und werde mich auch weiterhin selbst an dem Problem versuchen.
Soweit ich weiß, ist der Sinn der Seite etwas zu lernen... Das versuche ich gerade. Da finde ich Aussagen wie: "Ich hasse Menschen wie dich" reichlich niveaulos....

Wie gesagt ich möchte hier keine Lösung für die Aufgabe ich möchte Hilfe dabei meine Lösungsansätze umzusetzen. Durch den Tip von GregorSamsa habe ich nun einen anderen Ansatz den ich versuchen kann umzusetzen.

$_staX
08.04.2010, 00:21
1+1=10 Wer hilft mir das richtig zu stellen aber bitte keine Lösung (Meine Mathekentnisse sind schlecht aber der Ansatz ist ja da) ;)
Merkst du, dass sich da was beißt? Wenn du eine Challenge nicht schaffst mach die nächste und versuch dich dann wieder dran, klappt garantiert, mach ich auch so ;)

GregorSamsa
08.04.2010, 00:21
Also: was dir bewusst sein sollte ist, dass es _nicht_ darum geht, dass Programmiertechnisch zu lösen, sondern mithilfe von logischem Denken...!

Daher: Weg von Editor und Compiler, und starte deine brain.exe um mal drüber nachzudenken ;)
Es ist keine "Programmiertechnische" Lösung...

k0rxxx
08.04.2010, 00:23
pro tipp:
unsigned __int32
unsigned __int64http://de.wikipedia.org/wiki/Integer_%28Datentyp%29#Maximaler_Wertebereich_von_ Integer

Cristhecrusader
08.04.2010, 01:28
Also wenn ihr mich fragt reicht int auch nicht aus um das auszurechnen :O

krypt0n
08.04.2010, 05:21
Eventuell solltest du nächstes Mal deine Frage etwas detaillierter stellen, so wie du sie aktuell gestellt hast sieht es für mich auch so aus, als ob du mal irgendwas gecodet hast und nun von uns willst, dass wir deinen kompletten Code überarbeiten.

Eine ziemlich optimale Lösung hat sp1nny ja schon gepostet.

blackberry
08.04.2010, 15:04
Also wenn ihr mich fragt reicht int auch nicht aus um das auszurechnen :O

Tuts auch.
25 Zeilen bei mir und das Problem war gelöst - wo liegt also das Problem?

sp1nny
08.04.2010, 15:58
Hier mein Source zum lösen des Problems, bitte nur angucken, wenn du es unter keinen Umständen mehr hinbekommst.





#include <iostream>
using namespace std;

//--------------------------------------------------------------------------

int csum(int);
int getcsumforrange(int);

//--------------------------------------------------------------------------

int main(void){

cout << getcsumforrange(1000000);

cin.get();
return 0;
}

//--------------------------------------------------------------------------

int csum(int iNumber){

int iChecksum = 0;

do{
iChecksum += iNumber % 10;
iNumber /= 10;
}while(iNumber > 0);

return iChecksum;
}

//--------------------------------------------------------------------------

int getcsumforrange(int iRange){

int iRangechecksum = 0;

for(int i = 0; i <= iRange; i++){
iRangechecksum += csum(i);
}

return iRangechecksum;
}

lolly
08.04.2010, 21:51
Hatte den Fehler schon gefunden und mein Problem gelöst!
War zu simpel um wahr zu sein... Naja sowas sieht man immer erst auf den 3ten Blick.
Trotzdem danke an alle für die Hilfsbereitschaft