Python 作业-6 字符串
程序填空题 / 函数题 / 编程题
程序填空题
5-1 判断字符类型
题目:从键盘输入一个字符,判断是数字、英文字母还是其他字符。
ch = input() # 请输入一个字符
if ch.isdigit():
print("输入的是数字")
elif ch.isalpha():
print("输入的是英文字母")
else:
print("输入的是其他字符")
| 行号 | 代码 | 白话解释 |
|---|---|---|
| 1 | ch = input() | 从键盘读取输入,存到变量 ch 里。input() 读进来的永远是字符串。 |
| 2 | if ch.isdigit(): | 调用 isdigit() 方法,判断 ch 是不是纯数字(如 '5')。 |
| 4 | elif ch.isalpha(): | 否则,判断 ch 是不是纯英文字母(如 'a' 或 'Z')。 |
| 6 | else: | 前两关都没过,说明是标点、空格、中文等其他字符。 |
拓展:也可以用 ASCII 范围判断:
if '0' <= ch <= '9':和elif 'a' <= ch <= 'z' or 'A' <= ch <= 'Z':,但isdigit()/isalpha()更简洁。
5-2 字符串处理
题目:给定 s = 'http://sports.sina.com.cn/',用表达式完成 7 项操作。
先给字符串编号(理解切片的命脉):
h t t p : / / s p o r t s . s i n a . c o m . c n /
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| 题号 | 需求 | 答案 | 白话解释 |
|---|---|---|---|
| 1 | 计算 t 出现次数 | s.count('t') | count 就像拿着放大镜数项链上有几颗同样的珠子。 |
| 2 | 计算 "com" 出现的位置 | s.find('com') | 从左往右找,返回第一次出现的起始座位号(结果为 21)。找不到返回 -1。 |
| 3 | . 替换为 - | s.replace('.', '-') | "全部替换",结果是 http://sports-sina-com-cn/。 |
| 4 | 提取 "sports" | s[7:13] | 7~12 号座位是 sports,终点 13 要 +1(包前不包后)。 |
| 4 | 提取 "sina" | s[14:18] | 14~17 号座位是 sina。 |
| 5 | 字母全变大写 | s.upper() | 一键 Caps Lock。 |
| 6 | 输出总字符数 | len(s) | 数一数这条"字符项链"共有多少颗珠子,结果是 26。 |
| 7 | 后拼接 "index" | s + 'index' | 用 + 把两条字符串首尾相接。 |
字符串方法速查口诀:count 数一数,find 找一找,replace 换掉它,upper 变大写,len 求长度,加号粘一起。
5-3 字符串切片
题目:填写切片参数,使程序产生期望输出。
s = '接天莲叶无穷碧,映日荷花别样红。'
给字符串编号(从 0 开始):
接 天 莲 叶 无 穷 碧 , 映 日 荷 花 别 样 红 。
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
参考答案:
s = '接天莲叶无穷碧,映日荷花别样红。'
print(s[3:]) # '叶无穷碧,映日荷花别样红。'
print(s[:8]) # '接天莲叶无穷碧,'
print(s[3::2]) # '叶穷,日花样。'
print(s[::-1]) # '。红样别花荷日映,碧穷无叶莲天接'
print(s[10:3:-2]) # '荷映碧无'
print(s[::3]) # '接叶碧日别。'
print(s[8::2]) # '映荷别红'
| 题号 | 期望输出 | 答案 | 解析 |
|---|---|---|---|
| 1 | 叶无穷碧,映日荷花别样红。 | s[3:] | 从 3 号 "叶" 开始,取到末尾。 |
| 2 | 接天莲叶无穷碧, | s[:8] | 从 0 开始,取到 8 号之前(0~7),刚好包含 ,。 |
| 3 | 叶穷,日花样。 | s[3::2] | 从 "叶"(3号)出发,步长 2,隔一个取一个:3→5→7→9→11→13→15。 |
| 4 | 。红样别花荷日映,碧穷无叶莲天接 | s[::-1] | 步长 -1,字符串反转神技。 |
| 5 | 荷映碧无 | s[10:3:-2] | 从 "荷"(10号)倒着走,步长 -2,到 3 号之前停:10→8→6→4。 |
| 6 | 接叶碧日别。 | s[::3] | 从 0 开始,步长 3,跳两格取一个:0→3→6→9→12→15。 |
| 7 | 映荷别红 | s[8::2] | 从 "映"(8号)开始,步长 2:8→10→12→14。 |
切片万能公式:
s[start:end:step]
start省略 = 从头来;end省略 = 取到尾;step省略 = 1。- 包前不包后:
[2:5]取 2、3、4,不取 5。- 步长为负 = 倒着取,此时终点是不包含的"挡路石"。
函数题
6-1 回文数
题目:判断整数是否是回文数(正着读和倒着读一样,如 8778、12321)。是返回 True,否返回 False。
函数接口: def isHuiwen(n):
裁判程序:
n = int(input())
if isHuiwen(n):
print("yes")
else:
print("no")
参考答案:
def isHuiwen(n):
s = str(n)
return s == s[::-1]
| 行号 | 代码 | 白话解释 |
|---|---|---|
| 1 | def isHuiwen(n): | 定义函数,接收整数 n。 |
| 2 | s = str(n) | 把数字转成字符串,因为数字不能"倒着读",字符串可以。 |
| 3 | return s == s[::-1] | s[::-1] 是字符串反转。如果正序倒序一模一样,== 返回 True,否则 False。 |
图解:
12321正序倒序都是12321→True;1232倒序是2321→False。
6-2 函数求整数各位数字和
题目:实现函数 mysum(x),计算一个整数各位数字之和。
函数接口: def mysum(x):
裁判程序:
n = int(input())
print(mysum(n))
| 输入 | 输出 |
|---|---|
65 | 11 |
参考答案(循环版):
def mysum(x):
s = 0
while x != 0:
s = s + x % 10
x = x // 10
return s
| 行号 | 代码 | 白话解释 |
|---|---|---|
| 1 | def mysum(x): | 定义函数,接收整数 x。 |
| 2 | s = 0 | 准备一个累加器 s,初始为 0。 |
| 3 | while x != 0: | 只要 x 还没变成 0,就继续循环。 |
| 4 | s = s + x % 10 | x % 10 取 x 的最后一位,加到 s 里。 |
| 5 | x = x // 10 | // 10 整除 10,相当于砍掉最后一位。 |
| 6 | return s | 所有位都加完了,返回总和。 |
执行图解(x = 65):
- 第 1 轮:
x % 10 = 5,s = 5,x = 6- 第 2 轮:
x % 10 = 6,s = 11,x = 0- 结束,返回
11
进阶写法(一行代码):
def mysum(x):
return sum(int(d) for d in str(abs(x)))
6-3 字符串中提取数字
题目:读入字符串,提取其中所有数字,输出新字符串。没有数字返回空字符串。
函数接口: def trans(s):
裁判程序:
s = input()
t = trans(s)
print(t)
| 输入 | 输出 |
|---|---|
ab32 434 jiohio3lh3 | 3243433 |
参考答案:
def trans(s):
result = ""
for ch in s:
if ch.isdigit():
result = result + ch
return result
| 行号 | 代码 | 白话解释 |
|---|---|---|
| 1 | def trans(s): | 定义函数,接收字符串 s。 |
| 2 | result = "" | 准备一个空篮子,用来装找到的数字。 |
| 3 | for ch in s: | 逐个检查字符串里的每个字符。 |
| 4 | if ch.isdigit(): | 判断当前字符是不是数字。 |
| 5 | result = result + ch | 如果是数字,就把它粘到篮子末尾。 |
| 6 | return result | 全部检查完,把篮子交还。 |
进阶写法(一行代码):
return "".join(filter(str.isdigit, s))
6-4 特殊 a 串和
题目:给定 a 和 n,求 a + aa + aaa + ... + aa...a(n 个 a)之和。
函数接口: def fn(a, n):
裁判程序:
n, a = list(map(int, input().split()))
s = fn(a, n)
print(s)
| 输入 | 输出 | 验算 |
|---|---|---|
3 2 | 246 | 2 + 22 + 222 = 246 |
参考答案:
def fn(a, n):
total = 0
term = 0
for i in range(n):
term = term * 10 + a
total = total + term
return total
| 行号 | 代码 | 白话解释 |
|---|---|---|
| 1 | def fn(a, n): | 定义函数,a 是要重复的数字,n 是最多重复几次。 |
| 2 | total = 0 | 累加器,存最终总和。 |
| 3 | term = 0 | 当前项,每轮变成 a, aa, aaa... |
| 4 | for i in range(n): | 循环 n 次。 |
| 5 | term = term * 10 + a | 构造秘诀:把上一项左移一位(乘 10),末尾补上 a。如 2→22→222。 |
| 6 | total = total + term | 把刚造出来的项加到总和中。 |
| 7 | return total | 返回总和。 |
执行图解(a=2, n=3):
- 第 1 轮:
term = 0*10+2 = 2,total = 2- 第 2 轮:
term = 2*10+2 = 22,total = 24- 第 3 轮:
term = 22*10+2 = 222,total = 246
编程题
7-1 到底有多二
一个整数"犯二的程度"定义为该数字中包含 2 的个数与其位数的比值。如果这个数是负数,则程度增加 0.5 倍;如果还是个偶数,则再增加 1 倍。
| 输入样例 | 输出样例 |
|---|---|
-13142223336 | 81.82% |
n = input().strip()
# 统计2的个数
count2 = n.count('2')
# 计算有效位数(负数去掉负号)
if n[0] == '-':
length = len(n) - 1
ratio = count2 / length * 1.5
else:
length = len(n)
ratio = count2 / length
# 偶数再翻倍
if int(n[-1]) % 2 == 0:
ratio *= 2
print(f"{ratio * 100:.2f}%")
| 行号 | 代码 | 白话解释 |
|---|---|---|
| 3 | n.count('2') | 数一数字符串里有多少个字符 '2'。 |
| 6-9 | if n[0] == '-': | 负数时,有效位数减 1(去掉负号),比值先乘 1.5。 |
| 12-13 | int(n[-1]) % 2 == 0 | 取最后一位判断奇偶。% 2 == 0 就是偶数,再乘 2。 |
| 15 | f"{ratio * 100:.2f}%" | 换算成百分比,保留两位小数,末尾加 %。 |
7-2 密码验证
密码必须满足:至少 8 个字符、包含至少一个大写字母、包含至少一个数字。符合要求输出"密码设置成功",否则提示重新输入。输入 Q(不区分大小写)强制结束。
while True:
pwd = input()
if pwd.lower() == 'q':
break
if (len(pwd) >= 8 and
any(c.isupper() for c in pwd) and
any(c.isdigit() for c in pwd)):
print("密码设置成功")
else:
print("密码不符合要求,请重新输入")
| 行号 | 代码 | 白话解释 |
|---|---|---|
| 1 | while True: | 无限循环,直到遇到 break。 |
| 3 | pwd.lower() == 'q' | 统一转小写再比较,实现"不区分大小写"。 |
| 5 | len(pwd) >= 8 | 长度检查。 |
| 6 | any(c.isupper() for c in pwd) | any 检查密码里至少有一个大写字母。 |
| 7 | any(c.isdigit() for c in pwd) | 同理,至少有一个数字。 |
7-3 身份证掩码
输入 18 位身份证号,用 8 个 * 替换出生年月部分(第 7-14 位)后输出。不足 18 位输出 error。
| 输入样例 | 输出样例 |
|---|---|
120102198802016598 | 120102********6598 |
12010219880201659 | error |
s = input()
if len(s) != 18:
print("error")
else:
print(s[:6] + "********" + s[14:])
| 行号 | 代码 | 白话解释 |
|---|---|---|
| 1 | s = input() | 读取身份证号。 |
| 2 | len(s) != 18 | 先验长度,不对直接报错。 |
| 4 | s[:6] + "********" + s[14:] | 前 6 位保留,中间 8 位替换成 *,后 4 位保留。 |
7-4 身份证号验证
验证 18 位身份证号格式:前 17 位为数字,最后一位为数字或 X,且长度必须为 18。
| 输入样例 | 输出样例 |
|---|---|
370101199001011234 | Valid |
s = input().strip()
if (len(s) == 18 and
s[:17].isdigit() and
(s[17].isdigit() or s[17].upper() == 'X')):
print("Valid")
else:
print("Invalid")
| 行号 | 代码 | 白话解释 |
|---|---|---|
| 1 | s = input().strip() | strip() 去掉首尾空格,防止误伤。 |
| 2 | len(s) == 18 | 长度检查。 |
| 3 | s[:17].isdigit() | 前 17 位必须全是数字。 |
| 4 | s[17].isdigit() or s[17].upper() == 'X' | 最后一位是数字或者 X(大小写均可)。 |
附录:字符串 & 函数核心口诀
【切片】
切片三参数,起止和步长;
起点 inclusive,终点 exclusive;
步长为正正向走,步长为负倒着取。
【函数提交】
def 起个头,参数放括号;
冒号缩进别忘记,return 把值送回家;
PTA 裁判已写好输入输出,
只需提交 def 块,莫把 print 带进去。