Python word counter

I'm taking a Python 2.7 course at school, and they told us to create the following program:

Assume s is a string of lower case characters.

Write a program that prints the longest substring of s in which the letters occur in alphabetical order.

For example, if s = azcbobobegghakl , then your program should print

Longest substring in alphabetical order is: beggh

In the case of ties, print the first substring.

For example, if s = 'abcbcd', then your program should print

Longest substring in alphabetical order is: abc

I wrote the following code:

s = 'czqriqfsqteavw'

string = ''

tempIndex = 0
prev = ''
curr = ''

index = 0
while index < len(s):
    curr = s[index]
    if index != 0:
        if curr < prev:
            if len(s[tempIndex:index]) > len(string):
               string = s[tempIndex:index]
            tempIndex=index
        elif index == len(s)-1:
            if len(s[tempIndex:index]) > len(string):
               string = s[tempIndex:index+1]
    prev = curr
    index += 1

print 'Longest substring in alphabetical order is: ' + string

The teacher also gave us a series of test strings to try:

onyixlsttpmylw  
pdxukpsimdj  
yamcrzwwgquqqrpdxmgltap  
dkaimdoviquyazmojtex  
abcdefghijklmnopqrstuvwxyz  
evyeorezmslyn  
msbprjtwwnb  
laymsbkrprvyuaieitpwpurp  
munifxzwieqbhaymkeol   
lzasroxnpjqhmpr    
evjeewybqpc   
vzpdfwbbwxpxsdpfak    
zyxwvutsrqponmlkjihgfedcba  
vzpdfwbbwxpxsdpfak     
jlgpiprth  
czqriqfsqteavw 

All of them work fine, except the last one, which produces the following answer:

Longest substring in alphabetical order is: cz

But it should say:

Longest substring in alphabetical order is: avw

I've checked the code a thousand times, and found no mistake. Could you please help me?


These lines:

        if len(s[tempIndex:index]) > len(string):
           string = s[tempIndex:index+1]

don't agree with each other. If the new best string is s[tempIndex:index+1] then that's the string you should be comparing the length of in the if condition. Changing them to agree with each other fixes the problem:

        if len(s[tempIndex:index+1]) > len(string):
           string = s[tempIndex:index+1]

I see that user5402 has nicely answered your question, but this particular problem intrigued me, so I decided to re-write your code. :) The program below uses essentially the same logic as your code with a couple of minor changes.

It is considered more Pythonic to avoid using indices when practical, and to iterate directly over the contents of strings (or other container objects). This generally makes the code easier to read since we don't have to keep track of both the indices and the contents.

In order to get access to both the current & previous character in the string we zip together two copies of the input string, with one of the copies offset by inserting a space character at the start. We also append a space character to the end of the other copy so that we don't have to do special handling when the longest ordered sub-sequence occurs at the end of the input string.

#! /usr/bin/env python

''' Find longest ordered substring of a given string 

    From http://stackoverflow.com/q/27937076/4014959
    Written by PM 2Ring 2015.01.14
'''

data = [
    "azcbobobegghakl",
    "abcbcd",
    "onyixlsttpmylw",
    "pdxukpsimdj",
    "yamcrzwwgquqqrpdxmgltap",
    "dkaimdoviquyazmojtex",
    "abcdefghijklmnopqrstuvwxyz",
    "evyeorezmslyn",
    "msbprjtwwnb",
    "laymsbkrprvyuaieitpwpurp",
    "munifxzwieqbhaymkeol",
    "lzasroxnpjqhmpr",
    "evjeewybqpc",
    "vzpdfwbbwxpxsdpfak",
    "zyxwvutsrqponmlkjihgfedcba",
    "vzpdfwbbwxpxsdpfak",
    "jlgpiprth",
    "czqriqfsqteavw",
]


def longest(s):
    ''' Return longest ordered substring of s
        s consists of lower case letters only.
    '''
    found, temp = [], []
    for prev, curr in zip(' ' + s, s + ' '):
        if curr < prev:
            if len(temp) > len(found):
                found = temp[:]
            temp = []
        temp += [curr]
    return ''.join(found)


def main():
    msg = 'Longest substring in alphabetical order is:'
    for s in data:
        print s
        print msg, longest(s)
        print


if __name__ == '__main__':
    main()  

output

azcbobobegghakl
Longest substring in alphabetical order is: beggh

abcbcd
Longest substring in alphabetical order is: abc

onyixlsttpmylw
Longest substring in alphabetical order is: lstt

pdxukpsimdj
Longest substring in alphabetical order is: kps

yamcrzwwgquqqrpdxmgltap
Longest substring in alphabetical order is: crz

dkaimdoviquyazmojtex
Longest substring in alphabetical order is: iquy

abcdefghijklmnopqrstuvwxyz
Longest substring in alphabetical order is: abcdefghijklmnopqrstuvwxyz

evyeorezmslyn
Longest substring in alphabetical order is: evy

msbprjtwwnb
Longest substring in alphabetical order is: jtww

laymsbkrprvyuaieitpwpurp
Longest substring in alphabetical order is: prvy

munifxzwieqbhaymkeol
Longest substring in alphabetical order is: fxz

lzasroxnpjqhmpr
Longest substring in alphabetical order is: hmpr

evjeewybqpc
Longest substring in alphabetical order is: eewy

vzpdfwbbwxpxsdpfak
Longest substring in alphabetical order is: bbwx

zyxwvutsrqponmlkjihgfedcba
Longest substring in alphabetical order is: z

vzpdfwbbwxpxsdpfak
Longest substring in alphabetical order is: bbwx

jlgpiprth
Longest substring in alphabetical order is: iprt

czqriqfsqteavw
Longest substring in alphabetical order is: avw

Indices are your friend. below is a simple code for the problem.

longword = ''

for x in range(len(s)-1):
    for y in range(len(s)+1):
        word = s[x:y]
        if word == ''.join(sorted(word)):
            if len(word) > len(longword):
                longword = word
print ('Longest substring in alphabetical order is: '+ longword)                
链接地址: http://www.djcxy.com/p/20314.html

上一篇: 你如何使用NHibernate进行分页?

下一篇: Python字计数器