我参加了不同的编码竞赛,因此不能使用python,因为它执行时间太慢,但是我真的很喜欢input.split(),所以我尝试实现自己的split。 这是我想出的:
#include <iostream>
#include <vector>
#include <stack>
using namespace std;
vector<string> splt(string s){
vector<string> ans={};
for(int i=0;i<s.size();i++){
string str="";
while(s[i]!=' '){
str+=s[i];
i++;
}
ans.push_back(str);
}
return ans;
}
int main(){
string s;
getline(cin, s);
vector<string> ans=splt(s);
for(auto i:ans)
cout<<i<<", ";
}
但是函数返回的向量经常(但不总是)最后有一些垃圾。感谢您提供有关纠正我的代码的帮助,以及将字符串拆分为数组的其他一些帮助。
P.S。对不起,如果我的英语不好,我是俄罗斯人,还没读完书:)
答案 0 :(得分:8)
在此循环中:
while(s[i]!=' '){
str+=s[i];
i++;
}
您永远不会检查i
是否在s
的边界之外,只要那里没有' '
,i
就会超出边界,并且将在边界之外访问该字符串。未定义访问字符串超出范围的行为。
答案 1 :(得分:2)
仅在遇到空格字符时,您的内部循环才会在字符串的结尾处停止。
因此,如果您的输入不以空格结尾,那么您将在字符串之外建立索引并具有不确定的行为。
(而且当它起作用时,连续的空格字符将导致空字符串,这可能是您不想要的。)
在空格上分割的最直接方法是使用流:
#include <sstream>
vector<string> split(string s){
vector<string> ans;
istringstream ss(s);
string word;
while (ss >> word)
ans.push_back(word);
return ans;
}
或
#include <algorithm>
#include <iterator>
#include <sstream>
vector<string> split(string s){
vector<string> ans;
istringstream ss(s);
copy(istream_iterator<string>(ss), istream_iterator<string>(), back_inserter(ans));
return ans;
}
答案 2 :(得分:2)
while(s[i]!=' '){
str+=s[i];
i++;
}
上面的代码部分不检查s的边界。在执行i++
时,您可能会越过字符串的边界。因此,请检查i == s.size()
是否已退出循环。
答案 3 :(得分:0)
您的while循环不会检查字符串的结尾,因此,如果到达字符串的最后一个空格,它将不会在最后一个字符处停止。
while(s[i]!=' ' && i<s.size()){
使用来自其他答案的流来使用解决方案,或者使用字符串类的find方法和substring方法可能更聪明。示例:
vector<string> splt(string s){
vector<string> ans={};
size_t found = s.find_first_of(' ');
size_t last = 0;
while(found!=string::npos){
ans.push_back(s.substr(last,found));
last = found+1;
found = s.find_first_of(' ',found+1);
}
ans.push_back(s.substr(last,s.size()));
return ans;
}