palindrome

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.
cyp++
User
Beiträge: 69
Registriert: Freitag 22. September 2006, 13:54

hi

ich habe ein kleines problem.

Code: Alles auswählen

inp = raw_input('Palindrompruefung: ')
t = inp.upper()
k = ''
i = 0
while i < len(inp):
    if t[i] >= 'A' and t[i] <= 'Z' or t[i] >= 'a' and t[i] <= 'z':
        k += inp[i]
    i += 1
l = k.lower()
print l


d = len(l)
for i in range(d+1):
    if l[i] == l[-(i+1)]:
        print 'k'
    else:
        print 'nicht k'
es gahr darum, zu prüfen, ob es sich bei der eingabe um ein palindrom handelt. bitte beachtet den ersten abschnitt nicht, ich habe einfach drauf los getippt und es funktioniert, doch der 2. teil funzt nicht ganz! ich bekom immer einen IndexError: String Index out of range in zeile 15
was ist falsch daran?

mfg
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

so geht es.

Code: Alles auswählen

for i in range(len(l)): # <------- das +1 weggemacht, damit es nicht zum Index Error kommt. Der ganze Code von dir scheint zu funtzen! :)
    if l[i] == l[-(i+1)]: # <------- zeile 15
        print l[i]
   else:
        print 'nicht k'
Der Fehler ligt daran das du oberhalb der Lenge von l iterierst und es so zu eine index error kommt ;) Sprich: Der letzte index ist nicht mehr in list l vorhanden und daher der Fehler.

EDIT: Aber mal so nebenbei, was sol der untere teil machen? Wenn ich otto eingebe wird mir otto angezeigt. wenn ich aber ottos (^^) eingebe wird mir nur ein t angezeigt :?


EDIT2: Ok ich hatte die else vergessen zu kopieren ^^ Wird aber dadurch auch nicht logischer für mich. wenn ein Zeichen doppelt ist, wird if ausgeführt ansonsten else. In wie fern sol das dazu beitragen um zu testen, ob das Wort ein Palindrom ist :?

EDIT3: Ok, nun hab ichs verstanden wie das funktioniert ^^ Coole Sache! :)

EDIT4:
cyp++ hat geschrieben:ja es ist noch nicht ganz fertig, wenn überall 'k' steht ist es ein palindrom! ich muss die ausgabe noch bissl abändern!
Jepp, hab ich auch gerade gemerkt. Der Code ist aber ein wenig schwer zu lesen Funktioniert bei mir aber 100% (habs mit otto ausprobiert). Werde den code noch ein wenig studieren ^^
Zuletzt geändert von sape am Donnerstag 9. November 2006, 11:34, insgesamt 3-mal geändert.
cyp++
User
Beiträge: 69
Registriert: Freitag 22. September 2006, 13:54

ja es ist noch nicht ganz fertig, wenn überall 'k' steht ist es ein palindrom! ich muss die ausgabe noch bissl abändern!
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

OK, die while schleife würde ich weg machen und stattdessen mit einer for schleife über inp iterieren ;) Ist Pythonischer. schließlich sind wir ja hier nicht bei C/C++ ^^

EDIT: Nicht d+1. Ist der gleiche Fehler wie vorhin der einen Index Error auslöst!
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Hier mal der aufgeräumte Code.

Code: Alles auswählen

inp = 'otToS' # raw_input('Palindrompruefung: ')
k = ''

for i in inp:
    if i >= 'A' and i <= 'Z' or i >= 'a' and i <= 'z':
        k += i
        
l = k.lower()
print l

for i in range(len(l)):
    if l[i] == l[-(i+1)]:
        print "l:", l[i]
    else:
        print "nicht k"
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

So und hier die Finale Version.

Code: Alles auswählen

inp = 'Madam' # raw_input('Palindrompruefung: ')
k = ''

for i in inp:
    if i >= 'A' and i <= 'Z' or i >= 'a' and i <= 'z':
        k += i
        
k = k.lower()

