Write a function partlist that gives all the ways to divide a list (an array) of at least two elements into two non-empty parts.
Each two non empty parts will be in a pair (or an array for languages without tuples or a structin C - C: see Examples test Cases - )
Each part will be in a string
Elements of a pair must be in the same order as in the original array.
Examples of returns in different languages:
a = ["az", "toto", "picaro", "zone", "kiwi"]
--> [["az", "toto picaro zone kiwi"], ["az toto", "picaro zone kiwi"], ["az toto picaro", "zone kiwi"], ["az toto picaro zone", "kiwi"]]
分析
最好是在对string列表进行一遍扫描后完成的pair的构造.
观察下表能发现以下规律:
第K个字符串出现在第K ~ 最后一个 pair的first中.
并且也出现在第0个~ K-1个pair的second中.
pair.first | pair.second |
---|---|
“az” | “toto picaro zone kiwi” |
“az toto” | “picaro zone kiwi” |
“az toto picaro” | “zone kiwi” |
“az toto picaro zone” | “kiwi” |
class PartList
{
public:
static std::vector<std::pair <std::string, std::string>> partlist(std::vector<std::string> &arr){
std::vector<std::pair<std::string, std::string>> res(arr.size()-1);
for(size_t i =0 ;i< arr.size() ; ++i){
// 组装 每个pair的首个元素
for(size_t j = i ;j< res.size() ; ++j){
std::string& current = res[j].first ;
if(current != "") current.append(" ");
current.append(arr[i]);
}
// 组装 pair的第二个元素
for(size_t k = 0 ; k< i ;++k){
std::string& current = res[k].second ;
if(current != "") current.append(" ");
current.append(arr[i]);
}
}
return res;
}
};
更好的解法
其实有更加直观的思路. 那就是每个pair的first和second分别是有字符串的前N个/后N个字符串拼接合成的一个长字符串
但由于对C++算法库不熟, 没想到能完成"多个合成为一个"这样的函数,
std::accumulate
就能完成这样的任务. 其参数为:
( 开始位置, 结束位置, 初始值, 将每两个元素合成为一个的方法 )
#include <numeric>
using namespace std;
class PartList
{
public:
static std::vector<std::pair <std::string, std::string>> partlist(std::vector<std::string> &arr)
{
vector<pair<string, string>> result;
auto combine = [](string a, string b) { return a + ' ' + b; };
for (int i = 1; i < arr.size(); i++)
{
result.emplace_back(
accumulate(arr.begin() + 1, arr.begin() + i, arr[0], combine),
accumulate(arr.begin() + i + 1, arr.end(), arr[i], combine));
}
return result;
}
};