我不完全相信你的模方法会因为工作,如果你开始与7823
和78
,然后7823 mod 100
给你23
具有没有公共数字与78
即使7823
呢。
但是,即使我误解了规范,它确实奏效,我认为还有更好的办法。首先,如何得分一个基于它包含的数字的数字。
如果你的整数至少有10位(他们会,因为标准要求一个范围需要16位),你可以使用一个位掩码,每位表示数字是否包含数字。我们可以使用一个正常的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^^^^
//(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
除以10时给予剩余部分。所以123 % 10
给出3
,314159 % 10
给出9
等等。
下一步是将二进制文件1
左移很多位,其中1 << (val % 10)
。将1位左移4位可以给出二进制值10000
,因此这只是一种将1位置于正确位置的方法。
最后,按位或与计算值的屏蔽,有效地设置在面具相当于位,牢记位a | b
给你1
如果一方或双方a
和b
是1
。
或者您可以查看我的其他答案here以了解更多详情。
所以,我听到你问,这个位掩码如何帮助我们找到没有共同数字的数字。那么,AND按位运算符&
进来 - 这只会给你一个1
位,如果两个输入位是1
(同样,请参阅前面提供的链接关于按位运算符的更多详细信息)。
一旦你有你的数位掩码,你可以使用&
与他们按照下面的例子,那里有没有共同的数字:
Number Bitmask
------ ----------------
314159 000000 1000111010
720 000000 0010000101
----------------- AND(&)
000000 0000000000
可以看到的是,除非位位置有1
为两个数字,结果位将是0
。如果有任何数字都是常见的话,那将是一些非零值:
Number Bitmask v
------ -----------------
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
实际起始编号。如果不是,只需取消注释。
有你有它,如下面的成绩单,其中包括除其他事情你的测试数据:
$ ./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
代码:您可能还需要变得有点聪明你想,如果你去否定,比如一起发生什么。
'int closest = number1 + 1;'here' number1' in uninitialized。 – 2014-10-28 11:40:00
这没关系,因为如果我有378和78它需要从379开始。 – 2014-10-28 11:50:18
请检查您的代码。 **在**之前做'+ 1'。 – 2014-10-28 11:53:16