for i in range(len(k)):
    if k[i] == k[-(i+1)]:
        print k[i]
    else:
        print "Das Wort %s ist kein Palindrome" %k
        break
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Code: Alles auswählen

k=k.lower()
if k == k[::-1]:
     print "Ist ein Palindrom"
else:
     print "Ist kein Palindrom"
BlackJack

Fast. Du filterst keine nicht-Buchstaben.

Code: Alles auswählen

def is_palindrom(s):
    s = [c.lower() for c in s if c.isalpha()]
    return s == s[::-1]

print is_palindrom('Satan, oscillate my metallic sonatas!')
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Hmm, interessant. Das heißt k[::-1] macht ein Reverse. Wuste ich ja noch gar nicht :)

Hab auch noch einen ^^ ;):

Code: Alles auswählen

import re

def isPalindrome(string):
    if len( re.findall("([^a-z-A-Z])", string)):
        print "Fehler der String %s enthaelt andere Zeichen ausser a-z oder A-Z!" %string
        return False
    else:
        string=string.lower()
        if string == string[::-1]:
            print "%s ist ein Palindrom" %string
            return True
        else:
            print "%s ist kein Palindrom" %string
            return False
        


isPalindrome("hallo456")
isPalindrome("test%&/")
isPalindrome("otto")
isPalindrome("oTTO")
isPalindrome("madam")
isPalindrome("Hallo")
EDIT:BlackJack wahr mal wider schneller ^^ BTW: Bis her ist seine Variante am besten ^^
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

:shock: :shock: :shock: @ Satan, oscillate my metallic sonatas! = True
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

@BlackJack: Das ist nur eine Kontext-Frage. Palindrom ist schließlich nicht Palindrom. In der engsten Definition liefern meine Zeilen die korrekte Antwort, wenn man den Begriff weiter fast, dann natürlich nicht.

Noch ein Goodie:
Für DNA habe ich noch folgende Version (hierbei ist self eine Instanz der DNA-Klasse und dieser scheinbare Aufwand, den ich treibe tatsächlich die beste Lösung, nämlich dann, wenn man mehr als vier komplementäre Basen - aus einem best. Grund habe ich eine ungerade Anzahl von Basen als nicht palindromisch einsortiert):

Code: Alles auswählen

    def check_palindromic(self):
        s = self.seq
        if (len(s)%2) == 0 and s[len(s)/2:] == DNA(s[:len(s)/2]).reversecomplement():
                return True
        else: return False
Gruß,
Christian
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

BlackJack hat geschrieben:Fast. Du filterst keine nicht-Buchstaben.

Code: Alles auswählen

def is_palindrom(s):
    s = [c.lower() for c in s if c.isalpha()]
    return s == s[::-1]

print is_palindrom('Satan, oscillate my metallic sonatas!')
funktioniert nicht da auch bei && oder5555 oder sonstwas ein True zurückgegeben wird.
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

So gehts:

Code: Alles auswählen

def is_palindrom(s):
    s = [c.lower() for c in s if c.isalpha()]
    return s == s[::-1] and len(s) != 0

print is_palindrom("9%$")
print is_palindrom("otto")

Code: Alles auswählen

False
True
BlackJack

CM hat geschrieben:@BlackJack: Das ist nur eine Kontext-Frage. Palindrom ist schließlich nicht Palindrom. In der engsten Definition liefern meine Zeilen die korrekte Antwort, wenn man den Begriff weiter fast, dann natürlich nicht.
Schon klar. Als Kontext bin ich davon ausgegangen es soll dass tun was das Programm von cyp++ auch macht.
cyp++
User
Beiträge: 69
Registriert: Freitag 22. September 2006, 13:54

danke für all eure hilfen! :D hier mal mein endergebnis:

Code: Alles auswählen

# eingabe durch den user

eingabe = raw_input('Palindrompruefung: ')

# umwandlung in grossbuchstaben

eingabe_gross = eingabe.upper()

k = ''

# schleifen-zaehler

i = 0

# zeichen-zaehler

zaehler = 0

# start des programms

