前言:
本文侧重于通过实战训练来提高字符串的处理能力,可以先行学习一下我之前的文章:蓝桥杯Python快速入门(4) ,学习完基础知识再来刷题才会事半功倍!
字符串处理
# 字符串切片
str1="12345678abcdefghi"
print(str1) #输出:12345678abcdefghi
print(str1[3]) #输出:4
print(str1[2:5]) #输出:345 截取一部分,左闭右开
print(str1[:5]) #输出:12345
print(str1[2:]) #输出:345678abcdefghi
print (len (str1) ) #输出字符串长度:17
#合并字符串: +和''.join
str2="***"
str12 = str1+str2
print (str12) #输出:12345678abcdefghi***
#也可以这样合并字符串
print(''.join([str1, str2]))#输出:12345678abcdefghi***
#字符串插入:借助list 在str1[4]插入
#str1="12345678abcdefghi"
str_list = list(str1)
str_list.insert(4, "***")
aa= ''.join(str_list)
print(aa) #输出:1234***5678abcdefghi
#重复输出
#str2="***”
print (str2*2) #输出:******
#用\输出特殊符号
print("\\ \" \n") #输出:\ " 换行
# 全局查找子串
str3="abc"
str1="12345678abcdefghi"
print (str3 in str1) #输出:True
print(str3 not in str1) #输出:False
# 局部查找
#str1="12345678abcdefghi"
#str.find(str,beg=0, end=len(string))指定范围查找
print (str1.find("345") ) #输出:2 输出字符串第一个字符索引
print (str1.find("345", 10)) #输出:-1 找不到输出-1
print (str1.find("456", 2,20)) #输出:3
#交换
str2 = "123"
str3 = "abc"
str2, str3 = str3,str2
print(str2) #输出:abc
#比较
print (str2 == str3) #输出:False
print (str2 != str3) #输出:True
例题一:单词分析
2020省赛 lanqiaoOJ504题
题目描述
小蓝正在学习一门神奇的语言,这门语言中的单词都是由小写英文字母组 成,有些单词很长,远远超过正常英文单词的长度。小蓝学了很长时间也记不住一些单词,他准备不再完全记忆这些单词,而是根据单词中哪个字母出现得最多来分辨单词。
现在,请你帮助小蓝,给了一个单词后,帮助他找到出现最多的字母和这 个字母出现的次数。
输入描述
输入一行包含一个单词,单词只由小写英文字母组成。
对于所有的评测用例,输入的单词长度不超过 1000。
输出描述
输出两行,第一行包含一个英文字母,表示单词中出现得最多的字母是哪 个。如果有多个字母出现的次数相等,输出字典序最小的那个。
第二行包含一个整数,表示出现得最多的那个字母在单词中出现的次数。
输入输出样例
示例 1
输入
lanqiao
输出
a 2
示例 2
输入
longlonglongistoolong
输出
o 6
【知识补充】
求一个字符的 ASCII码:ord('字符')
求该ASCII码下的字符:chr(ASCII码)
【代码】
s = input()
n = [0]*256 #对应256个ASCII码,初始化每个字符都是0个
for ch in s: #逐个统计s的每个字符
n[ord(ch)] += 1
k = n.index (max(n)) # 找出数量最多的字符的索引(ASCII码)
print(chr(k)) # 根据ASCII码找到数量最多的字符
print(max (n)) # 该字符的个数
例题二:标题统计
lanqiaoOJ题号325
题目描述
凯凯刚写了一篇美妙的作文,请问这篇作文的标题中有多少个字符?
注意:标题中可能包含大、小写英文字母、数字字符、空格和换行符。统计标题字符数时,空格和换行符不计算在内。
输入描述
输入文件只有一行,一个字符串 s (1≤∣s∣≤5)。
输出描述
输出只有一行,包含一个整数,即作文标题的字符数(不含空格和换行符)。
输入输出样例
示例
输入
Ca 45
输出
4
代码
把空格和换行符替换成空,然后再统计字符数。
替换:s.replace('要替换的字符','替换成的字符')
s = input ()
print (len(s.replace(' ','').replace('\n','')))
例题三:罗马数字
2012, 省赛 langiao0J题号276
题目描述
古罗马帝国开创了辉煌的人类文明,但他们的数字表示法的确有些繁琐,尤其在表示大数的时候,现在看起来简直不能忍受,所以在现代很少使用了。之所以这样,不是因为发明表示法的人的智力的问题,而是因为一个宗教的原因,当时的宗教禁止在数字中出现 0 的概念!
罗马数字的表示主要依赖以下几个基本符号:
I 1 V 5 X 10 L 50 C 100 D 500 M 1000
这里,我们只介绍一下 1000 以内的数字的表示法。
单个符号重复多少次,就表示多少倍。最多重复 3 次。比如:CCC 表示 300,XX 表示 20,但 150 并不用 LLL 表示,这个规则仅适用于 I X C M。
如果相邻级别的大单位在右,小单位在左,表示大单位中扣除小单位。比如:IX 表示 9,IV 表示 4, XL 表示 40 更多的输入描述参见下表,你找到规律了吗?
I,1 II,2 III,3 IV,4 V,5 VI,6 VII,7 VIII,8 IX,9
X,10 XI,11 XII,12 XIII,13 XIV,14 XV,15 XVI,16 XVII,17
XVIII,18 XIX,19 XX,20 XXI,21 XXII,22 XXIX,29 XXX,30
XXXIV,34 XXXV,35 XXXIX,39 XL,40 L,50 LI,51 LV,55 LX,60
LXV,65 LXXX,80 XC,90 XCIII,93 XCV,95 XCVIII,98 XCIX,99
C,100 CC,200 CCC,300 CD,400 D,500 DC,600 DCC,700
DCCC,800 CM,900 CMXCIX,999
本题目的要求是:请编写程序,由用户输入若干个罗马数字串,程序输出对应的十进制表示。
输入描述
第一行是整数 n (n<100) ,表示接下来有 n 个罗马数字。
以后每行一个罗马数字。罗马数字大小不超过 999。
输出描述
要求程序输出 n 行,就是罗马数字对应的十进制数据。
输入输出样例
输入
3 LXXX XCIII DCCII
输出
80 93 702
代码:
这道题主要是找规律。
dict = {'I': 1, 'IV': 4, 'V': 5, 'IX': 9, 'X': 10, 'XL': 40, 'L': 50, 'XC': 90,
'C': 100, 'CD': 400, 'D': 500, 'CM': 900, 'M': 1000}
n = int(input())
for _ in range(n):
ans = 0
flag = 0
s = input()
for i in range(len(s)):
if flag: # 前一位<后一位
flag = 0 # 已经计算过了,跳出当前循环
continue
c = s[i] # 当前罗马数字对应的数字
if i + 1 < len(s): # i不是最后一位
if dict[c] < dict[s[i + 1]]: # 前一位<后一位
flag = 1
c = s[i:i + 2] # 这两位罗马数字对应的数字
ans += dict[c]
print(ans)
例题四:删除字符
题目描述
给定一个单词,请问在单词中删除 t 个字母后,能得到的字典序最小的单词是什么?
输入描述
输入的第一行包含一个单词,由大写英文字母组成。
第二行包含一个正整数 t。
其中,单词长度不超过 100,t 小于单词长度。
输出描述
输出一个单词,表示答案。
输入输出样例
输入
LANQIAO 3
输出
AIAO
思路
这道题要求删除后得到字典序最小的单词,而字典序是从左到右排的,所以应该优先从左边开始删除。
做法:每次删除时,从头到尾遍历字符串,比较相邻的两个字符,如果前面的数较大就删除它。
代码
s = list(input()) + [''] # 注意最后补一个空格,空格的ASCI最小
t = int(input())
for _ in range(t):
for i in range(0, len(s)):
if s[i] > s[i + 1]:
s.remove(s[i]) # 只能转换成列表再删除
break
print(''.join(s)) # 连起来打印s
例题五:数位递增的数
lanqiao0J题号145
题目描述
一个正整数如果任何一个数位不大于右边相邻的数位,则称为一个数位递增的数。
例如 1135 是一个数位递增的数,而 1024 不是一个数位递增的数。
给定正整数 n,请问在整数 1 至 n 中有多少个数位递增的数?
输入描述
输入的第一行包含一个整数 n(1<n<10^6)。
输出描述
输出一行包含一个整数,表示答案。
输入输出样例
输入
30
输出
26
思路
- n比较小,只有10^6,可以暴力(算法复杂度O(n))检查每个数字。
- 如何判断一个数是数位递增的?一种简单的方法是把数变成一个字符串,然后按顺序判断每个字符的大小。
- 顺序:转换为字符串后,用sorted()从小到大排序,如果排序前后一样,则是一个数位递增的数。
代码
n = int (input ())
ans = 0
for i in range(1, n):
s = list(str(i))
if s==sorted(s):#注意不能用sort ()
ans+=1
print(ans)
例题六:单词接龙(难)
lanqiao0J题号769
题目描述
单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合部分合为一部分,例如
beast
和astonish
,如果接成一条龙则变为beastonish
,另外相邻的两部分不能存在包含关系,例如at
和atide
间不能相连。输入描述
输入的第一行为一个单独的整数 n(n≤20)表示单词数。
以下 n 行每行有一个单词,输入的最后一行为一个单个字符,表示“龙”开头的字母。你可以假定以此字母开头的“龙”一定存在。
输出描述
输出以此字母开头的最长的“龙”的长度。
输入输出样例
输入
5 at touch cheat choose tact a
输出
23
思路
- 把所有字符串拼接在一起,输出最长的拼接。
- 用DFS搜索所有可能的拼接,找到其中最长的拼接。
- 代码中的check()函数,判断s和m是否能拼接,当s的后k个和m的前k个字符相同,则能拼接。
代码
def check(x, y) : # 检查两个单词是否可以合并
flag=0
for i in range(1, min(len(x) , len(y))):
if x[-i : len(x)]==y[:i]: # 如果龙的后段等于后一个单词的前段
flag=1 ;break
if flag == 1 :
if x[:len(x)-i] in y[i: ] or y[i:] in x[:len(x)-i]: # 如果有包含关系
return False
else:
return i # 可以拼接,返回可以开始拼接的位置
else:
return False # 不能拼接,返回False
def dfs(dragon,x) :
global ans
ans=max(len(dragon) , ans) # 更新龙的最长长度
for i in range(n):
if check (x, word[i])!=False and vis[i]<2: # 访问次数不能超过两次
r=dragon+word[i][check(x,word[i]):] # 合并
vis[i]+=1 # 保护现场
dfs (r, word[i])
vis[i]-=1 # 恢复现场
n=int (input())
word=[]
for i in range (n) :
word.append(input())
first =input()
ans=0 # 记录长度
for i in range(n) : # vis:访问情况
vis=[0]*n
if word[i][0]==first: # 第i个单词的首字母是龙头
vis[i]+=1
res=word[i] # 当前的龙
dfs(res,word[i]) # 参数K:当前的龙和上一个单词,初始化为两个同一个单词
print (ans)
练习题:
蓝桥杯题库:题库 - 蓝桥云课 (lanqiao.cn)