Listeneinträge addieren - Problem: Übertrag

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
TiMMe129
User
Beiträge: 4
Registriert: Dienstag 28. Juni 2016, 20:43

Hallo liebe Community,

meine Aufgabe ist es den 196-Algorithmus zu programmieren.

Hier mein bisheriges Ergebnis (ich nutze Spyder):

Code: Alles auswählen

b=list(raw_input('Geben Sie eine natuerliche Zahl n>=10 an: '))

for i in range(0,len(b)):
        b[i]=int(b[i])
print b

g=[]

def p(x,z):
    global b,g
    c=reversed(b)
    d=list(c)
    if b==d:
        print 'Die beiden Zahlen sind Palindrome!'
        return b,d
    else:
        for j in range(0,len(d)):        
            g[len(d)-1-j]=b[len(d)-1-j]+d[len(d)-1-j]
            print g
            if g[j]>9:                                                   (*)
                g[j]=g[j]-10
        b=g
        print b
        z=z+1    
        return p(b,z)

for i in range (0,len(b)):
    g.append(0)
print g

print p(b,0)

Mein Problem (ab (*)) ist nun folgendes: Dieser Algorithmus fkt. für Zahlen wie 123 super, habe ich aber Zahlen bei deren Addition mit der zugehörigen Spiegelzahl ein Übertrag auftritt, z.B. 56 (56+65=121) klappt es nicht mehr.

Daher meine Frage wie z.B. [5,6]+[6,5]=[1,2,1] anstatt =[11,11] entsteht.

Vllt kann mir ja wer weiterhelfen :)
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@TiMMe129: bevor Du hier versuchst Deinen Algorithmus zu reparieren, solltest Du nochmal Deinen Code Zeile für Zeile durchgehen und versuchen zu verstehen was Du da geschrieben hast.
Einbuchstabige Variablennamen sind schlecht, weil man da leicht den Überblick verliert. Was ist x, b, c, g? x wird z.b. gar nicht verwendet. Ebensowenig z. global solltest Du nicht verwenden, weil das Deine Funktion auch unübersichtlicher macht. Am besten erzeugst Du Listen neu, statt sie wieder zu verwenden. Das führt bei Deinem Code zu schwer zu findenden Fehlern.
TiMMe129
User
Beiträge: 4
Registriert: Dienstag 28. Juni 2016, 20:43

Mir ist durchaus bewusst, dass mein Algorithmus dahingehend alles andere als übersichtlich ist, allerdings spielt das bei meiner Frage ja im Prinzip keine Rolle, oder? Ich hätte die Frage ja auch ohne Algorithmus ganz allgemein stellen können. Es geht mir in dem Sinne nur um die Operation mit Listen, mit dem Algorithmus wollte ich nur verdeutlichen, weshalb ich die Frage stelle.
BlackJack

@TiMMe129: Natürlich spielt das eine Rolle ob man den Quelltext lesen und verstehen können soll. Die Frage ohne den Quelltext, könnte man doch gar nicht beantworten, denn Du fragst ja wieso da ein bestimmtes Ergebnis eintritt. Wenn man nicht weiss was der 196-Algorithmus sein soll und dann Deinen Code anschaut, möchte man das auch gar nicht mehr heraus finden. ;-)
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Von schriftlicher Addition und Spiegelzahlen hast du sicherlich in der Grundschule gehört. Einem Grundschüler sollte der Algorithmus durchaus zu vermitteln sein so dass dieser den anwenden kann. Es gibt nichts was daran schwierig sein sollte.

Schwierig wird es hier aber weil dein Code absolut unverständlich ist. Anhand des Codes ist es überhaupt nicht klar was dass für ein Algorithmus sein sollte, was dabei rauskommt oder was du gehofft hast dass dabei rauskommt. Offensichtlich geht es nicht nur mir als Leser so sondern auch dir als Autor.

Der Code spielt nicht nur eine Rolle, er spielt die entscheidende Rolle. Vergiss den Code, schau dir den Algorithmus nochmal an und brich ihn in seine Bestandteile auf und verwende Funktionen. Eine Funktion um die Spiegelzahl zu ermitteln, eine Funktion für Addition, eine Funktion die darauf prüft ob eine Zahl ein Palindrom ist und eine Funktion für den Algorithmus selbst.

