给定每个数字值范围的可能数字

时间:2018-08-11 06:37:05

标签: combinations permutation

我们给了3个变量dabd指定最大位数。 ab分别指定最小位数和最大位数。 我们必须找出可以制造多少个数字,每个数字的数字都以不降序的顺序进行排列,最大位数为d,a和b之间的每个数字都包含在内。

Ex-
d = 1
a = 8
b = 9
Answer = 2 (Possible numbers are 8 and 9)


Ex-
d = 2
a = 8
b = 9
Answer = 5 (Possible numbers are 8, 9, 88, 89, and 99)

我曾尝试应用,置换和组合,但是无法找到所有d值的通用答案。

此外,我试图观察每个位数可能出现的模式,但似乎有所不同。

实际的方法是什么?

1 个答案:

答案 0 :(得分:0)

您正在寻找具有重复性的组合。我们要做的就是针对每个特定长度(不超过d)重复生成您的集合的所有组合。

下面,我们在C++中有一个简单的实现。首先,我们需要适当的include以及一个用于返回具有重复的组合数(即nChooseK)的函数:

#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>

int nChooseK(int n, int k) {

    int nCk = 1;

    for (int i = (n - k + 1), d = 1; d <= k; ++i, ++d) {
        nCk *= i;
        nCk /= d;
    }

    return round(nCk);
}

这是生成具有重复的组合的算法:

void combsWithRep(std::vector<int> v, int d) {

    int numIter, maxZ, count = 0;
    int n = v.size();
    int d1 = d - 1, d2 = d - 2;
    std::vector<int> z(d, 0);
    int numRows = nChooseK(n + d - 1, d);

    maxZ = n - 1;

    while (count < numRows) {
        numIter = n - z[d1];;

        for (int i = 0; i < numIter; ++i, ++count, ++z[d1]) {
            for (int k = 0; k < d; ++k) {
                std::cout << v[z[k]];
            }
            std::cout << std::endl;
        }

        for (int i = d2; i >= 0; i--) {
            if (z[i] != maxZ) {
                ++z[i];
                for (int k = (i + 1); k < d; ++k)
                    z[k] = z[k - 1];

                break;
            }
        }
    }
}

这是main函数:

int main() {
    std::vector<int> v;
    int d, input;

    std::cout << "Enter the number of possible digits" << std::endl;
    std::cin >> d;

    std::cout << "\nEnter the digits" << std::endl;
    while (std::cin >> input)
        v.push_back(input);

    std::sort(v.begin(), v.end());

    for (int i = 1; i <= d; ++i)
        combsWithRep(v, i);

    return 0;
}

因此,输入以下内容:

Enter the number of possible digits
4

Enter the digits
7
8
9

输出为:

7
8
9
77
78
79
88
89
99
777
778
779
788
789
799
888
889
899
999
7777
7778
7779
7788
7789
7799
7888
7889
7899
7999
8888
8889
8899
8999
9999