while i < len(eingabe):
    # wenn zeichen nicht innerhalb von A-Z oder a-z, raus damit!
    if eingabe_gross[i] >= 'A' and eingabe_gross[i] <= 'Z' or eingabe_gross[i] >= 'a' and eingabe_gross[i] <= 'z':
        k += eingabe[i]

    i += 1

# umwandlung in kleinbuchstaben

eingabe_klein = k.lower()

# ermittlung der laenge von l

d = len(eingabe_klein)

for i in range(d):
    # wenn i-tes zeichen gleich -(i-tes-zeichen + 1)...
    if eingabe_klein[i] == eingabe_klein[-(i+1)]:
        # ... addiere 1 zum zaehler
        zaehler += 1

# wenn zaehler der anzahl der zeichen des eingebenen strings entspricht, handelt es sich um ein palindrom!

if zaehler == len(eingabe_klein):
    print '\n',eingabe_klein, 'ist ein Palindrom.'

# wenn nicht, ist es kein palindrom!

else:
    print '\n',eingabe_klein, 'ist kein Palindrom.'
gibts noch verbesserungsvorschläge?
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

cyp++ hat geschrieben: gibts noch verbesserungsvorschläge?
Na ja, will ja nicht so direkt fragen ... aber hast Du Dir mal die anderen Posts angeschaut?

Gruß,
Christian
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

cyp++ hat geschrieben:[...]
gibts noch verbesserungsvorschläge?
Ja ^^

Code: Alles auswählen

def is_palindrom(s):
    s = [c.lower() for c in s if c.isalpha()]
    return s == s[::-1] and len(s) != 0

# Test
print is_palindrom("9%$")
print is_palindrom("otto")
Dein Code ist zu lang und zu unpythonic. Dein Code erinnert an C/C++. Du kommst nicht zufällig aus der C/C++ ecke?
BlackJack

Hm ich würde das noch ein klein wenig ändern, IMHO erfüllt eine leere Zeichenkette auch die Palindrom-Eigenschaft:

Code: Alles auswählen

def is_palindrom(s):
    if not s:
        return True
    s = [c.lower() for c in s if c.isalpha()]
    return s and s == s[::-1]
cyp++
User
Beiträge: 69
Registriert: Freitag 22. September 2006, 13:54

CM hat geschrieben:
cyp++ hat geschrieben: gibts noch verbesserungsvorschläge?
Na ja, will ja nicht so direkt fragen ... aber hast Du Dir mal die anderen Posts angeschaut?

Gruß,
Christian
vll weißt du es nicht, aber ich bin anfänger 11. klasse ausbildung zum tai. das hatten wir noch alles gar nicht!
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

BlackJack hat geschrieben:Hm ich würde das noch ein klein wenig ändern, IMHO erfüllt eine leere Zeichenkette auch die Palindrom-Eigenschaft:

Code: Alles auswählen

def is_palindrom(s):
    if not s:
        return True
    s = [c.lower() for c in s if c.isalpha()]
    return s and s == s[::-1]
OK, aber nicht im sinne von einem Wort/Begriff. Otto ist ein Palindrom aber ein Leerzeichen ist einfach nichts und mMn wäre es verkehrt dann ein True zurückzugeben. Aber in weitesten Sinne magst du wohl rech haben, wie auch CM mit seinen Code.

Code: Alles auswählen

k=k.lower()
if k == k[::-1]:
     print "Ist ein Palindrom"
else:
     print "Ist kein Palindrom"
Aber danach wurde ja nicht gefragt. Die Anforderung beschränkte sich ja nur auf Begriffe und nicht auf Leerzeichen oder (wie in CMs Beispiel) auf Alle Chars.

lg

EDIT:
@cyp++:
Dabei fällt mir die regel 1 vom Zen ein: Schön ist besser als hässlich.
und die regel 3: Einfach ist besser als komplex.

EDIT2: Im ersten Edit das @cyp++ vergessen.
Zuletzt geändert von sape am Freitag 10. November 2006, 17:23, insgesamt 1-mal geändert.
Antworten