In der Funktion die Addition implementiert, mach deutlich wie zwei Stellen addiert werden, was passiert wenn dass Ergebnis > 9 ist und dass dann ein Übertrag entsteht, zeig wie dieser in die Berechnung für nächste Stelle einfliesst.
Benutzeravatar
noisefloor
User
Beiträge: 3854
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

@TiMMe129: Willst / musst du nur den Algorithmus programmieren, so dass am "nur" das Ergebnis (=die Spiegelzahl) hat oder willst / musst du alle Schritte dorthin ebenfalls zeigen / aufzeichnen?

Gruß, noisefloor
TiMMe129
User
Beiträge: 4
Registriert: Dienstag 28. Juni 2016, 20:43

Ich habe es jetzt hinbekommen, bedanke mich aber trz für alle Tipps und Anregungen und werde versuchen es vor Abgabe noch etwas zu verfeinern und übersichtlicher zu gestalten.

Code: Alles auswählen

b=list(raw_input('Geben Sie eine natuerliche Zahl n>=10 an: '))

for i in range(0,len(b)):
        b[i]=int(b[i])

def p(x,z):
    global b,g
    c=reversed(b)
    d=list(c)
    print 'Spiegelzahl: '
    print ListToInt(d)
    if b==d:
        print 'Die Zahl',ListToInt(b),'ist ein Palindrom!'
        print 'Anzahl der Ausführungen: '
        return z
    else:
        g=ListToInt(b)+ListToInt(d)
        g=IntToList(g)        
        b=g
        z=z+1    
        return p(b,z)

def ListToInt(g):
    x=0
    for i in range (0,len(g)):
       x=g[i]*(10**(len(g)-1-i))+x    
    return x
    
def IntToList(x):
    str_x=str(x)
    list_x=list(str_x)
    for i in range(0,len(list_x)):
        list_x[i]=int(list_x[i])
    return list_x  
            
print p(b,0) 
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@TiMMe129: Du hast das Problem mit dem Übertrag jetzt umgangen, indem Du statt mit Listen mit Zahlen rechnest. Für das korrekte Rechnen mit Listen muß man einfach das, was man in der Grundschule gelernt hat, nach Python übertragen:

Code: Alles auswählen

from itertools import izip_longest
from itertools import izip_longest

def addiere(a, b):
    ergebnis = []
    uebertrag = 0
    for u, v in izip_longest(a, b, fillvalue=0):
        uebertrag, zahl = divmod(u + v + uebertrag, 10)
        ergebnis.insert(0, zahl)
    if uebertrag:
        ergebnis.insert(0, uebertrag)
    return ergebnis
Bei Deiner jetzigen Lösung vereinfacht sich einiges, wenn Du statt mit Listen mit Strings arbeitest, dann sind die Funktionen ListToInt und IntToList überflüssig und das Programm vereinfacht sich zu:

Code: Alles auswählen

from itertools import count

def p(b):
    for z in count():
        if b == b[::-1]:
            break
        b = str(int(b) + int(b[::-1]))
    return b, z
            
b = raw_input('Geben Sie eine natuerliche Zahl n>=10 an: ')
b, z = p(b)
print 'Die Zahl {} ist ein Palindrom!'.format(b)
print 'Anzahl der Ausführungen: {}'.format(z)
BlackJack

Ach das war gemeint. :-) Das habe ich auch mal zu Schulzeiten umgesetzt. Auf dem C64, in BASIC. Mal die Diskette raus suchen… Liegt in drei Versionen vor. Einmal für das Programm ”basic assembler”, was der eigentliche Quelltext war, den ich eingegeben hatte, ohne Zeilennummern, dafür mit Labeln, und der hat das dann zu einem normalen CBM BASIC-Programm ”übersetzt”:

