如何从3位数组合中找到一个数字?

时间:2016-03-09 10:14:58

标签: algorithm search language-agnostic logic combinations

如果有一个8位数字65478209(数字中的数字可以重复)并且给定组合总是按数字的顺序排列,那么如果给出所有组合8c3 = 56种组合,那么什么是最短的解决方案找出数字?

示例场景可以是银行登录,其中用户需要输入其代码的3个随机数字,例如第3个,第5个和第6个,其中这是8c3组合之一。因此,如果给出所有8c3组合,那么找到数字的解决方案/逻辑是什么? (如果有更多数字作为解决方案,则为第一个数字)

对于编程语言中的问题解决,输入将是56个3位组合的数组,我们必须找到“65478209”或其他任何代码。

2 个答案:

答案 0 :(得分:2)

使用排列怎么样?我用c ++风格编写简单代码。检查一下。

int k = 3;
string digit = "65478209";
int digitLen = digit.length();

int* indexArr = new int[digitLen];
for(int i=0; i < digitLen; i++) indexArr[i] = i;

do
{
    bool isInOrder=true;
    string ret = "";
    for(int i=1; i < k; i++) if(indexArr[i] < indexArr[i-1])
    {
        isInOrder = false;
        break;
    }
    if(!(isInOrder)) continue;

    for(int i=0; i < k; i++) ret += digit[indexArr[i]];
} while(next_permutation(indexArr, indexArr+digitLen));

delete indexArr;

修改

这是我的解决方案。

vector<string> combinations;
set<int> includedDigit;
vector<int> referCnt;

// Get reference count from all precedences
for(int i=0; i < combinations.size(); i++)
{
    string e = combinations[i];
    for(int j=0; j < k-1; j++)
    {
        includedDigit.insert(e.at(j) - '0');
        for(int l=j+1; l < k; l++)
        {
            int curDigit = e.at(l) - '0';
            referCnt.push_back(curDigit);
        }
    }
}

// Sorting reference counts with digit
vector<pair<int,int>> ret;
for(int i=0; i < 10; i++)
{
    int digitCnt = count(referCnt.begin(), referCnt.end(), i);
    if(digitCnt == 0 && includedDigit.find(i) != includedDigit.end()) ret.push_back(make_pair(1, i));
    else if(digitCnt != 0) ret.push_back(make_pair(digitCnt, i));
}
sort(ret.begin(), ret.end());

// Print the result
for(auto it=ret.begin(); it != ret.end(); it++)
{
    pair<int,int> val = *it;
    cout << val.second;
}

虽然我认为它可以缩短,但它有效。另外,如果原始数字不是一种排列,它应该更复杂。

答案 1 :(得分:0)

k = 3

以下递归算法从有序集中选择所有k元素组合:

  1. 选择i作为第一个元素。
  2. i与大于k-1的元素集合中递归选择的i个元素的每个元素组合。
  3. 为集合中的每个i迭代上述内容。