【问题标题】:How to get all possible n-digit numbers that can be formed using given digits?如何获得可以使用给定数字形成的所有可能的 n 位数字?
【发布时间】:2012-03-27 14:01:16
【问题描述】:

我正在编写面临此问题的大型应用程序的一部分。我将通过呈现一个类似的普通场景将所有细节从所有细节中抽象出来。

给我 n(在运行时形成的数字的位数)。

我还得到了一个数字列表,比如 {2,4,8,9}。

我必须从上面给定长度的列表中形成所有可能的数字。

例如如果 n = 3 并且列表 = {4, 5, 6}

那么可能的数字是:

444,
445,
446,
454,
455,
456,
464,
465,
466, 

等等……

任何帮助将不胜感激!

问候

沙恨沙

【问题讨论】:

  • 因为答案在您的问题的解释上有所不同:您能指定输出应该是什么数据类型吗?

标签: algorithm loops for-loop logic permutation


【解决方案1】:

您可以使用递归。 假设您可以使用的数字在一个数组中。

C#代码:

static int[] digits = new int[] {4, 5, 6};

static void Rec(int current, int numDigits) {
    if(numDigits==0)
        Console.WriteLine(current);
    else
        foreach(int x in digits)
            Rec(current*10+x, numDigits-1);
}

然后调用:

static void Main(string[] args){
    Rec(0, 3);
}

【讨论】:

  • 所有答案都很好,但我觉得这是最优雅的一个。非常感谢@petar Ivanov! (:
【解决方案2】:

使用递归函数。这是javascript中的一个例子......

var result;
function recurse(n,lst,s){
  var i,c;  
  for (i=0; i<lst.length; i++){
    if(n>1)recurse(n-1,lst,s+lst[i]);
    else result.push(s+lst[i])
  }
}
function generate(n,lst){
  result=[];
  if(n>0 && lst.length>0){
    for(var i=0; i<lst.length; i++)lst[i]=''+lst[i];
    recurse(n,lst,'')
  }
  return result
}
generate(3,[4,5,6]);

【讨论】:

    【解决方案3】:

    我的方法如下:

    list combine(list a, list b)
    {
        list c;
        for ( i = 0, i < list.size(), ++i )
        {
            for ( j = 0, j < list.size(), ++j )
                c.add( a[i] * pow(10,log_10(b[j]) + 1) + b[j] );
        }
        return c;
    }
    

    然后对于n位问题:

    list nDigit(list a, int n)
    {
        list out;
        out = combine(a, a);
        for ( i = 1, i < n, ++i )
            out = combine(a, out);
        return out;
    }
    

    这应该会变魔术。 代码应该是不言自明的,如果不是,请发表评论。

    您必须注意列表项是否可以超过一个数字。然后需要在 combine 函数中添加以下内容:

    [....]
    for ( j = 0, j < list.size(), ++j )
    {
        if ( log_10(a[i]) + log_10(b[j]) + 1 <= n )
            c.add( a[i] * pow(10,log_10(b[j]) + 1) + b[j] );
    }
    [....]
    

    当然还有 n 给 combine 函数。

    最后在 nDigit 你必须检查是否有长度小于 n 的组合

    【讨论】:

    • 将数字字符串视为整数非常容易溢出。为什么不使用字符串和索引来代替数字和对数?
    • Shahensha 从来没有提到它必须是字符串,所以这个算法是为整数工作而设计的
    【解决方案4】:

    您的任务相当于以不同于 10 的基数进行计数,如以下 C++ 程序所示:

    #include <vector>
    #include <iostream>
    
    using std::vector;
    
    unsigned int pow(unsigned int n, unsigned int m)
    {
        unsigned int to_ret = 1;
        for (unsigned int i = 0; i < m; i++)
            to_ret *= n;
        return to_ret;
    }
    
    void print_all(vector<unsigned int> sym, unsigned int n)
    {
        const unsigned int m = sym.size();
        unsigned int max = pow(m, n);
        char *text = new char[n + 1];
        text[n] = '\0';
        for (unsigned int i = 0; i < max; i++) {
            unsigned int to_print = i;
            for (unsigned int j = 1; j <= n; j++) {
                text[n - j] = sym[to_print % m];
                to_print /= m;
            }
            std::cout << text << std::endl;
        }
        delete[] text;
    }
    
    int main(int argc, char **argv)
    {
        vector<unsigned int> a({'1','2','3','4','5'});
        print_all(a, 5);
        return 0;
    }
    

    对于足够高的nm 值,max 很容易溢出这种方法的明显问题。您可以通过使用m 链表数组模拟计数来解决这个问题,该数组必须表示“数字”。

    【讨论】:

      【解决方案5】:

      我编写了以下 F# 代码来解决这个问题:

      let rec variations rank xs = 
          match rank with
          | 1 -> 
              seq {
                  for x in xs do
                  yield [x]
              }
      
          | _ -> 
              seq {
                  for x in xs do
                  for y in variations (rank-1) xs do   
                  yield x::y
              }
      

      所以,

      variations 3 (seq {4..6})
      |> Seq.iter (printfn "%s")
      

      将打印

      444
      445
      446
      454
      455
      ...
      666
      

      所有 27 个值

      【讨论】:

        猜你喜欢
        • 2015-03-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-04
        相关资源
        最近更新 更多