1. Finding longest substring in alphabetical order
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”
本题我自己未做出来,一直想用比较s[i-1]和s[i]大小做判断的方式,但始终无法正确截取出按照字母顺序排序的片段。经过网上搜索之后,发现自己思路最大的问题所在:
- 我在搜索字符串的过程中只用了一个“指针”(此处指针为我自己对搜索过程中标识位置变量的简称),而事实上应该用2个变量充当指针,来分别标注头尾;
- 在用for循环挨个判断string中字母顺序时,我总是在用s[i]这种由位置找字母的形式,但实际上直接用for n in s 直接取出字母更加简洁方便。
先将自己的半成品语句放上来,以供日后反思:
def alphastr(s):
'''
此函数意图为取出所有按照字母顺序排序的字符小串
input: s is a string
output: a list of subset strings which the letters occur in alphabetical order
'''
ans = ''
anslist = []
if len(s) <= 1:
ans = s[:]
anslist.append(ans)
else:
ans += s[0]
for i in range(1,len(s)-1):
if s[i-1] <= s[i]:
if s[i] > s[i+1]:
ans += s[i]
anslist.append(ans)
else :
ans += s[i]
else:
alphastr(s[i:])
return anslist
接下来贴上2个网上的答案:
- 最简洁版本
def find_longest_substring_in_alphabetical_order(s):
groups = []
cur_longest = ''
prev_char = ''
for c in s.lower():
if prev_char and c < prev_char: #用prev_char的空判断,包括了c为首字母或末尾字母的情况。
groups.append(cur_longest) #将先前已整理好的字符串存入group中
cur_longest = c # 清空元字符串,继续寻找后续符合条件的字符串
else:
cur_longest += c
prev_char = c #在本字母判断完毕之后,再将标识已结束字母的指针放过来,一点一点推动。
return max(groups, key=len) if groups else s
#用一个语句解决了我本想写一个函数解决的问题:选择出字符串中最长的那一个
#若groups为空,则直接返回s(s只有1个字母的情况)
- 使用了generator
def alphabetical_substrings(word):
current_sequence = [] # 用一个list代替了上面一段代码中的groups和cur_longest
last_letter = '' # 相当于上一段代码里的prev_char
for letter in word:
if letter >= last_letter:
current_sequence.append(letter)
else:
yield ''.join(current_sequence)
'''
. join():连接字符串数组。
将字符串、元组、列表中的元素以指定的字符(分隔符)连接生成一个新的字符串,如:
>> a=['1','2','3','4','5']
>> ' '.join(a)
1 2 3 4 5
>>'-'.jion(a)
1-2-3-4-5
>>'.'.join(a)
1.2.3.4.5
'''
current_sequence = [] #将符合要求的字符串直接用yield输出,再清空此列表
last_letter = letter
if current_sequence: # 需要单独判断当符合要求的字符串一直延续到末尾的情况
yield ''.join(current_sequence)
# 由于alphabetical_substrings()是一个generator,所以直接call无法返回值,
# 需要使用另一个函数对其调用后方能显示结果
def longest_substring_in_alphabetical_order(word):
return max(alphabetical_substrings(word), key=len)
if __name__ == '__main__':
'''
一个python的文件有两种使用的方法:
第一是直接作为脚本执行,第二是import到其他的python脚本中被调用(模块重用)执行。
因此if __name__ == 'main': 的作用就是控制这两种情况执行代码的过程,
在if __name__ == 'main': 下的代码只有在第一种情况下(即文件作为脚本直接执行)才会被执行,
而import到其他脚本中是不会被执行的。
'''
print(longest_substring_in_alphabetical_order('azcbobobegghakl'))
关于yield的解释
https://blog.csdn.net/mieleizhi0522/article/details/82142856
先把yield看做return,之后再把它看做是生成器(generator)的一部分(带yield的函数才是真正的迭代器)。
程序会在yield时返回后面的值,然后将此函数或程序停止在此刻,执行后面的内容,待下次再调用本程序时,会从yield后面(即先前停止的位置)继续往下执行此程序。
关于generator的解释
https://www.jb51.net/article/63929.htm
generator保存算法但不保存值,所以与list相比更省内存,但在调用时也会有所不同,常用的两种调用方法:
- next()
https://www.runoob.com/python/python-func-next.html - for循环:
for n in g:
… print n
2. Problem Set 4 - a
# -*- coding: utf-8 -*-
# 6.00x Problem Set 4A Template
#
# The 6.00 Word Game
# Created by: Kevin Luu <luuk> and Jenna Wiens <jwiens>
# Modified by: Sarina Canelake <sarina>
#
import random
import string
VOWELS = 'aeiou'
CONSONANTS = 'bcdfghjklmnpqrstvwxyz'
HAND_SIZE = 7
SCRABBLE_LET