Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
按类型组合列表算法 我试图在C++中创建一个算法,它将给我一组列表项的所有可能组合(以一种MAP格式输入)。我希望避免重复,并确保涵盖所有可能的组合。为了简化示例,以下是输入的外观: map<string, vector<string> > sandwichMap; sandwichMap["bread"].push_back("wheat"); sandwichMap["bread"].push_back("white"); sandwichMap["meat"].push_back("ham"); sandwichMap["meat"].push_back("turkey"); sandwichMap["meat"].push_back("roastbeef"); sandwichMap["veggie"].push_back("lettuce"); sandwichMap["sauce"].push_back("mustard");_C++_Algorithm - Fatal编程技术网

按类型组合列表算法 我试图在C++中创建一个算法,它将给我一组列表项的所有可能组合(以一种MAP格式输入)。我希望避免重复,并确保涵盖所有可能的组合。为了简化示例,以下是输入的外观: map<string, vector<string> > sandwichMap; sandwichMap["bread"].push_back("wheat"); sandwichMap["bread"].push_back("white"); sandwichMap["meat"].push_back("ham"); sandwichMap["meat"].push_back("turkey"); sandwichMap["meat"].push_back("roastbeef"); sandwichMap["veggie"].push_back("lettuce"); sandwichMap["sauce"].push_back("mustard");

