题目大概
这道题目异常的阴间,可以说是阴间到一定地步了。
涉及的方面也很多,可以说是一道好的题目。
去除多余的空格
简单方法
创建一个新的string 然后遍历string
void removeextraspace(string s){
string ans;
for(int i = 0 ; i<s.size();i++){
if(i>0&&s[i]==' '&&s[i-1]==' ')continue;
ans.push_back(s[i]);
}
cout<<ans;
}
快慢指针法
没错痛苦的双指针又来了。
我们不适用额外空间的话 其实双指针也可以解决。但是这题涉及到一些技巧。
还有一件就是,可能想到了用快慢指针。但是苦于开头空格或者末尾的特殊情况,想着如何将他们全部放在一个for循环解决。其实有时候不需要这么讲究,我们可以特殊情况,特殊处理。
遇到特殊情况,我们也特殊处理。不能因为特殊的开头结尾,影响了我们对于主题的做法。
如果放在一个for循环里面处理所有情况,第一步就会受苦
我们判断字符串中多余的空格是根据前一个字符判断的。如果不是开头并且前一个也是空格
那么需要剔除。但是开头这种情况就不符合。我们需要再for里面加上新的判断情况 来判断这是开头还是中间还是结尾。所以我们有时候考虑问题 先从主体下手。然后看能不能从外部剔除特殊情况的部分从而简化问题
我们特殊处理开头
//移动快指针到开头的第一个单词
while(s[fast]==' '){
fast++;
}
后面我们需要剔除末尾多余的空格
//末尾检测
int last = s.size()-1;
while(s[last]==' '){
last--;
}
s.resize(last+1);
注意是last+1 可不是last
这是主题代码
int slow = 0,fast = 0;
for(;fast<s.size();fast++){
if(fast>0&&s[fast]==' '&&s[fast-1]==' '){
continue;
}
s[slow++] = s[fast];
}
最后我们需要resize string
s.resize(slow);
其实这里我当时呆掉了
我觉得是slow-1 因为slow应该是处于有效字符串的后一位,但是分配的内存大小就是slow
因为例如slow是25 我们应该分配25的空间 因为下表是0-24
反转单词
反转单词有一个非常重要的技巧
负负得正
我们反转字符串,然后针对单词进行局部反转。于是负负得正,单词便就正常了。
reverse(s.begin(),s.end());
slow = 0;fast = 0;
for(;fast<s.size();fast++){
if(s[fast]==' '){
reverse(s.begin()+slow,s.begin()+fast);
slow = fast+1;
}
}