算法刷题总结 (五) 字符串操作

news/2025/2/12 16:08:22/

算法总结5 字符串方法

  • 一、理解Python中的字符串
    • 1.1、字符串的特性
    • 1.2、字符串的操作
      • 1.2.1、字符串的截取与加长
      • 1.2.2、字符串的数字与字母的操作
      • 1.2.3、字符串的字母分割添加
      • 1.2.4、字符串的对齐填充
      • 1.2.5、字符串的左右剔除
      • 1.2.6、ASCII值最大/最小的字符
      • 1.2.7、整数与字符的转化
      • 1.2.8、字符串的替换
      • 1.2.9、字符串中字符的寻找(报错和不报错)
      • 1.2.10、字符串按指定字符/字符串切分
      • 1.2.11、统计字符/字符串出现次数
      • 1.2.12、字符串起始/结尾首字符的检查
  • 二、经典题型
    • 2.1、344. 反转字符串
    • 2.2、541. 反转字符串 II
    • 2.3、剑指 Offer 05. 替换空格
    • 2.4、151.翻转字符串里的单词
    • 2.5、剑指Offer58-II.左旋转字符串
    • 2.6、28. 实现 strStr()
    • 2.7、459. 重复的子字符串
  • 三、参考

在这里插入图片描述

一、理解Python中的字符串

字符串是 Python 中最常用的数据类型使用频率非常高,并且它非常灵活有非常多的操作,且拥有非常强大的内置库函数。

字符串经常作为考题出现,或者为其他主题考题的某一部分,所以熟练的掌握字符串的相关操作对自己编程解决问题的能力的提升至关重要。


1.1、字符串的特性

(1)、字符串是字符的有序可重复集合
字符串中的字符是有序的,所以可以像list和tuple一样通过索引查找相应位置的元素;它的元素也可以重复,所以它不像set不仅无序,而且元素不可重复。

(2)、字符串不可修改,或者“修改”会开辟新的内存空间。
字符串为不可变类型(字符串、数字和元组为不可变类型;列表、字典和集合为可变类型),所以不可以直接在字符串上进行修改操作,否则会报错。

所以我们只能生成新的字符串变量来保存结果,这算是变相“修改”字符串。但这样做是生成新的变量,去开辟一块新的内存空间而产生新的内存地址,不是对原变量进行操作,而有些题目会要求进行原址操作,那么在新的变量上的任何操作都对原变量没任何影响,结果会出现问题。

但字符串不会进行任何更改,所以原址操作修改是不可能的,这里不用考虑,但是对于list需要其修改是否为原址。


1.2、字符串的操作

1.2.1、字符串的截取与加长

截取:string [ start : end : step ]

字符串索引从左往右从0,1开始,step为1;从右往左从-1,-2开始,step要设置为-1.

类似于range的使用。

注意[:]生成相同值的string,当赋予新的变量时,内存地址还是相同的。

加长:
1.拼接:string1 + string2
直接将两个字符串加起来,结果为新的地址。

无减法操作。

2.重复:string1 * n
将sting1重复n次,n必须为整数,为小数则报错,为0和负数则为’'空字符串。

结果同样为新的地址。

3.百分比输出: ’ …%s’%string

m='abc'
'123%s'%m

4.format输出:‘{}’.format()

m = 'you'
'123{love}'.format(love=m)

1.2.2、字符串的数字与字母的操作

1.判断整个字符串是否为数字:
string.isnumeric() / isdigit(),返回值为True或者False

'12a'.isnumeric()False

区别: 前者支持所有形式的数字,后者不支持类似汉字数字

'一'.isnumeric()True'一'.isdigit()False

2.字母大小写互换:
string.swapcase()

'a123B'.swapcase()'A12b'

3.字符串全转大/小写
string.upper() / string.lower(),将字符串中的每个字符转换成大写 / 转换成小写

'abC'.upper()'ABC''abC'.lower()'abc'

4.是否全是大写或小写
string.isupper()/islower()

5.是否全是字母和数字
string.isalnum()

6.是否全是空白字符
S.isspace()

7.是否是首字母大写的
S.istitle()

8.首字母大写
S.capitalize()


1.2.3、字符串的字母分割添加

splitSym.join(string)

将splitSym添加到string的每个字母之间

'|'.join('abcde')a|b|c|d|e

1.2.4、字符串的对齐填充

1. 中间对齐,两边对称填充:
string.center(width, fillchar),fillchar默认为空格必须为str类型,width为填充后整个字符串的长度。

当不对称时,比如string为两个字符,width为奇数5,则左边的填充比右侧的多1.

'ab'.center(5, '0')00ab0

2.左边对齐,右侧填充:
string.ljust(width[ ,fillchar])

'ab'.ljust(5)'ab   '

3.右边对齐,左侧填充:
rjust(width[ ,fillchar])

'ab'.rjust(5)'   ab'

1.2.5、字符串的左右剔除

