如何查找范围内重复数字的数字

时间:2017-06-06 02:18:20

标签: algorithm

我试图找到000000000..999999999范围内至少包含3个或更多相似数字的所有数字。

以下是传递的整数示例:112333678111234567122111876

以下是失败的整数示例:123456789122334455123123123

我在Ruby中运行了这一行,然后我的16 GB内存的Macbook Pro内存不足:(000000000..999999999).to_a.select{|e| e.to_s =~ /(\d)\1+/}

4 个答案:

答案 0 :(得分:2)

要计算它们,请记下所有9位数字,

999999999 + 1

减去没有连续相似数字的9位数字,

- 9^9

并用两个连续相似数字的一组或多组减去9位数的数字

- (10 - 2*k) choose k * 9^(9 - k) for k=1 to 4

要按字典顺序列出它们,我们可以使用以下方法:

Until done:
  Increment the number until done or the next increment would invalidate it
  If the third digit from the right is less than 9:
    Increment it and set the last two to the same digit
    Increment all three last digits at once until they are 999
  Increment the first digit, l, left of the the third digit 
   from the right that is less than 9
  Set the digits right of l to 0

答案 1 :(得分:0)

递归解决方案:

  • 生成从000到999的所有数字,并使用n % 111进行检查 是否为111的倍数。如果是,则将标志设置为true。
  • 对于这些数字中的每一个,添加0-9范围内的数字,如果数字的标志为false,请使用(n % 1000) % 111检查三个最后的数字现在是否相等,如果是,则设置标志为真。
  • 递归重复上一步,直到达到7位数。
  • 然后,对于每个7位数字,如果其标志为真,则添加完整 最后两位数字的00-99范围(产生一百个9位数 号码)。
  • 如果标志为false,请使用(n % 100) % 11检查是否为最后一个 两个数字是相等的,如果是,则添加第三个相等的数字和 那么最后一位数的范围是0-9(产生十位9位数 号码)。
  • 如果最后两位数不相等,请添加两位数等于 最后一位数(生成一个9位数字)。

这是一个简单的JavaScript实现。如果您只计算结果,它会很快,但如果您打开打印,则超过6位数的任何内容都需要几分钟而不是几秒钟。

function repeatingDigits(len) {
    for (var n = 0; n < 1000; n++) {
        var flag = n % 111 ? false: true;
        add_digit(10 * n, flag, len - 3);
    }
}
function add_digit(n, flag, len) {
    for (var d = 0; d < 10; n++, d++) {
        var f = (!flag && (n % 1000) % 111 == 0) ? true : flag;
        if (len > 3) add_digit(10 * n, f, len - 1)
        else add_final(100 * n, f);
    }
}
function add_final(n, flag) {
    if (flag) {
        for (var d = 0; d < 100; n++, d++) {
            ++count; // document.write(n + " ");
        }
    }
    else if ((n % 10000) % 1100 == 0) {
        n += (n % 1000) / 10;
        for (var d = 0; d < 10; n++, d++) {
            ++count; // document.write(n + " ");
        }
    }
    else {
        n += ((n % 1000) / 100) * 11;
        ++count; // document.write(n + " ");
    }
}

var count = 0;
repeatingDigits(9);
document.write(count);

重复组为3位或更多位的整数数为:

 3 digits:             10  
 4 digits:            190  
 5 digits:          2,800  
 6 digits:         36,910  
 7 digits:        457,390  
 8 digits:      5,448,700  
 9 digits:     63,154,810  
10 digits:    717,431,590  
11 digits:  8,025,277,600  
12 digits: 88,684,382,710  

答案 2 :(得分:0)

让我们计算你有多少个有三个或更多重复数字的数字。让我们专注于&#34; 1&#34;重复3次或更多次。

要计算这个数字,我们需要考虑的字符串只有3个,只有4个,...所有10个出现的&#34; 1&#34;。

这是累积的二进制概率,可以像这样计算:

cumulative = 0;
for k = 3:10
    cumulative = cumulative + (1/10)^k*(9/10)^(10-k)*nchoosek(10,k);
end
disp(cumulative)

答案是0.0702。但总共有10个 10 不同的数字。因此,只考虑重复&#34; 1&#34;你有0.0702 * 10 10 数字。

关于您当前的实施。我不太了解Ruby,但我假设to_a从一个范围产生数组,所以你要求创建10个 10 数字的数组。假设每个数字需要8个字节(你不能以4个字节存储9,999,999,999),所以最终得到10 ^ 10 * 8/1024 ^ 3~ = 74.5 GB。

答案 3 :(得分:0)

为什么不提取数组中的每个数字并检查是否有任何数字连续3次出现?

int number = 666455477;

int counter = 0;
//l = number of digits
int l = (int)(Math.Log10(number) + 1);
int[] array = new int[l];

//Numbers get inserted in reverse order, but doesnt matter
while (number > 0)
{
    array[counter] = number % 10;       

    if(counter > 1)
    {
        if (array[counter] == array[counter - 1] && array[counter] == array[counter - 2])
            Console.WriteLine("Number contains 3 consecutive: {0}'s", array[counter]);
    }
    number /= 10;
    counter++;
}

通过这种方式,您还可以将大数字存储为字符串,读入每个字符并将其作为int解析到数组中。如果您不想使用数组,您可以简单地使用3个变量来存储当前和之前的2个值。

不确定您想要使用哪种语言解决,但大多数语言都会支持我认为的循环和数组。