Day 08
字符串
1. 反转字符串(力扣344)
- 题目:反转字符串
- 思路:由于不让用额外的存储,所以只能用指针交换。一个指针指向开头,一个指针指向末尾,交换后一次向中间移动。这道题给的类型是字符数组,下一道题给的是字符串。
- python语法细节
- 对于用列表存储的字符串可以用reverse函数实现反转。
s.reverse()
但是只能反转整个字符串,不能部分反转。想要部分反转使用切片+[::-1]。reverse函数就地反转不返回任何值。
- python使用元组解包的方式可以很方便的交换两个变量的值。
- 切片操作可以实现对字符串的反转
reversed_string = my_string[::-1]
- python实现
class Solution:
def reverseString(self, s: List[str]) -> None:
"""
Do not return anything, modify s in-place instead.
"""
left = 0
l = len(s)
right= l-1
while left <= right:
s[right],s[left]=s[left],s[right]
left +=1
right-=1
- C++语法细节
-
C++实现交换两个变量,可以使用swap函数
-
C++实现字符串反转可以使用reverse函数
reverse(vec.begin(), vec.end());
- C++实现
class Solution {
public:
void reverseString(vector<char>& s) {
int l = s.size();
int left = 0,right = l-1;
while(left<=right){
swap(s[left],s[right]);
left++;
right--;
}
}
};
2. 反转字符串2(力扣541)
1.题目描述:反转字符串2
2. 思路:理解题目意思 ,每经过2k个字符就反转前k个,如果不够k个就都反转了。
而C++中这些都是可变对象,可以对他们重新赋值
- python对传入函数的不可变参数是无法修改的,如果向修改要使用可变对象比如这道题传入的如果是字符串列表,则可以原地修改。
- 下面实现中的方法2看起来是对字符串对象s的原地操作,但其实每一次迭代都会新建一个变量,新开辟一块内存。就执行效率上讲不如方法1.
- python实现
class Solution:
def reverseStr(self, s: str, k: int) -> str:
l = len(s)
i = 0
res = list(s)
while i<l:
if l-i+1 < k:
res[i:l]=s[i:l][::-1]
elif l-i+1>=k :
res[i:i+k]=s[i:i+k][::-1]
i += 2*k
return ''.join(res)
# # 使用切片法进行反转
# l = len(s)
# i = 0
# while i<l:
# j = i+k
# s= s[:i]+s[i:i+k][::-1]+s[i+k:]
# i += 2*k
# return s
- C++语法
- C++中字符串是由字符数组实现的,因此它可以像字符数组一样操作。
- reverse函数的参数不是传入字符数组的值,而是接受两个迭代器参数,表示反转范围的起始位置和结束位置。这个区间是左闭右开的。
- swap是交换变量,reverse是反转。
- C++实现
class Solution {
public:
string reverseStr(string s, int k) {
int l = s.size();
int i = 0;
while (i<l){
int min_ = min(i+k,l);
reverse(s.begin()+i,s.begin()+min_);
i+=2*k;
}
return s;
}
};
3. 替换数字(卡玛网54)
-
题目描述:替换字符
-
思路:这道题输入的是字符串类型,python无法对字符串进行操作,因此需要新建一个字符数组进行操作。而C++可以实现不另外开辟空间,在词字符串上操作。但是为了不向后挪动,从末尾开始填充。
-
python语法细节:
- python如何判断一个字符是数字还是字母:
char.isdigit()
- python实现
s = input()
def change_num(s):
res=[]
for i in s:
if i.isdigit():
res.append('number')
elif i.isalpha():
res.append(i)
print(''.join(res))
change_num(s)
- C++语法:
- C++中的输入输出流:cin,cout,<<,>>用法介绍
- C++中resize用法:resize可以改变容器的大小,第一个参数是改变后的长度,第二个参数是用什么填充,默认是使用初始值进行填充。
- C++ 判断数字类型,字母类型:
isdigit(char);
- C++不能够通过切片的方式对字符数组赋值,可以使用replace函数,其三个参数分别代表:从哪开始,替换几个,用谁替换。
但是python完全可以对切片直接赋值
- C++实现:
#include <iostream>
using namespace std;
int main(){
string s;
while(cin>>s){
int oldl = s.size();
int count_num = 0;
for(char i:s){
if(isdigit(i)){
count_num++;
}
}
int newl = oldl+6*count_num-count_num;
int j = newl-1;
s.resize(newl,'*');
// cout<<s<<endl;
for(int i=oldl-1;i>=0;i--){
// cout<<i<<j<<endl;
if(isalpha(s[i])){
s[j--]=s[i];
}else if(isdigit(s[i])){
s.replace(j - 5, 6, "number");
j=j-6;
}
// cout<<s<<endl;
}
}
cout<<s<<endl;
}
4. 反转字符串中的单词(力扣151)
- 题目描述:反转字符串中的单词
- 思路:python 很好实现,先用空格炸开字符串,再把列表反转顺序即可
C++要麻烦一些,先处理空格问题,再把整体反转,然后再把每个单词反转。 - python语法:
- Python实现:
class Solution:
def reverseWords(self, s: str) -> str:
tmp = s.split()
tmp.reverse()
res = ' '.join(tmp)
return res
- C++语法
- C++实现
class Solution {
public:
string reverseWords(string s) {
//移除不该有的空格:字符串头,字符串尾,字符中间多的
int slow=0,fast=0;
while(fast<s.size()){
if(slow==0 && s[fast]==' '){
fast++;
}
else if(slow!=0 && s[slow-1]==' ' &&s[fast]==' '){
fast++;
}
else{
s[slow++]=s[fast++];
}
}
//移除最后一个空格,如果有的话
if(s[slow-1]==' '){slow--;}
//字符串整体反转
s.resize(slow);
cout<<s<<endl;
//按单词反转
reverse(s.begin(),s.end());
slow = 0;
fast = 0;
while(fast<=s.size()){
if(s[fast]==' ' or fast == s.size()){
reverse(s.begin()+slow,s.begin()+fast);
slow = fast+1;
fast = fast+2;
}
else{
fast++;
}
}
cout<<s<<endl;
return s;
}
};
5. 右旋转字符(卡码网55)
- 题目描述:右旋转字符
- 思路:先整体反转,再把前k个反转,再把剩余的部分反转,即可实现。
- python语法细节:先把字符串变为字符数组,这里整体反转可以使用reverse,后面部分反转切片使用[::-1]
- python实现:
k = int(input())
s = input()
#整体旋转
res = list(s)
res.reverse()
#部分旋转
res[:k] = res[:k][::-1]
res[k:] = res[k:][::-1]
print(''.join(res))
- C++语法细节
要使用 reverse 函数,你需要包含 <algorithm> 头文件
- C++实现
#include<iostream>
#include <algorithm>
using namespace std;
int main(){
int k = 0;
cin>>k;
string s;
cin>>s;
reverse(s.begin(),s.end());
reverse(s.begin(),s.begin()+k);
reverse(s.begin()+k,s.end());
cout<<s<<endl;
}