第20节课 【字符串编程练习题】
练习01 回文字符串
输入一个字符串,判断其是否是回文字符串。
# 思路1
# s1 = "黄山落叶松叶落山黄"
# s2 = s1[::-1] # 反转
# print(s2)
# print(s1 == s2)
# 思路2
def is_palindrome(s):
l = 0
r = len(s) - 1
while l < r:
if s[l] != s[r]:
return False
l += 1
r -= 1
return True
s1 = "2黄山落叶松叶落山黄1"
# l r
print(is_palindrome(s1))
练习02 十进制转二进制
题目描述
输入一个十进制正整数,输出其二进制形式
输入输出描述
输入一个十进制正整数
输出二进制字符串
示例
输入:
9
输出:
1001
def to_binary(num):
s = ""
while num != 0:
y = num % 2
s = str(y) + s # 重点
print(y)
num //= 2
return s
num = 123
print(to_binary(num))
练习03 二进制转十进制
题目描述
输入一个二进制字符串,输出其对应的十进制数字
输入输出描述
输入一个二进制字符串
输出十进制数字
示例
输入:
1001
输出:
9
def to_decimal(s):
s = s[::-1]
#"11101101"
num = 0
for i in range(len(s)):
num += int(s[i]) * 2 ** i
return num
s = "10110111"
print(to_decimal(s))
print(int(s, 2))
练习04 十进制转十六进制
题目描述
输入一个十进制正整数,输出其十六进制形式
输入输出描述
输入一个十进制正整数
输出十六进制字符串
示例
输入:
1233321
输出:
1e1b9
def to_hex(num):
s = ""
while num != 0:
y = num % 16
if y < 10:
s = str(y) + s
else: # 10 -> A 11 -> B
s = chr(55 + y) + s
num //= 16
return s.lower()
num = 1928916238751286
print(to_hex(num))
print(hex(num)[2:])
# 十六进制转十进制
def to_decimal(s):
s = s[::-1]
num = 0
for i in range(len(s)):
if s[i].isdigit():
num += int(s[i]) * 16 ** i
else: # a - 10 b - 11
num += (ord(s[i]) - 87) * 16 ** i
return num
s = "6da56cf365636"
print(to_decimal(s))
print(int(s, 16))
练习05 最长公共前缀
题目描述
给定两个字符串 s1 和 s2 ,求两个字符串最长的公共前缀串,字符区分大小写
输入输出描述
输入两行,分别表示s1和s2
输出前缀串
示例
输入:
abcdefg
abcdhko
输出:
abcd
def sovle(s1, s2):
p1 = 0
p2 = 0
while p1 < len(s1) and p2 < len(s2):
if s1[p1] != s2[p2]:
break
p1 += 1
p2 += 1
return s1[:p1]
s1 = "123456"
s2 = "789123"
suffix = sovle(s1, s2)
print(suffix)
练习06 子串出现的次数
题目描述
给定两个字符串 s1 和 s2 ,求 s2 在 s1 中出现的次数,字符区分大小写,已匹配的字符不计入下一次匹配
输入输出描述
输入两行字符串,分别为s1和s2,s2的长度小于等于s1
输出s2在s1中出现的次数
示例1
输入:
ABCsdABsadABCasdhjabcsaABCasd
ABC
输出:
3
示例2
输入:
AAAAAAAA
AAA
输出:
2
# 贪心的思路
# def sovle(s1, s2): # O(n^2)
# count = 0
# for i in range(len(s1) - len(s2) + 1):
# sub = s1[i:i + len(s2)]
# if sub == s2:
# count += 1
# return count
# 非贪心思路 O(n^2)
# def sovle(s1, s2):
# count = 0
# i = 0
# while i < len(s1) - len(s2) + 1:
# sub = s1[i:i + len(s2)]
# if sub == s2:
# count += 1
# i = i + len(s2)
# else:
# i += 1
# return count
def sovle(s1, s2):
count = 0
i = 0
while i < len(s1) - len(s2) + 1:
j = i
k = 0
while k < len(s2):
if s1[j] != s2[k]:
i += 1
break
j += 1
k += 1
else:
count += 1
i = j
# i += 1 # 贪心就这么写就对了
return count
s1 = "AAAAAAAA"
s2 = "AAA"
count = sovle(s1, s2)
print(count)
"""
关于字符串匹配的问题,有专门的算法
KMP
"""
练习07 最长公共子串
题目描述
给定两个字符串 s1 和 s2 ,求 s1 与 s2 之间的最长公共子串,字符区分大小写
输入输出描述
输入两行字符串,分别为s1和s2
输出最长公共子串
示例
输入:
123ABCDEFG83hsad
iughABCDEFG23uy
输出:
ABCDEFG
# 暴力破解 枚举
def solve(s1, s2):
# 默认长度 s1 > s2
for length in range(len(s2), 0, -1):
left = 0
right = length - 1
while right < len(s2):
sub = s2[left:right + 1]
print(sub)
if s1.find(sub) != -1:
return sub
left += 1
right += 1
return ""
s1 = "12345678910"
s2 = "abc"
print(solve(s1, s2))
练习08 猜单词游戏
题目描述
随机产生一个单词,然后提示用户一次猜一个字母,如下示例所示。单词中的每个字母都显示为一个#号,当用户猜测正确时就会显示确切的字母,当用户完成一个单词时,显示失误的次数并询问用户是否继续玩游戏
创建一个数组存储备选单词,然后随机从中抽取进行游戏
示例
Enter a letter in word ####### > p
Enter a letter in word p###### > r
Enter a letter in word pr##r## > p
p is already in the word
Enter a letter in word pr##r## > o
Enter a letter in word pro#r## > g
Enter a letter in word progr## > n
n is not in the word
Enter a letter in word progr## > m
Enter a letter in word progr#m > a
The word is program. You missd 1 time.
Do you want to guess another word? Enter y or n >
import random
# 获取单词的密文字符串
def get_passwd(word, status):
passwd = ""
for i in range(len(word)):
if status[i]:
passwd += word[i]
else:
passwd += "#"
return passwd
# 改变单词状态数组
def change_status(letter, status, word):
for i in range(len(word)):
if word[i] == letter:
# 是否已经改过
if status[i]:
# 已经改过了 后面就不用看了
return False
else:
# 没改过 后面也都没改过
status[i] = True
return True
# 针对word这个单词来进行游戏
def start_game(word):
# 错误的次数
missed = 0
# 单词字母的状态列表
status = [False] * len(word)
# 具体的输入字母进行猜单词
while False in status:
# 获取当前单词的密文
passwd = get_passwd(word, status)
# 提示输入一个字母
letter = input(f"请输入字母 {passwd}>>>")
# 判断字母的存在性
if letter in word:
# 考虑修改状态数组了 True 改了 False没改
if not change_status(letter, status, word):
print(f"{letter}已经存在!")
else:
missed += 1
print(f"{letter}不在单词中!")
print(f"你猜对了,这个单词就是{word},你猜错了{missed}次")
def main():
words = ["banana", "python","apple","computer"]
while True:
# 随机抽取一个单词 [a, b]
index = random.randint(0, len(words) - 1)
word = words[index]
# 开始猜单词的游戏
start_game(word)
# 是否继续
choice = input("是否继续游戏? y/n >>>")
if choice == "n":
break
main()