[codebox=locobasic file=Unbenannt.txt] 2 poke 53280,6:poke 53281,14
4 dim z1(39),z2(39),er(39)
6 print "{blue}{clear}{lower case}{up/lo lock on}{down} Palindrom oder 'Das 196-Problem'"
8 print "{down} Bitte geben Sie eine zwei- oder mehr-"
10 print "{down} stellige Zahl ein !!!"
12 print "{down}>";
14 poke 19,1
16 input e$
18 poke 19,0
20 l=len(e$)
22 if l<2 or l>20 then run
24 for i=1 to l
26 z1(39-l+i)=asc(mid$(e$,i,1))-48
28 next
30 print "{clear}";
32 print tab(39-l);
34 for i=40-l to 39
36 print chr$(z1(i)+48);
38 next
40 for i=1 to l
42 z2(39-l+i)=z1(40-i)
44 next
46 print:print tab(39-l);
48 for i=40-l to 39
50 print chr$(z2(i)+48);
52 next
54 print:print tab(39-l);
56 for i=1 to l
58 print "{shift asterisk}";
60 next
62 ue=0
64 for i=0 to l-1
66 er(39-i)=z1(39-i)+z2(39-i)+ue
68 ue=int(er(39-i)/10)
70 if ue>0 then er(39-i)=er(39-i)-ue*10
72 next
74 if ue>0 then l=l+1:er(40-l)=ue
76 print:print tab(39-l);
78 for i=40-l to 39
80 print chr$(er(i)+48);
82 next
84 ue=0
86 for i=0 to int(l/2)
88 if er(40-l+i)<>er(39-i) then ue=ue+1
90 next
92 if ue=0 then end
94 if l=39 then print:print "{down}Nicht mit 39 Stellen loesbar !!!":end
96 for i=0 to l
98 z1(39-i)=er(39-i)
100 next
102 goto40[/code]
Und das dann durch ein Programm gejagt das überflüssige Leerzeichen entfernt und Zeilen zusammenfasst und dabei so viel wie möglich in jede Zeile quetscht. Teilweise mehr als man manuell über den BASIC-Editor vom C64 eingeben kann, denn der Zeilenpuffer dort ist 80 Zeichen lang, technisch kann der BASIC-Interpreter aber mit Zeilen umgehen in denen bis zu 255 Bytes stecken. :-)
[codebox=locobasic file=Unbenannt.txt] 2 poke53280,6:poke53281,14:dimz1(39),z2(39),er(39):print"{blue}{clear}{lower case}{up/lo lock on}{down} Palindrom oder 'Das 196-Problem'":print"{down} Bitte geben Sie eine zwei- oder mehr-":print"{down} stellige Zahl ein !!!":print"{down}>";:poke19,1:inpute$:poke19,0:l=len(e$):ifl<2orl>20thenrun
24 fori=1tol:z1(39-l+i)=asc(mid$(e$,i,1))-48:next:print"{clear}";:printtab(39-l);:fori=40-lto39:printchr$(z1(i)+48);:next
40 fori=1tol:z2(39-l+i)=z1(40-i):next:print:printtab(39-l);:fori=40-lto39:printchr$(z2(i)+48);:next:print:printtab(39-l);:fori=1tol:print"{shift asterisk}";:next:ue=0:fori=0tol-1:er(39-i)=z1(39-i)+z2(39-i)+ue:ue=int(er(39-i)/10):ifue>0thener(39-i)=er(39-i)-ue*10
72 next:ifue>0thenl=l+1:er(40-l)=ue
76 print:printtab(39-l);:fori=40-lto39:printchr$(er(i)+48);:next:ue=0:fori=0toint(l/2):ifer(40-l+i)<>er(39-i)thenue=ue+1
90 next:ifue=0thenend
94 ifl=39thenprint:print"{down}Nicht mit 39 Stellen loesbar !!!":end
96 fori=0tol:z1(39-i)=er(39-i):next:goto40[/code]
Eine Implementierung in Assembler müsste ich auch noch irgendwo haben.
Benutzeravatar
noisefloor
User
Beiträge: 3854
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

ich wäre das Problem auch ähnlich wie Sirius3 angegangen, also komplett ohne Liste. Ist IMHO viel einfacher.

Gruß, noisefloor
TiMMe129
User
Beiträge: 4
Registriert: Dienstag 28. Juni 2016, 20:43

Ich bedanke mich für die Programmvorschläge, leider enthalten die sehr viele Befehle, die wir nicht behandelt haben. Allerdings ist es auch nur ein Modul aus dem Lehramts Mathematik Studiengang, von daher glaube ich auch nicht weiter verwunderlich. Trz danke für eure Zeit.
Antworten