按类型组合列表算法 我试图在C++中创建一个算法,它将给我一组列表项的所有可能组合(以一种MAP格式输入)。我希望避免重复,并确保涵盖所有可能的组合。为了简化示例,以下是输入的外观: map<string, vector<string> > sandwichMap; sandwichMap["bread"].push_back("wheat"); sandwichMap["bread"].push_back("white"); sandwichMap["meat"].push_back("ham"); sandwichMap["meat"].push_back("turkey"); sandwichMap["meat"].push_back("roastbeef"); sandwichMap["veggie"].push_back("lettuce"); sandwichMap["sauce"].push_back("mustard");,c++,algorithm,C++,Algorithm,它需要用于任何字符串向量的映射。到目前为止,我已经尝试并接近了,但我最终发现了重复的组合和遗漏的组合: sandwichList getCombinations(sandwichMap sMap) { locList retList; int totalCombos = 1; for (sandwichMapIt i = sMap.begin(); i != sMap.end(); ++i) { totalCombos *= i->seco

它需要用于任何字符串向量的映射。到目前为止,我已经尝试并接近了,但我最终发现了重复的组合和遗漏的组合:

sandwichList getCombinations(sandwichMap sMap)
{
    locList retList;
    int totalCombos = 1;

    for (sandwichMapIt i = sMap.begin(); i != sMap.end(); ++i)
    {
        totalCombos *= i->second.size();
    }

    retList.resize(totalCombos);
    int locCount;

    for (sandwichMapIt a = sMap.begin(); a != sMap.end(); ++a)
    {
        locCount = 0;
        for (locListIt l = a->second.begin(); l != a->second.end(); ++l)
        {
            for (unsigned int i = 0; i < totalCombos / a->second.size(); ++i)
            {
                retList[i + a->second.size() * locCount] += *l;
            }

            locCount++;
        }
    }

    return retList;
}
sandwichList getcompositions(sandwichMap sMap)
{
locList retList;
int totalCombos=1;
for(sandwichMapIt i=sMap.begin();i!=sMap.end();++i)
{
totalCombos*=i->second.size();
}
调整大小(totalCombos);
int locCount;
对于(sandwichMapIt a=sMap.begin();a!=sMap.end();++a)
{
locCount=0;
对于(locListIt l=a->second.begin();l!=a->second.end();++l)
{
对于(无符号整数i=0;isecond.size();++i)
{
retList[i+a->second.size()*locCount]+=*l;
}
locCount++;
}
}
返回列表;
}
任何帮助都将不胜感激

更新代码:

#include <vector>
#include <map>
#include <list>
#include <iostream>

typedef std::vector<std::string> strVec;
typedef std::list<std::string> strList;
typedef std::map<std::string, strVec> sandwichMap;

int main()
{
    sandwichMap sMap;

    sMap["bread"].push_back("wheat");
    sMap["bread"].push_back("white");
    sMap["meat"].push_back("ham");
    sMap["meat"].push_back("turkey");
    sMap["meat"].push_back("roastbeef");
    sMap["veggie"].push_back("lettuce");
    sMap["sauce"].push_back("mustard");

    strList finalSandwichList;
    for (sandwichMap::iterator i = sMap.begin(); i != sMap.end(); ++i)
    {
        strList tmpSandwich;
        for (strVec::iterator j = i->second.begin(); j != i->second.end(); ++j)
        {
            if (finalSandwichList.empty())
            {
                tmpSandwich.push_back(*j);
            }
            else
            {
                for (strList::iterator k = finalSandwichList.begin(); k != finalSandwichList.end(); ++k)
                    tmpSandwich.push_back(*k + "+" + *j);
            }
        }
        tmpSandwich.swap(finalSandwichList);
    }

    for (strList::iterator i = finalSandwichList.begin(); i != finalSandwichList.end(); ++i)
    {
        std::cout << *i << std::endl;
    }

    return 0;
}
#包括
#包括
#包括
#包括
typedef std::向量strVec;
typedef std::list strList;
typedef标准::地图三明治地图;
int main()
{
三明治地图;
sMap[“面包”]。向后推(“小麦”);
sMap[“面包”]。推回(“白色”);
sMap[“肉”]。后推(“火腿”);
sMap[“肉”]。推回(“火鸡”);
sMap[“肉”]。推回(“烤牛肉”);
sMap[“素食者”]。向后推(“生菜”);
sMap[“酱”]。向后推(“芥末”);
斯特利斯特最终三明治名单;
for(三明治映射::迭代器i=sMap.begin();i!=sMap.end();++i)
{
斯特利斯特-特姆桑德维奇;
对于(strVec::迭代器j=i->second.begin();j!=i->second.end();++j)
{
if(finalSandwichList.empty())
{
tmpSandwich.向后推_(*j);
}
其他的
{
for(strList::iterator k=finalSandwichList.begin();k!=finalSandwichList.end();++k)
tmpSandwich.push_back(*k++“++”++*j);
}
}
tmpSandwich.swap(最终三明治列表);
}
for(strList::iterator i=finalSandwichList.begin();i!=finalSandwichList.end();++i)
{
std::cout这应该有效:

#include<iostream>
#include<map>
#include<string>
#include<algorithm>

using namespace std;

map<string, vector<string>> sMap;
vector<string> add;
int sett[200], countt;

void solve(map<string, vector<string>>::iterator itt, int ct, vector<string> addd){
    vector<string> tmp = itt->second;
    if(ct == countt){
        for(int j=0;j<addd.size();j++){
            cout<<addd[j]<<" ";
        }
        cout<<endl;
        return;
    }
    itt++;
    for(int i=0;i<tmp.size();i++){
        //cout<<tmp[i]<<" ";
        addd.push_back(tmp[i]);
        solve(itt, ct+1, addd);
        vector<string>::iterator tempIt = addd.end();
        addd.erase(tempIt--);
    }
}

int main(){
    sMap["bre"].push_back("wh");
    sMap["bre"].push_back("whi");
    sMap["me"].push_back("ham");
    sMap["me"].push_back("tur");
    sMap["me"].push_back("rr");
    sMap["veg"].push_back("let");
    sMap["sau"].push_back("mus");
    countt = sMap.size();
    solve(sMap.begin(), 0, add);
return 0;
}
#包括
#包括
#包括

#include

由于helper方法的原因,代码有点长,但它可以完成以下任务:

#include <vector>
#include <string>
#include <map>
#include <iostream>
using namespace std;

template <class T>
vector<T> Head(const vector<T> &v) {
    return vector<T>(v.begin(), v.begin() + 1);
}

template <class T>
vector<T> Tail(const vector<T> &v) {
    auto first = v.begin() + 1;
    auto last = v.end();
    return vector<T>(first, last);
}

template <class T>
vector<T> Concat(const vector<T> &v1, const vector<T> &v2) {
    vector<T> result = v1;
    result.insert(result.end(), v2.begin(), v2.end());
    return result;
}


vector<vector<string>> CombineVectorWithScalar(const vector<vector<string>> &v, const string &scalar) {
    vector<vector<string>> result = v;
    for (unsigned i = 0; i < v.size(); i++) {
        result[i].push_back(scalar);
    }
    return result;
}

vector<vector<string>> CombineVectorWithVector(const vector<vector<string>> &v1, const vector<string> &v2) {
    if (v2.empty()) {
        return vector<vector<string>>();
    }
    else {
        auto headCombination = CombineVectorWithScalar(v1, v2.front());
        auto tailCombination = CombineVectorWithVector(v1, Tail(v2));
        return Concat(headCombination, tailCombination);
    }
}

vector<string> GetKeys(const map<string, vector<string>> &mp) {
    vector<string> keys;

    for (auto it = mp.begin(); it != mp.end(); ++it) {
        keys.push_back(it->first);
    }

    return keys;
}

vector<vector<string>> CombineMapValues(const map<string, vector<string>> &mp) {
    vector<string> keys = GetKeys(mp);

    vector<vector<string>> result;
    auto &firstVector = mp.begin()->second;
    for (auto it = firstVector.begin(); it != firstVector.end(); ++it) {
        vector<string> oneElementList;
        oneElementList.push_back(*it);
        result.push_back(oneElementList);
    }

    vector<string> restOfTheKeys = Tail(keys);
    for (auto it = restOfTheKeys.begin(); it != restOfTheKeys.end(); ++it) {
        auto &currentVector = mp.find(*it)->second;
        result = CombineVectorWithVector(result, currentVector);
    }

    return result;
}

void PrintCombinations(const vector<vector<string>> & allCombinations) {
    for (auto it = allCombinations.begin(); it != allCombinations.end(); ++it) {
        auto currentCombination = *it;
        for (auto itInner = currentCombination.begin(); itInner != currentCombination.end(); ++itInner) {
            cout << *itInner << " ";
        }
        cout << endl;
    }
}

int main() {
    map<string, vector<string> > sandwichMap;

    sandwichMap["bread"].push_back("wheat");
    sandwichMap["bread"].push_back("white");
    sandwichMap["meat"].push_back("ham");
    sandwichMap["meat"].push_back("turkey");
    sandwichMap["meat"].push_back("roastbeef");
    sandwichMap["veggie"].push_back("lettuce");
    sandwichMap["sauce"].push_back("mustard");

    auto allCombinations = CombineMapValues(sandwichMap);
    PrintCombinations(allCombinations);

    return 0;
}
#包括
#包括
#包括
#包括
使用名称空间std;
模板
向量头(常量向量和v){
返回向量(v.begin(),v.begin()+1);
}
模板
矢量尾(常数矢量和v){
自动优先=v.开始()+1;
自动结束=v.结束();
返回向量(第一个、最后一个);
}
模板
向量Concat(常数向量&v1,常数向量&v2){
向量结果=v1;
result.insert(result.end(),v2.begin(),v2.end());
返回结果;
}
向量组合向量和标量(常量向量和v、常量字符串和标量){
向量结果=v;
for(无符号i=0;i第一);
}
返回键;
}
向量组合mapvalues(const map&mp){
向量键=获取键(mp);
矢量结果;
auto&firstVector=mp.begin()->second;
for(auto it=firstVector.begin();it!=firstVector.end();+it){
向量元素表;
一个元素列表。向后推(*它);
结果。推回(一个元素列表);
}
向量键=尾部(键);
for(auto it=restof keys.begin();it!=restof keys.end();++it){
auto¤tVector=mp.find(*it)->秒;
结果=组合因子与向量(结果,当前向量);
}
返回结果;
}
无效打印组合(常量向量和所有组合){
for(auto it=allCombinations.begin();it!=allCombinations.end();+it){
自动电流组合=*it;
对于(自动itInner=currentCombination.begin();itInner!=currentCombination.end();++itInner){
cout
void generate\u all(std::map::iterator start,
向量累积器,
标准:地图和sMap){
for(auto-it=start;it!=sMap.end();+it){
对于(auto-jt=it->second.begin();jt!=it->second.end();jt++){
生成所有(启动+1,accomulator.pus_back[jt],sMap);
}
}
if(acomulator.size()==sMap.size()){
//打印累积器
}
}
使用
generate_all(sMap.begin(),aVector,sMap)调用;

如果映射太大而无法递归执行,则始终可以生成等效的迭代代码。

//解决方案
   //solution
  std::list<std::string> result;
  for(auto i=sandwichMap.begin(); i!=sandwichMap.end(); ++i) {
    std::list<std::string> new_result;
    for(auto j=i->second.begin(); j!=i->second.end(); ++j) {
      if(result.empty())
        new_result.push_back(*j);
      else
       for(auto k=result.begin(); k!=result.end(); ++k)
         new_result.push_back(*k + "+" + *j);
    }
    new_result.swap(result);
  }
std::列表结果; for(自动i=sandwichMap.begin();i!=sandwichMap.end();++i){ 标准::列出新的结果; 用于(自动j=i->second.begin();j!=i->second.end();++j){ if(result.empty()) 新结果。向后推(*j); 其他的 for(auto k=result.begin();k!=result.end();++k) 新结果。向后推(*k++“++”++*j); } 新结果交换(结果); }
此解决方案不是递归的。它的基本功能如下:

  • 计算实际可能的组合数
  • 要知道,对于地图中的每个键,您必须总共添加它们的组合
  • 您可以将其视为一棵正在生长的树,访问的密钥越多,分支就越多
  • 如果你记录有多少个,它们之间的间隔是多少
    void generate_all(std::map<std::string,std::vector<std::string>>::iterator start,
     std::vector<std::string::iterator> accomulator,
     std::map<std::string,std::vector<std::string>>& sMap){
        for (auto it=start; it!=sMap.end(); ++it){
            for (auto jt=it->second.begin(); jt!=it->second.end(); jt++){
                generate_all(start+1,accomulator.pus_back[jt],sMap);
            }
        }
        if (accomulator.size() == sMap.size()){
            // print accomulator
        }
    }
    
       //solution
      std::list<std::string> result;
      for(auto i=sandwichMap.begin(); i!=sandwichMap.end(); ++i) {
        std::list<std::string> new_result;
        for(auto j=i->second.begin(); j!=i->second.end(); ++j) {
          if(result.empty())
            new_result.push_back(*j);
          else
           for(auto k=result.begin(); k!=result.end(); ++k)
             new_result.push_back(*k + "+" + *j);
        }
        new_result.swap(result);
      }
    
    #include <vector>
    #include <iostream>
    #include <map>
    #include <string>
    
    int main() {
        std::map<std::string, std::vector<std::string> > sandwichMap;
    
        sandwichMap["bread"].push_back("wheat");
        sandwichMap["bread"].push_back("white");
        sandwichMap["meat"].push_back("ham");
        sandwichMap["meat"].push_back("turkey");
        sandwichMap["meat"].push_back("roastbeef");
        sandwichMap["veggie"].push_back("lettuce");
        sandwichMap["sauce"].push_back("mustard");
        sandwichMap["sauce"].push_back("mayo");
    
        // Compute just how many combinations there are
        int combinationNr = 1;
        for ( auto it : sandwichMap ) {
            combinationNr *= it.second.size();
        }
        std::vector<std::vector<std::string>> solutions(combinationNr);
        // We start with empty lists, thus we only have one cluster
        int clusters = 1, clusterSize = combinationNr;
        for ( auto category : sandwichMap ) {
            int startIndex      = 0;
            int itemsNr         = category.second.size();
            int itemsPerCluster = clusterSize / itemsNr;
            for ( auto item : category.second ) {
                for ( int c = 0; c < clusters; ++c ) {
                    for ( int i = 0; i < itemsPerCluster; ++i ) {
                        // We sequentially fill each cluster with this item.
                        // Each fill starts offset by the quantity of items
                        // already added in the cluster.
                        solutions[startIndex+i+c*clusterSize].push_back(item);
                    }
                }
                startIndex += itemsPerCluster;
            }
            clusters *= itemsNr;
            clusterSize = combinationNr / clusters;
        }
    
        for ( auto list : solutions ) {
            for ( auto element : list ) {
                std::cout << element << ", ";
            }
            std::cout << "\n";
        }
        return 0;
    }