我遇到了一个有趣的练习。基本上,我必须从字符串中删除所有多余的空格,而多余的是指字符串开头,字符串结尾处的所有空格,并且连续的空格不应超过两个。
这是我尝试过的
#include <iostream>
#include <string>
using namespace std;
string RemoveSpaces(string s) {
auto it = s.begin();
while(*it == ' ') { // removes spaces at the beginning
if(*it == ' ') s.erase(it);
}
auto it2 = s.end(); // removes spaces at the end of a string
it2--;
while(*it2 == ' ') it2--;
it2++;
while(*it2 == ' ') {
if(*it2 == ' ') s.erase(it2);
}
for(int i = 0; i < s.length() - 1; i++) { // this does NOT work
if(s.at(i) == ' ' && s.at(i + 1) == ' ') {
auto it3 = s.at(i);
s.erase(it3);
}
}
return s;
}
int main() {
string s;
getline(cin, s);
string s1 = RemoveSpaces(s);
cout << "|" << s << "|" << endl;
cout << "|" << s1 << "|" << endl;
return 0;
}
但是,这并没有达到我的预期。我的代码成功删除了字符串开头和结尾的空格,但是我不能再进一步了。有人可以帮忙吗?
EDIT 我已解决此问题。这是代码的一部分,现在该部分删除了单词之间的多余空格,因此只在两个单词之间留了一个空格。
auto it3= s.begin();
for(int i = 0; i < s.length() - 1; i++) {
if(s.at(i) == ' ' && s.at(i + 1) == ' ') {
s.erase(s.begin()+i);
i--;
}
}
谢谢大家的帮助。
答案 0 :(得分:3)
您可以利用std::stringstream
的功能:
#include <string>
#include <sstream>
std::string RemoveSpaces(const std::string& str) {
std::string out; // the result
std::string word; // used to extract words from str
std::istringstream ss(str); // create an istringstream from str
while(ss >> word) { // extract a word
if(!out.empty()) out += ' '; // add a space between words
out += word; // add the extracted word
}
return out;
}
答案 1 :(得分:0)
#include <iostream>
std::string remove_excessive_spaces(const std::string& str)
{
std::string ret;
for(std::size_t i = str.find_first_not_of(' '); i < str.size(); i++)
{
if(str[i] != ' ' || ret[ret.size() - 1] != ' ')
{
ret.push_back(str[i]);
}
}
return ret;
}
int main()
{
std::string sentence(" some weird sentence xd ");
std::cout<<sentence<<"\n";
std::cout<<remove_excessive_spaces(sentence)<<"\n";
return 0;
}
答案 2 :(得分:0)
当我的模拟从命令行或文本文件读取输入时,我经常使用这一小段代码,以确保数据干净。它通过自定义copy_if()使用STL的predicate。它将所有内部空格减少到一个空格,并删除所有前导和尾随空格。
/* Removes inner whitespace from str_in */
string remove_excess_spaces(string str_in){
//predicate class to use with copy_if
//determines if a character should be copied based on if there is
//a space following a non-space character
class copy_space{
public:
copy_space() : was_last_space(true) {};
bool operator()(char c) {
if(!isspace(c)){
was_last_space = false;
return true;
}
else{
if(was_last_space) return false;
was_last_space = true;
return true;
}
}
private:
bool was_last_space;
} pred;
//copy into single-spaced string
string str;
str.resize(str_in.size());
auto it = std::copy_if(str_in.begin(), str_in.end(), str.begin(), pred);
//remove trailing empty spots
str = str.substr(0, it - str.begin());
//convert all remaining whitespace to ' '. Accounts for tabs, miscelaneous newlines, etc.
std::replace_if(str.begin(), str.end(), isspace, ' ');
//remove any trailing whitespace
if(isspace(str[str.size() - 1]))
str.erase(str.size() - 1, 1);
return str;
}
尝试一个可行的示例here!
答案 3 :(得分:0)
标准库已经具有搜索范围为search_n的连续元素的功能。使用此功能,您可以找到两个以上空格开始的位置。然后您可以清除此ws并继续,找到更多连续的空格:
public function users()
{
return $this->hasMany('App\Users', 'iduser');
}
删除前导和尾随空白称为修整。您可以使用std :: find_if从头开始,从头开始一次:
inline auto remove_triple_spaces(std::string str)
{
for(auto r = std::search_n(str.begin(), str.end(), 3, ' '); r != str.end(); r = std::search_n(r, str.end(), 3, ' '))
{
r = str.erase(r); // returns new iterator pointing to the 2nd ws. the first got erased
}
return str;
}
您现在可以合并两个功能:
inline auto trim_ws(std::string s)
{
// erase all trailing ws (start from the end for performance)
auto one_past_last_non_ws = std::find_if(s.rbegin(), s.rend(), [](char c){ return c != ' '; }).base();
s.erase(one_past_last_non_ws, s.end());
//erase all leading ws
auto first_non_ws = std::find_if(s.begin(), s.end(), [](char c){ return c != ' '; });
s.erase(s.begin(), first_non_ws);
return s;
}
答案 4 :(得分:0)
那么多行代码。 。
这里是使用嵌套std::regex
的C ++标准解决方案。这样,我们得到了单线。
请参阅:
#include <iostream>
#include <string>
#include <regex>
int main()
{
// Test string
std::string s(" abc de fg hi jk lm ");
// First remove leading and trailing spaces, then remove too many spaces in between
s = std::regex_replace(std::regex_replace(s, std::regex("^ +| +$|(\S+)"), "$1"), std::regex(" {3,}"), " ");
// Show result
std::cout << s << '\n' << std::string(s.size(), '^') << '\n';
return 0;
}
这实际上并不复杂:内部正则表达式替换
OR
带有原始的休息文本。在此新文本中,我们进入第二个正则表达式,在这里我们将3个或更多空格替换为2个空格。
应该可以理解。而且超短。