生成所有增加的数字

时间:2012-02-08 22:25:44

标签: c# java

我在接受采访时遇到了以下问题。

对于给定的位数,生成所有数字,使得高位数的值小于低位数。

145 // 1< 4< 5

有没有比我提出的更好(有效)的方法:

public static void GenerateSpecialNumbers(int noDigits)
{           
    int prod = 1;
    for(int i=0; i < noDigits; i++)
    {
        prod = prod * 10;
    }
    int minValue = prod/10;
    int maxValue = prod - 1;        

    for(int i = minValue; i < maxValue; i++)
    {
        bool isValid = true;

        int num  = i;
        int max = int.MaxValue;

        while(num > 0)
        {
            int digit = num % 10;
            if(digit >= max)
            {
                isValid = false;
                break;
            }
            max = digit;            

            num = num/10;
        }

        if(isValid)
            Console.WriteLine(i);               
    }
}

编辑: 输出3位数:

123 124 125 126 127 128 129 134 135 136 137 138 139 145 146 147 148 149 156 157 158 159 167 168 169 178 179 189 234 235 236 237 238 239 245 246 247 248 249 256 257 258 259 267 268 269 278 279 289 345 346 347 348 349 356 357 358 359 367 368 369 378 379 389 456 457 458 459 467 468 469 478 479 489 567 568 569 578 579 589 678 679 689 789

7 个答案:

答案 0 :(得分:3)

好难题!这是我的看法:

static void Main()
{
    WriteNumbers(3);
}

static void WriteNumbers(int digits, int number = 0)
{
    int i = (number % 10) + 1;
    number *= 10;
    for (; i <= 9; i++)
    {
        if (digits == 1)
            Console.WriteLine(number + i);
        else
            WriteNumbers(digits - 1, number + i);
    }
}

答案 1 :(得分:2)

是的,这个问题有一个简单的递归描述,可以构建所有数字,而不必测试并扔掉任何数字。

例如,有效n位数字包括“1”.append(仅使用数字n-1的所有有效>1位数字)

每个数字的下限为1加上紧靠其左侧的数字。你能找到一个简单的上限吗?

答案 2 :(得分:1)

for (i1 from 1 to 9)
for (i2 from 1 to i1 - 1)
for (i3 from 1 to i2 - 1)
 print(i1 * 1 + i2 * 10 + i3 * 100);

固定长度数字不需要递归。易于编码和故障安全。

请注意,循环上限不固定。这就是使这项工作的原因。

答案 3 :(得分:1)

因为我喜欢基于表格的东西,所以我会先生成n = 2的表(显然是&lt; 100个条目),然后将它保存在初始化的数组中。

然后f(n)=由f(n-1)组成的序列N [1,2,3,4,5,6,7,8,9]中的数字,其中f(n-1)[ 0]&gt; Ñ

i.e. for n = 3:
1, f(2) where f(2)[0] > 1: 123, 124, 125, ...
2, f(2) where f(2)[0] > 2: 234, 235, 236, ...
...

答案 4 :(得分:1)

这是我的解决方案,得到@Hand-E-Food和@Ben Voigt评论的帮助。我觉得这更容易理解:

        static void WriteNumbers(int digits, int left=0,int number=0)
        {
           for(int i=left+1; i<10; i++)
           {
               if(digits==1)
               {
                   Console.WriteLine(number*10+i);
               }
               else
               {
                   WriteNumbers(digits - 1, i, number*10 + i);
               }
           }
        }

答案 5 :(得分:0)

这里有一个提示:如果有N个可能的数字值,并且你想要选择其中的M个,可能的数量是“N选择M”。

答案 6 :(得分:0)

这是一个适用于任意数字位数的解决方案(尽管有点hack-ish):

private static void printSpecialNumbers(int noOfDigits){
    int max = (int) Math.pow(10, noOfDigits);
    int min = (int) Math.pow(10, noOfDigits-1);

    for(int i = min; i < max; i++){
        if(isSpecialNumber(i))
            System.out.println(i);
    }
}

private static boolean isSpecialNumber(int i){

    String intString = String.valueOf(i);
    String[] digits = intString.split("");

    for(int k = 1; k < digits.length-1; k++){
        if(Integer.valueOf(digits[k]) >= Integer.valueOf(digits[k+1]))
            return false;
    }

    return true;
}