这是一个愚蠢的问题,但出于好奇,可能会在逗号上拆分一个字符串,对字符串执行一个函数,然后在一个C ++语句中用逗号重新加入它?
这是我到目前为止所做的:
string dostuff(const string& a) {
return string("Foo");
}
int main() {
string s("a,b,c,d,e,f");
vector<string> foobar(100);
transform(boost::make_token_iterator<string>(s.begin(), s.end(), boost::char_separator<char>(",")),
boost::make_token_iterator<string>(s.end(), s.end(), boost::char_separator<char>(",")),
foobar.begin(),
boost::bind(&dostuff, _1));
string result = boost::algorithm::join(foobar, ",");
}
因此,这会导致"a,b,c,d,e,f"
转变为"Foo,Foo,Foo,Foo,Foo,Foo"
我意识到这是OTT,但我只想扩展我的助力魔法。
答案 0 :(得分:1)
首先,请注意你的程序写“Foo,Foo,Foo,Foo,Foo,Foo ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,对于你的结果字符串 - 正如评论中已经提到的那样,你想在那里使用back_inserter。
至于答案,每当有一个范围产生的单个值时,我会看std::accumulate
(因为 是折叠/缩减的C ++版本)
#include <string>
#include <iostream>
#include <numeric>
#include <boost/tokenizer.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/bind.hpp>
std::string dostuff(const std::string& a) {
return std::string("Foo");
}
int main() {
std::string s("a,b,c,d,e,f");
std::string result =
accumulate(
++boost::make_token_iterator<std::string>(s.begin(), s.end(), boost::char_separator<char>(",")),
boost::make_token_iterator<std::string>(s.end(), s.end(), boost::char_separator<char>(",")),
dostuff(*boost::make_token_iterator<std::string>(s.begin(), s.end(), boost::char_separator<char>(","))),
boost::bind(std::plus<std::string>(), _1,
bind(std::plus<std::string>(), ",",
bind(dostuff, _2)))); // or lambda, for slightly better readability
std::cout << result << '\n';
}
现在除了顶部的方式并重复make_token_iterator两次。我猜boost.range胜出。
答案 1 :(得分:1)
void dostuff(string& a) {
a = "Foo";
}
int main()
{
string s("a,b,c,d,e,f");
vector<string> tmp;
s = boost::join(
(
boost::for_each(
boost::split(tmp, s, boost::is_any_of(",")),
dostuff
),
tmp
),
","
);
return 0;
}
不幸的是,我无法两次删除提及tmp
。也许我稍后会想到什么。
答案 2 :(得分:1)
我实际上正在开发一个库,允许以比单独的迭代器更可读的方式编写代码...不知道我是否会完成项目,但似乎死的项目往往会积累在我的计算机上...
无论如何,我在这里的主要责任显然是使用迭代器。我倾向于将迭代器视为低级实现细节,在编码时你很少想要使用它们。
所以,我们假设我们有一个合适的库:
struct DoStuff { std::string operator()(std::string const&); };
int main(int argc, char* argv[])
{
std::string const reference = "a,b,c,d,e,f";
std::string const result = boost::join(
view::transform(
view::split(reference, ","),
DoStuff()
),
","
);
}
视图的想法是围绕另一个容器的光包装:
我已经让transform
部分工作,我想知道split
如何工作(一般),但我想我会进入它;)
答案 3 :(得分:0)
好的,我想这是可能的,但请不要在生产代码中真正做到这一点。
更好的是像
std::string MakeCommaEdFoo(std::string input)
{
std::size_t commas = std::count_if(input.begin(), input.end(),
std::bind2nd(std::equal_to<char>(), ','));
std::string output("foo");
output.reserve((commas+1)*4-1);
for(std::size_t idx = 1; idx < commas; ++idx)
output.append(",foo");
return output;
}
它不仅会表现得更好,下一个人阅读和理解也会容易得多。