另一个简单而好的解决方案是使用
ranges v3。当前版本是C++14或更高版本,但也有旧版本是C++11或更高版本。不幸的是,C++20的ranges没有
intersperse
函数。
这种方法的好处包括:
- 优雅
- 轻松处理空字符串
- 处理列表的最后一个元素
- 高效。因为ranges是惰性评估的。
- 小巧实用的库
函数分解(
Reference):
-
accumulate
= 类似于
std::accumulate
,但参数是一个范围和初始值。还有一个可选的第三个参数,即操作函数。
-
filter
= 类似于
std::filter
,过滤不符合谓词的元素。
-
intersperse
= 关键函数!在范围输入元素之间插入分隔符。
#include <iostream>
#include <string>
#include <vector>
#include <range/v3/numeric/accumulate.hpp>
#include <range/v3/view/filter.hpp>
#include <range/v3/view/intersperse.hpp>
int main()
{
using namespace ranges;
std::vector<std::string> a{ "Hello", "", "World", "is", "", "a", "program" };
std::string delimiter{", "};
std::string finalString =
accumulate(a | views::filter([](std::string s){return !s.empty();})
| views::intersperse(delimiter)
, std::string());
std::cout << finalString << std::endl;
}
编辑:正如
@Franklin Yu所建议的那样,只使用std库与
std::ranges::views::join_with是可能的。但不幸的是,它仅适用于c++23。由于我们正在使用c++23,我们还可以使用
std::ranges::fold_left代替
std::accumulate
来创建一行表达式。
std::ranges::fold_left
是rages v3的
rages::accumulate
的std版本。
#include <iostream>
#include <string>
#include <vector>
#include <ranges>
#include <algorithm>
int main()
{
std::vector<std::string> a{ "Hello", "", "World", "is", "", "a", "program" };
std::string delimiter{", "};
std::string finalString =
std::ranges::fold_left(a | std::views::filter([](std::string s){return !s.empty();})
| std::views::join_with(delimiter)
, std::string()
, std::plus());
std::cout << finalString << std::endl;
}