344.反转字符串
贴代码:
void reverseString(vector<char>& s) {
int l = 0, r = s.size() - 1;
while(l < r){
char a = s[l];
s[l] = s[r];
s[r] = a;
l++;
r--;
}
return;
}
没啥好说的,就是个交换。
541. 反转字符串II
先贴代码:
public:
void func(string& s, int st, int end){
while( st < end ){
char a = s[st];
s[st] = s[end];
s[end] = a;
st++,
end--;
}
}
string reverseStr(string s, int k) {
for(int i = 0; i < s.size(); i += 2*k){
if(i + k < s.size()){
func(s, i, i+k-1);
}else func(s, i, s.size()-1);
}
return s;
}
心得体会:
思路比较清晰,但是代码写的一般,尤其是自己定义的func,别忘了对指针进行范围缩减,老是忘。
思路就是一次走2k的距离,如果 I+k 还没到终点,就翻转 i+k 的字符,如果 i + k > 终点,则直接翻转 i 到终点的距离即可。
54. 替换数字
我的代码:
int main(){
string s;
while(cin >> s){
int count = 0;
for(int i = 0; i < s.size(); i++){
if(s[i]-'a' < 0) count++;
//s[i] >= '0' && s[i] <= '9'
}
int old_s = s.size() - 1;
s.resize(s.size() + 5 * count);
int new_s = s.size() - 1;
while(old_s <= new_s && old_s >= 0 && new_s >=0){
if(s[old_s] - 'a' >= 0){
s[new_s] = s[old_s];
old_s--;
new_s--;
}
else{
s[new_s--] = 'r';
s[new_s--] = 'e';
s[new_s--] = 'b';
s[new_s--] = 'm';
s[new_s--] = 'u';
s[new_s--] = 'n';
old_s--;
}
}
cout << s << endl;
}
return 0;
}
做题心得:
有一说一,ACM模式第一次使用实在给我整麻了,虽然弄明白了也就还好。输入是自己输入的,所以得自己先声明输入,再 cin。
resize 那里,弄错了需要扩充的大小,写成了 6 *,应该是 5 *,因为要包括数字原先占据的位置,所以得去掉一个。
还有就是如果想让字符直接与数字进行比较,得给数字转成字符,需要加上 ‘0’,单引号。
或者像我这样就直接做运算。
151.翻转字符串里的单词
先贴代码:
void func(string& s, int st, int end){
while(st < end){
char a = s[st];
s[st] = s[end];
s[end] = a;
st++;
end--;
}
}
void DeleteKG(string& s){
int slow = 0;
for(int i = 0; i < s.size(); i++){
if(s[i] != ' '){
if(slow != 0) s[slow++] = ' ';//不能写在 while 下面
while( i < s.size() && s[i] != ' ') s[slow++] = s[i++];
}
}
s.resize(slow);//这一步是去除后面的空格
}
string reverseWords(string s) {
DeleteKG(s);
func(s, 0, s.size()-1);
int k = 0;
for(int i = 0; i < s.size(); i++){
if( i == s.size() - 1) func(s, k, i);
if(s[i] == ' '){
func(s, k, i-1);
k = i + 1;
}
}
return s;
心得体会
在代码中有一点我不太明白,就是最开始if(slow != 0) s[slow++] = ' ' 我写在了 while 的下面,但是这样就报错了,只有在上面就不会报错。我调试了一下如下所示:
#include<iostream>
#include<string>
using namespace std;
void DeleteKG(string& s){
int slow = 0;
for(int i = 0; i < s.size(); i++){
if(s[i] != ' '){
if(slow != 0) s[slow++] = ' ';//不能写在 while 下面
while( i < s.size() && s[i] != ' ') s[slow++] = s[i++];
}
}
s.resize(slow);//这一步是去除后面的空格
}
int main(){
string s = {" sky is blue"};
cout << "old_s: " << s <<' '<< "old_s_len: " <<s.size() <<endl << endl;
DeleteKG(s);
cout <<"new_s: " << s << ' '<< "old_s_len: " <<s.size()<< endl << endl;
cin.get();
return 0;
}
当我如上演示, sky 前面空了俩个空格,正常的话去除所有空格,new_s 肯定会比原先少 2 个字符,则如上所示,先是正确答案,会显示:
没有问题。
但是当我把 if 放在下面会显示:
则会少一个。问题出来了,如果将 if 语句放在下面,则在处理完最后一个单词的时候,还会执行一次空格添加,则此次空格添加就会导致 slow 大小出现问题,会多前进一步。(虽然是个很简单的问题,但是空想确实没想出来。还是直接调试来的直观)
卡码网:55.右旋转字符串
先贴代码:
#include<iostream>
#include<string>
using namespace std;
void func(string& s, int st, int end){
while( st < end){
char a = s[st];
s[st] = s[end];
s[end] = a;
st++;
end--;
}
}
int main(){
int num ;
string s;
while(cin >> num >> s){
func(s, 0, s.size() - 1);
func(s, 0, num - 1);
func(s, num, s.size() - 1);
cout << s << endl;
}
return 0;
}
心得体会:
思路比较自然,定义个翻转的函数,然后先整体翻转,再分段翻转。