2016-01-24 22 views
0

我试图创建一个工具,这将使我的生活建立的基于数值除了指示哪些功能应启用配置设置的列表更容易。我正在使用从1到512的两个列表的权力(1,2,4,8,16,32,64,128,256,512)。打印全部子向量组合+问题

手动经历并创建一个列表,它的值将使该功能启用的将是耗时,所以我试图做到这一点编程,然后将输出保存到一个文件过于时间。但是,我遇到了找到合适解决方案的问题。

我从已经拿出了在谷歌的主题,所有这些解决线性组合SO和其他编码论坛阅读几乎每一个问题。这个我能做到,我有我改变了,然后建立我的工具之上此示例代码:

#include <iostream> 
using std::cout; 
using std::cin; 
using std::endl; 

// A is the array that contains the numbers 
// comb is an array of size k that will hold all possible combinations 
// n is the size of input array 
// k is 1 less than the size of combination i.e. we want to find out 4C2 k =1 
// current_k is the variable that makes us simulates k loops in a recursive function 
void combinations(int A[], int comb[], int start, int n, int current_k, int k){ 
    int sum = 0; 

    if (k < 0) 
     return; 

    // Base case just print all the numbers 1 at a time 
    if (k == 0){ 
     for (int i = 0; i < n; i++) 
      cout << A[i] << endl; 
    } 

    // current_k goes from 0 to k-1 and simulates a total of 
    // k iterations 
    if (current_k < k){ 
     // if current_k = 0, and k = 3 (i.e. we need to find combinations of 4) 
     // then we need to leave out 3 numbers from the end because there are 3 
     // more nested loops 
     for (int i = start; i < n - (k - current_k); i++){ 
      // Store the number in the comb array and recursively call with the remaining sub-array 
      comb[current_k] = A[i]; 
      // This will basically pass a sub array starting at index 'start' and going till n-1 
      combinations(A, comb, i+1, n, current_k+1, k); 
     } 
    } 

    else if (current_k == k){ 
     for (int i = start; i < n; i++){ 
      comb[current_k] = A[i]; 

      for (int j = 0; j <= k; j++){ 
       sum += comb[j];  
      } 

      cout << sum << endl; 
      sum = 0; 
     } 
    } 

    else 
     return; 
} 

int main(){ 
    int n; 
    cout << "Enter the 'n' " << endl; 
    cin >> n; 
    int *A = new int[n]; 

    for (int i = 0; i < n; i++) 
     A[i] = i+1; 

    int k; 
    cout << "Enter 'k'" << endl; 
    cin >> k; 
    int *comb = new int[k]; 

    combinations(A, comb, 0, n, 0, k-1); 

    system("pause"); 
    return 0; 
} 

唯一的问题是,我还需要非线性的组合。比如1 + 64 + 256。这也能够拿起这些组合吗?我也有一个问题,我会在发布我的代码后解释。下面是我使用这个的实际代码:

#include <iostream> 
#include <vector> 
#include <string> 
#include "mcl.h" 

using std::cout; 
using std::vector; 
using std::string; 
using std::cin; 
using std::endl; 

static vector<string> results; 

// A is the array that contains the numbers 
// comb is an array of size k that will hold all possible combinations 
// n is the size of input array 
// k is 1 less than the size of combination i.e. we want to find out 4C2 k =1 
// current_k is the variable that makes us simulates k loops in a recursive function 
void combinations(vector<mcl> A, vector<mcl> comb, int start, int n, int current_k, int k){ 
    string sum; 
    string sNames; 
    int sCodes = 0; 

    if (k < 0) 
     k = 0; 

    // Base case just print all the numbers 1 at a time 
    if (k == 0){ 
     for (int i = 0; i < n; i++) 
      cout << A.at(i).getCode() << " - " << A.at(i).getName() << endl; 
     return; 
    } 

    // current_k goes from 0 to k-1 and simulates a total of 
    // k iterations 
    if (current_k < k){ 
     // if current_k = 0, and k = 3 (i.e. we need to find combinations of 4) 
     // then we need to leave out 3 numbers from the end because there are 3 
     // more nested loops 
     for (int i = start; i < n - (k - current_k); i++){ 
      // Store the number in the comb array and recursively call with the remaining sub-array 
      comb.push_back(mcl(A.at(i).getCode(),A.at(i).getName())); 
      // This will basically pass a sub array starting at index 'start' and going till n-1 
      combinations(A, comb, i + 1, n, current_k + 1, k); 
     } 
    } 

    else if (current_k == k){ 
     for (int i = start; i < n; i++){ 
      comb.at(current_k-1) = A.at(i); 

      for (int j = 0; j < k; j++){ 
       sCodes += comb.at(j).getCode(); 
       if (sNames != ""){ 
        sNames = sNames + "," + comb.at(j).getName(); 
       } 

       else{ 
        sNames = sNames + comb.at(j).getName(); 
       } 
      } 
     } 

     results.push_back(sCodes + " - " + sNames); 
     sCodes = 0; 
     sNames = ""; 
    } 

    else 
     return; 
} 