1. 两边剔除:
string.strip(ch) ,截掉字符串两边的字符/字符串,可指定。当ch为空时,默认剔除空格字符(包括’\n’, ‘\r’, ‘\t’, ’ ')

'a b c d  '.strip('a')' b c d '

2. 左侧剔除:
string.lstrip(ch)

' a b c d  '.lstrip()'a b c d '

3. 右侧剔除:
string.rstrip(ch)

' a b c d  '.rstrip('d ')' a b c '

1.2.6、ASCII值最大/最小的字符

max(string)/min(string)


1.2.7、整数与字符的转化

chr(num)/ord(char) 将一个整数转化成一个字符 / 将一个字符转化成一个整数
整数同样为ASCII数值

A-Z 65-90
a-z 97-122


1.2.8、字符串的替换

string.replace( oldStr, newStr [,times] ),将string字符串中的原有字符/字符串串old替换成new字符/字符串,从而形成新的string字符串序列,默认new替换所有old,除非指定times替换次数。

'aaa'.replace('a', 'b', 2)'bba'

1.2.9、字符串中字符的寻找(报错和不报错)

不报错的寻找 (提倡使用):
1.左侧开始寻找:
s.find(str,beg=0,length=len) ,返回第一个找到的结果。beg指定从左开始的起始点,可为负数,默认为0;length指定寻找的长度,默认为整个长度,注意从0开始而不是从beg开始。

找不到指定的str时,返回-1

'111222111'.find('1', 3)6

2.右侧开始寻找:
s.rfind(str,beg=0,length=len),注意这里的beg也是从左侧开始,而不是右侧。

'111222111'.rfind('1', -3,7)6

3.找不到返回-1

'1'.find('2')-1

报错的寻找 (不提倡使用):
s.index(str,beg=0,length=len) / rindex(str,beg=0,length=len)
同上,但找不到则报错。

'1'.index('2')ValueError: substring not found

1.2.10、字符串按指定字符/字符串切分

string.split(splitChar [,times] ),以splitChar(字符或者字符串)为分隔符,将string拆分成不同组字符串,各个字符串整体形成一个列表。

'112211221'.split('1', 3)['', '', '22', '1221']

1.2.11、统计字符/字符串出现次数

str.count(sub, start= 0,end=len(string)),统计出现次数,可指定起始位置,默认为0,;可指定结尾位置,默认为整个字符串长度。

'112211'.count('11')2

1.2.12、字符串起始/结尾首字符的检查

1. 以某字符开头:
str.startswith(str, beg=0,end=len(string)),用于检查字符串是否是以指定子字符串开头,如果是则返回 True,否则返回 False。如果参数 beg 和 end 指定值,则在指定范围内检查。

'12345'.startswith('2',1)True

2. 以某字符结尾:
str.endswith(suffix[, start[, end]])



在这里插入图片描述

二、经典题型

2.1、344. 反转字符串

leetcode链接

1.库函数(不推荐):
如果题目关键的部分直接用库函数就可以解决,建议不要使用库函数。

如果库函数仅仅是 解题过程中的一小部分,并且你已经很清楚这个库函数的内部实现原理的话,可以考虑使用库函数。

class Solution:def reverseString(self, s: List[str]) -> None:"""Do not return anything, modify s in-place instead."""s.reverse()

2.创建新变量反向替换

class Solution:def reverseString(self, s: List[str]) -> None:"""Do not return anything, modify s in-place instead."""# 创建一个反向新变量for n, i in enumerate(s[::-1]):s[n]=i

3.双指针原址交换
首尾向中间交换遍历

class Solution:def reverseString(self, s: List[str]) -> None:"""Do not return anything, modify s in-place instead."""for i in range(len(s)//2):s[i], s[len(s)-i-1] = s[len(s)-i-1],s[i]

请添加图片描述
另一种双指针标准写法

class Solution:def reverseString(self, s: List[str]) -> None:"""Do not return anything, modify s in-place instead."""left, right = 0, len(s) - 1# 该方法已经不需要判断奇偶数,经测试后时间空间复杂度比用 for i in range(right//2)更低# 推荐该写法,更加通俗易懂while left < right:s[left], s[right] = s[right], s[left]left += 1right -= 1

2.2、541. 反转字符串 II

leetcode链接

过程模拟题,找到规律,设定起始点,每次2*k跳跃

class Solution:def reverseStr(self, s: str, k: int) -> str:#s = list(s)#if len(s)<k:#    s.reverse()#    return ''.join(s)#elif len(s)<2*k:#    s = list(reversed(s[:k]))+s[k:]#    return ''.join(s)#else:# 前面这些部分可以去掉,被包含在了下面# 对于[start:end]超过len(s)会被会略而不会报错start = 0while start<len(s):end = start+ks = s[:start]+s[start:end][::-1]+s[end:]start+= 2*kreturn s# return ''.join(s)    

2.3、剑指 Offer 05. 替换空格

leetcode链接

1.使用函数(不推荐):

class Solution:def replaceSpace(self, s: str) -> str:s = s.replace(' ', '%20')return s

2.遍历过程:
从后往前遍历,不然长度变化,未处理过的空格的索引的位置会改变。
比如:

"     "
会输出
"%20%20   "
而不是
"%20%20%20%20%20"
因为第一次len(s)的长度为3,从前往后替换时,替换第一个,遍历到%20
class Solution:def replaceSpace(self, s: str) -> str:for i in range(len(s)-1,-1,-1):if s[i]==' ':s = s[:i] + '%20'+ s[i+1:]return s

2.4、151.翻转字符串里的单词

leetcode链接

1.使用函数:

class Solution:def reverseWords(self, s: str) -> str:tmp = s.split(' ')tmp.reverse()while ''in tmp:tmp.remove('')return ' '.join(tmp)

2.双指针:

class Solution:def reverseWords(self, s: str) -> str:left, right = 0, 0res = []while right < len(s):if s[left] == ' ':left+=1elif right==len(s)-1 or s[right+1] == ' ':# s = s[:left]+s[left:right+1][::-1]+s[right+1:]res.insert(0, s[left:right+1])left = right+1right+=1# print((left,right))return ' '.join(res)

2.5、剑指Offer58-II.左旋转字符串

leetcode链接

1.拆分拼接:

class Solution:def reverseLeftWords(self, s: str, n: int) -> str:return s[n:]+s[:n]

2.6、28. 实现 strStr()

leetcode链接

1.使用函数:

class Solution:def strStr(self, haystack: str, needle: str) -> int:return haystack.find(needle)

2. KMP算法
这里可以使用更为具体的KMP算法,理解比较复杂,后续再学习补充。


2.7、459. 重复的子字符串

leetcode链接

class Solution:def repeatedSubstringPattern(self, s: str) -> bool:for i in range(len(s)):# 重复则至少两个以上if s[:i+1] + s[:i+1] in s:# 该子串的n次能拼成s,成功if s[:i+1]*(len(s)//len(s[:i+1])) == s:return Truereturn False


三、参考

KMP算法(百度百科)
字符串(blog)


http://www.ppmy.cn/news/34354.html

相关文章

MyBatisPlus+SpringBoot实现乐观锁功能

一、商城数据不一致的场景 如果商城中有一件商品&#xff0c;成本价是80元&#xff0c;售价是100元。经理先是通知小李&#xff0c;说你去把商品价格增加50元。小李正在玩游戏&#xff0c;耽搁了一个小时。正好一个小时后&#xff0c;经理觉得商品价格增加到150元&#xff0c;…

分布式事务详解

&#x1f3c6;今日学习目标&#xff1a; &#x1f340;分布式事务详解 ✅创作者&#xff1a;林在闪闪发光 ⏰预计时间&#xff1a;30分钟 &#x1f389;个人主页&#xff1a;林在闪闪发光的个人主页 &#x1f341;林在闪闪发光的个人社区&#xff0c;欢迎你的加入: 林在闪闪发光…

CSRF漏洞的概念、利用方式、防御方案

CSRF漏洞1.CSRF的概念1.1 什么是CSRF&#xff1f;1.2 基本攻击流程2.CSRF攻击实现2.1 靶场练习2.2 CSRFXSS组合拳2.2.1 攻击页面部署2.2.2 构造恶意xss语句&#xff0c;实现重复生效的CSRF3. CSRF攻击的防御**3.1 只使用JSON API****3.2 验证HTTP Referer字段****3.3 在请求地址…

国产化大趋势下学习linux的必要性

由于国际上的一些国家的制裁和威胁。最近几年国产化大趋势慢慢的兴起&#xff0c;我们国产化硬件的需求越来越大。对国产操作系统的需求也越来越多&#xff0c;那么我们一直用的Windows系统为什么不用了呢&#xff1f;众所周知的原因&#xff0c;不管是最新的Windows11还是正值…

go错误处理(2)——panic函数使用及捕获

前言 前面我们讲过了error类型来处理一般的错误&#xff0c;本文会描述使用panic函数和recover函数来处理比较极端的错误。简单来说&#xff0c;当程序运行时遇到无法处理的错误或异常情况时&#xff0c;会调用panic函数引发一个运行时错误&#xff0c;此时程序会终止执行并抛…

‘/’ 和 ‘%’ 在编程中的作用【附加练习题】

‘/’和‘%’在编程中有非常重要的作用&#xff0c;使用它们可以说是在使用一种简单算法&#xff0c;不仅易于理解&#xff0c;而且会极大的减少你的代码量&#xff0c;让你的程序看起来高级一点点&#x1f92a;&#xff01;/ 除我们通常都是除10的倍数&#xff0c;比如‘10’只…

真要被00后职场整顿了?老员工纷纷表示真的干不过.......

最近聊到软件测试的行业内卷&#xff0c;越来越多的转行和大学生进入测试行业。想要获得更好的待遇和机会&#xff0c;不断提升自己的技能栈成了测试老人迫在眉睫的问题。 不论是面试哪个级别的测试工程师&#xff0c;面试官都会问一句“会编程吗&#xff1f;有没有自动化测试…

Postgres schema search_path

/**在 TEST_DM库中新建 schema&#xff1a;test_dm 并授权*/CREATE schema test_dm authorization uown_test_dm;CREATE SCHEMA (模式名&#xff09;AUTHORIZATION&#xff08;用户名&#xff09;中的用户名指的是将拥有该模式的用户名&#xff0e;如果省略&#xff0c;缺省为执…