C:找到与第一个数字最接近的数字而不重复第二个数字的数字?

时间:2014-10-28 11:00:07

标签: c closest digit

我读了两个数字,int

我需要做的是打印高于但最接近第一个数字的数字,例如378,但包含第二个数字中的任何数字数字,例如78

  

输入:378 78,输出:390,因为这是378以上的最低数字,不包含78的任何数字。

     

输入:3454 54,输出:3600因为3600是第一个不包含54的最近,54的数字1}}。

我试图通过从第二个数字的长度获取第一个数字的最新模数位来做到这一点。例如:

  

378 78

378 mod 100 == 78,然后比较7878位数,如果有同一位数移至379,则检查379 mod 100 == 79。在比较7978时,7是相同的数字。

依此类推,直到我们得到390为例。这适用于所有N号码。

这是我到目前为止所做的......而且几乎没有。

#include <stdio.h>

int main()
{
    int number1, number2;
    int closest = number1 + 1;
    scanf("%d %d",&number1,&number2);

    int count_modulus = 1;

    while(number2)
    {
        count_modulus = count_modulus * 10;
        number2 = number2 / 10;
    }
    int mod = count_modulus;
    int n2 = number2;
    while(number1)
    {
        int remain = number1 % mod;
        while(remain)
        {
            if((remain % 10 == number2 % 10))
            {

            }
            else
            {

            }
        }
    }
    printf("%d",closest);
    return 0;
}

1 个答案:

答案 0 :(得分:0)

我不是完全确信你的模数方法会起作用,因为如果你从782378开始,那么7823 mod 100会给你23 787823具有 no 数字,int

但是,即使我误解了规范并确实有效,我认为还有更好的方法。首先,如何根据它包含的数字得分。

如果您的整数至少有十位(并且它们将由于标准要求的范围需要十六位),您可以使用位掩码来表示该数字是否包含数字。我们可以使用正常的// Return a bitmask with the bottom ten bits populated, // based on whether the input number has a given digit. // So, 64096 as input will give you the binary value // 000000 0000111010 // <-unused ^ ^ ^ ^ // 9876543210 (digits) int getMask (int val) { int mask = 0; // All start at 0 while (val > 0) { // While more digits mask = mask | (1 << (val % 10)); // Set bit of digit val = val / 10; // Move to next digit } return mask; } ,因为十位将使我们无法接近符号位,这可能会导致我们的问题。

对数字进行评分的代码是:

mask = mask | (1 << (val % 10));

“棘手”的一点是声明:

val % 10

它的作用是获取数字的最后一位数,val在将123 % 10除以10时给出余数。因此3提供314159 % 109提供1等等。

下一步是将多个位的二进制1 << (val % 10)向左移动10000。向左移动1位四位将为您提供二进制值a | b,因此这只是将1位置于正确位置的一种方法。

最后,您使用该计算值对掩码进行按位或运算,有效地设置掩码中的等效位,请记住,如果中的任何一个或两者,位1会为您提供a b1&

或者您可以查看我的其他答案here以获取更多详细信息。

所以,我听到你问,这个位掩码如何帮助我们找到没有常用数字的数字。那么,AND位运算符1进来的地方 - 如果两个输入位都是1,这只会给你一个&位(再次,请参阅链接前面提供了有关按位运算符的更多详细信息)。

一旦为两个号码设置了位掩码,就可以使用Number Bitmask 9876543210 ------ ---------------- 314159 000000 1000111010 720 000000 0010000101 ----------------- AND(&) 000000 0000000000 ,如下例所示,其中没有常用数字:

1

您可以看到,除非位位置具有两个数字的0,否则结果位将为Number Bitmask v 9876543210 ------ ----------------- 314159 000000 1000111010 320 000000 0000001101 ----------------- AND(&) 000000 0000001000 ^ The bit representing the common digit 3. 。如果任何数字都是共同的,那么它将是一些非零值:

#include <stdio.h>

int main (int argc, char *argv[]) {
    // Default input numbers to both zero, then try
    //   to get them from arguments.

    int check = 0, exclude = 0, excludeMask;
    if (argc > 1)
        check = atoi(argv[1]);
    if (argc > 2)
        exclude = atoi(argv[2]);

    // Get the mask for the exclusion number, only done once.

    excludeMask = getMask (exclude);

    // Then we loop, looking for a mask that has no
    //   common bits.

    printf ("%d -> ", check);
    //check++;
    while ((excludeMask & getMask (check)) != 0)
        check++;
    printf ("%d\n", check);

    return 0;
}

这导致我们得到实际的检查代码,相对容易在评分函数之上构建:

check++

流程基本上是从参数中获取数字,计算排除数字的位掩码(在结果中具有想要的数字的位数),然后开始查找从支票号码,直到你找到一个。

我已经注释掉了最初的123因为我不确定你是否真的想要一个更高的数字而不是给定的数字,或者98是否排除123的{​​{1}}应该为您提供$ ./myprog 378 78 378 -> 390 $ ./myprog 3454 54 3454 -> 3600 $ ./myprog 123 98 # would give 124 if 'count++' uncommented 123 -> 123 $ ./myprog 314159 6413 314159 -> 500000 的实际起始编号。如果没有,只需取消注释该行。

你有它,如下面的成绩单所示,其中包括你的测试数据:

$ ./myprog 1 154862397

它确实有一个可能致命的缺陷,但如果你在开始寻找之前检查排除位掩码,那么很容易修复。我会将其作为练习留给读者,但只需考虑以下命令可能会发生什么:

check

当然,如果你想要其他方式(更低的数字),那么递减 $ ./myprog 1 102 而不是递增它的问题。如果你出现负面情况,你可能还需要更明智地了解你想要发生什么,例如:

{{1}}

目前的代码可能无法很好地处理。