我想知道是否有更短/更简单的方法:
有两个限制:没有库,没有循环
#include <string>
#include <iterator>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <deque>
void list_string_elements(std::string s) {
using namespace std;
istringstream iss (s);
deque<string> v;
copy(istream_iterator<string>(iss), istream_iterator<string>(), front_inserter(v));
copy(v.begin(),v.end(),ostream_iterator<string>(cout,"\n"));
}
答案 0 :(得分:7)
轻微的缩写,我们可以通过deque
的迭代器构造函数来删除副本:
void list_string_elements(std::string s) {
using namespace std;
istringstream iss (s);
deque<string> v(istream_iterator<string>(iss), (istream_iterator<string>()));
copy(v.rbegin(),v.rend(),ostream_iterator<string>(cout,"\n"));
}
请注意istream_iterator<string>()
周围的额外问题,以避免最令人烦恼的解析。
答案 1 :(得分:5)
没有,因为您需要存储单词,直到获取最后一个单词。尝试向后标记化会更复杂。
此外,您无法使用std::copy_backward
,因为std::istream_iterator
不是双向的(仅限输入)。
std::deque
非常适合这项任务。您也可以使用vector
+ back_inserter
,并从v.rbegin()
复制到v.rend()
到ostream_iterator
。
此外,标记字符串的逻辑最简单的用istringstream
表示。
基本上,这似乎无法做得更好。
唯一的宗教小事是我无法忍受using namespace
,即使是在街区范围内。
我的建议,行数相同:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>
#include <vector>
void output_tokens(const std::string& str)
{
typedef std::istream_iterator<std::string> in_iterator;
typedef std::ostream_iterator<std::string> out_iterator;
std::istringstream in(str);
std::vector<std::string> buffer(in_iterator(in), (in_iterator()));
std::copy(buffer.rbegin(), buffer.rend(), out_iterator(std::cout, "\n"));
}
重要编辑:您需要在in_iterator()
周围添加一对额外的括号,以避免将整个语句解析为函数声明。 @Steve Jessop的答案也有同样的问题。请参阅this erroneous sample,了解因此类混淆导致的令人毛骨悚然的错误消息。
答案 2 :(得分:2)
老师鼓励使用正确的C ++功能是件好事,但为了好玩,我会争辩说使用copy
只是将循环向下移动到堆栈......我会认为递归是真实的这样做的方式不使用显式循环,如下所示...
#include <iostream>
#include <string>
typedef std::string::const_iterator iterator;
void print_reverse(iterator s, iterator i, iterator e)
{
// last word
if (i == e)
{
if (s != i)
std::cout << std::string(s, i) << std::endl;
return;
}
std::string word;
if (*i == ' ')
{
// have word here
word.assign(s, i);
s = ++i;
}
else
++i;
// recursively call
print_reverse(s, i, e);
if (!word.empty())
std::cout << word << std::endl;
}
int main(void)
{
std::string foo ("foo bar bof bob");
print_reverse(foo.begin(), foo.begin(), foo.end());
}