int main(){ 
    int k; 
    vector<mcl> A,comb; 

    A.push_back(mcl(1, "Light")); 
    A.push_back(mcl(2, "Bright")); 
    A.push_back(mcl(4, "Dark")); 

    k = 2; 


    combinations(A, comb, 0, A.size(), 0, k - 1); 

    //system("cls"); 
    for (int i1 = 0; i1 < results.size(); i1++){ 
     cout << results.at(i1) << endl; 
    } 

    system("pause"); 
    return 0; 
} 

MCL头和小鬼代码:

#ifndef MCL_H 
#define MCL_H 

#include <string> 

using std::string; 

class mcl{ 
public: 
    mcl(int code, string name); 

    int getCode(); 
    string getName(); 

    void setCode(int i); 
    void setName(string s); 

private: 
    int cCode; 
    string cName; 
}; 
#endif; 

小鬼:

#include "mcl.h"; 

mcl::mcl(int code, string name){ 
    cCode = code; 
    cName = name; 
} 

int mcl::getCode(){ 
    return cCode; 
} 

string mcl::getName(){ 
    return cName; 
} 

void mcl::setCode(int i){ 
    cCode = i; 
} 

void mcl::setName(string s){ 
    cName = s; 
} 

现在的问题。当我尝试测试我在我看到这个输出的代码定义的三个MCL对象的组合显示:

亮点,暗

,黑暗

按任意键接着说 。 。 。

正如我看到每个单独的对象的数据表示正确如果我组k为0:

1 - 光

2 - 布赖特

4 - 暗

按任意键继续。 。 。

我认为这个问题是由创建显示结果向量的for循环造成的,但我不确定实际问题是什么。

至于我的预期输出的例子,考虑到上面代码中的硬编码元素,这是我想要的工具输出(其中粗体是基本设置和非粗体是组合):

1 - 轻
2 - 布赖特
3 - 光,亮
4 - 暗
5 - 光线暗
6 - 乙黑暗
7 - Light,Bright,Dark

回答

0

因此,经过大量的研究和测试后,我决定这不适合我的情况,并且性价比太高。相反,我选择通过中间表选择数据库内(SQLite)解决方案,该表将ID从一个表映射到另一个表中的ID,以一对多关系形式存在。与通过代码处理全部代码的蛮力方法相比,更容易编写代码并且非常精简,因为上面的示例正在尝试执行。

0

看过你的代码一段时间后;并试图理解你所追求的是你的代码的这一部分已经引起了我的注意组合功能中找到:

else if (current_k == k) { 
     for (int i = start; i < n; i++) { 
      comb.at(current_k-1) = A.at(i); 

      for (int j = 0; j < k; j++){ 
       sCodes += comb.at(j).getCode(); 
       if (sNames != "") { 
        sNames = sNames + "," + comb.at(j).getName(); 

       } else { 
        sNames = sNames + comb.at(j).getName(); 
       } 
      } 
     } 

     results.push_back(sCodes + " - " + sNames); 
     sCodes = 0; 
     sNames = ""; 

    } else { 
     return; 
    } 

什么我想这里是你正在经历一个双重for循环和你做在double for循环完成之前不更新您的向量。这是你想要的吗?或者你的意思是在内循环的每次迭代之后保存?如果是的话,你就只需要你的if else语句之后这个移动到内的环的内侧,其中修改后的代码看起来就象这样:

else if (current_k == k) { 
     for (int i = start; i < n; i++) { 
      comb.at(current_k-1) = A.at(i); 

      for (int j = 0; j < k; j++){ 
       sCodes += comb.at(j).getCode(); 
       if (sNames != "") { 
        sNames = sNames + "," + comb.at(j).getName(); 

       } else { 
        sNames = sNames + comb.at(j).getName(); 
       } 

       results.push_back(sCodes + " - " + sNames); 
      } 
     } 

     sCodes = 0; 
     sNames = ""; 

    } else { 
     return; 
    } 

让我知道这是否可以帮助你以任何方式;不幸的是,我没有足够的时间尝试在我的IDE中重新创建代码,尝试编译,构建,运行和调试以查看修改版本的输出是否正确。我从头顶上视觉上做这件事。如果我在不久的将来有空闲时间,我可能会这样做,并试图看看我能想出什么。

+0

我试过这个,但除了一个额外的元素被添加到结果向量之外,它没有多大变化。我试图做的是得到像这样的输出给定代码中的硬编码元素:1 - 光2 - 光明3 - 光,明亮4 - 黑暗5 - 光,黑6 - 明亮,黑7 - 光,明亮,黑暗 – Geowil

+0

是的,我试着通过你的代码阅读,我有点明白你想要做什么;但是你的算法是一个难以解决的问题。也许在几天之后;我必须将您的代码复制到我的IDE中,并在其中查看调试器中发生的情况,以便我能够为您提供更多的见解。 –