【问题标题】:combination of n distinct numbersn 个不同数字的组合
【发布时间】:2013-09-17 04:18:35
【问题描述】:

我有一组格式为 a b 的 n 案例,我要做的是我必须从 a、b 中形成不同的数字组合。例如,

假设 n=4 并且 a,b 跟随

1 2
3 1
2 4
3 2

现在看 a,b 总共有 4 个不同的数字,它们是 (1,2,3,4)

并且可以形成所有不同数字的两个组合,它们是(1,3,4,2)和(2,1,4,3),如下:-

 1 2
 | 
 3 1
  \
 2 4
   |
 3 2

 1 2
   | 
 3 1
   |
 2 4
  /
 3 2

我的问题是我无法思考如何编码,因为 n

【问题讨论】:

  • 如果n > max(a) || n > max(b),则无法像您所说明的那样找到从上到下的路径。在你到达那里之前,你会用完不同的数字。只是想指出这一点,正如帖子所述:as n<=50 and a,b<=16.

标签: algorithm math combinations permutation distinct-values


【解决方案1】:

要形成一个不同数字的列表,只需使用“唯一集”并继续将所有数字插入其中。在 C++ 中,std::set 按定义只存储唯一的数字。

要查找不同序列组合的数量,您必须保留一个“候选列表”列表,如果它们已经没有这些数字,则继续在其中插入数字,否则删除该特定候选列表。

C++ 完整代码:

#include <iostream>
#include <vector>
#include <set>
using namespace std;

int main() {

    int n = 4;
    set<int> uniqueNumbers; // ordered set of unique numbers
    vector< set<int> > possibleLists( 1 );
    set<int>::iterator it;

    for ( int i = 0; i < n; i++ ) {

        int num1;
        int num2;
        cin >> num1 >> num2;

        // numbers will be inserted if not already present in set (by definition)
        uniqueNumbers.insert( num1 );
        uniqueNumbers.insert( num2 );

        // make a copy for a possible new branch
        vector< set<int> > possibleListsCopy( possibleLists );

        //int size1 = possibleLists.size();

        for ( int j = 0; j < possibleLists.size(); j++ ) {

            it = possibleLists[j].find( num1 );
            if ( it == possibleLists[j].end() ) {
                possibleLists[j].insert( num1 ); // insert if not found
                //cout << "inserted1 "<<endl;
            }
            else {
                // erase this possible combination
                possibleLists[j].clear();
                possibleLists.erase( possibleLists.begin() + j );
                j--;
            }

        }

        //int size2 = possibleListsCopy.size();

        for ( int j = 0; j < possibleListsCopy.size(); j++ ) {
;

            it = possibleListsCopy[j].find( num2 );
            if ( it == possibleListsCopy[j].end() ) {
                possibleListsCopy[j].insert( num2 ); // insert if not found
            }
            else {
                // erase this possible combination
                possibleListsCopy[j].clear();
                possibleListsCopy.erase( possibleListsCopy.begin() + j );
                j--;
            }

        }

        // concatenate both set of lists.
        possibleLists.insert( possibleLists.end(),
                                possibleListsCopy.begin(),
                                possibleListsCopy.end() );


    }


    cout << " The unique list: ";
    //output the unique list.
    for ( it = uniqueNumbers.begin(); it != uniqueNumbers.end(); it++ )
        cout << *it << " ";

    /*cout << endl << endl;

    cout << "Possible Lists:" << endl;

    for ( int i = 0; i < possibleLists.size(); i++ ) {

        for ( it = possibleLists[i].begin(); it != possibleLists[i].end(); it++ )
            cout << *it << " ";
        cout << endl;

    }*/

    cout << endl << "Total number of combinations: "
        << possibleLists.size() << endl;

    return 0;
}

输入: 1 2 3 1 2 4 3 2

输出: 唯一列表:1 2 3 4 组合总数:2

【讨论】:

  • 感谢您的回复,但我没有得到候选人名单,我也无法在谷歌中找到它.. :(
  • 对不起,因为我正在研究 c++ 和向量的东西,所以迟到了评论。谢谢你的回复,我照你说的做了,检查 http://ideone.com/8DZkvY 但我没有得到正确的输出,因为有只有两个不同的 1234 但得到 50,这是因为向量的大小是 50.. 如何获得正确的输出..:(
  • 我看不到您的代码。但是,我已经编辑了我的答案并包含了完整的代码。你可以检查一下。
【解决方案2】:

在解决像这样的组合问题时,递归可能是最简单的方法。这个想法是您考虑当前项目的所有可能性,然后通过递归剩余的项目来传递其余的工作。在这种情况下,您需要传递一些关于不使用哪些项目的额外信息。

它的工作原理是这样的:

def DistinctChooseFromEach(listOfChoicePairs, alreadyUsed = {}):
    if listOfChoicePairs is empty: return []
    for value in listOfChoicePairs[0]:
        if value in alreadyUsed: continue;
        newUsed = union(alreadyUsed, value)
        remainingChoices = listOfChoicePairs[1:];
        tails = DistinctChooseFromEach(remainingChoices, newUsed)
        for tail in tails:
           yield concat(value, tail)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-24
    • 2023-01-23
    • 1970-01-01
    • 1970-01-01
    • 2021-09-15
    相关资源
    最近更新 更多