CS入门学习笔记10-作业题(含generator生成器, yield, input与raw_input区别等初步学习)

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]大小做判断的方式,但始终无法正确截取出按照字母顺序排序的片段。经过网上搜索之后,发现自己思路最大的问题所在:

  1. 我在搜索字符串的过程中只用了一个“指针”(此处指针为我自己对搜索过程中标识位置变量的简称),而事实上应该用2个变量充当指针,来分别标注头尾;
  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个网上的答案:

  1. 最简洁版本
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个字母的情况)
  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相比更省内存,但在调用时也会有所不同,常用的两种调用方法:

  1. next()
    https://www.runoob.com/python/python-func-next.html
  2. 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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值