C程序检查整数是否为零或一个数字的有效方法是什么?
示例100 //是正确的,因为它只包含0或1
701 //错了
我试过
int containsZero(int num) {
if(num == 0)
return 0;
if(num < 0)
num = -num;
while(num > 0) {
if(num % 10 == 0)
return 0;
num /= 10;
}
return -1;
}
int containsOne(int num) {
if(num == 0)
return 0;
if(num < 0)
num = -num;
while(num > 0) {
if(num % 10 == 1)
return 0;
num /= 10;
}
return -1;
}
答案 0 :(得分:2)
嗯,在最糟糕的情况下,您必须检查每个数字,因此您的算法不能超过O(d)
,其中d
是数字位数。
直接的方法满足了这个:
int n = 701;
while ( n != 0 && (n % 10) <= 1 )
{
n /= 10;
}
if ( (n % 10) > 1 )
{
printf("Bad number\n");
}
else
{
printf("Good number\n");
}
这假定为正数。把它放到一般函数中:
int tester(int n)
{
if ( n < 0 )
{
n = -n;
}
while ( n != 0 && (n % 10) <= 1 )
{
n /= 10;
}
return ( (n % 10) <= 1 );
}
我们在这做什么?我们检查最后一位十进制数字(n%10)是0还是1,然后将最后一位数除以十,直到数字为0。
现在当然还有另一种方法。 如果您保证有例如总是32位整数,查找表不是那么大。我想它可能是大约2048个条目,所以真的不是那么大。
您基本上列出了所有有效数字: 0 1 10 11 100 101 110 111 ...
现在您只需搜索列表(如果列表已排序,则可以进行二进制搜索!)。当然,线性搜索的复杂性将比上述方法更糟糕。我怀疑二进制搜索在实际性能方面还要差一些,因为你需要在内存中跳过很多而不是只运行一个数字。
对这么小的问题感兴趣的东西很可能是矫枉过正的。
答案 1 :(得分:2)
你可以剥掉每一个数字并检查它。这需要O(n)
次操作。
int input;
while (input != 0)
{
int digit = input %10; //get last digit using modulo
input = input / 10; //removes last digit using div
if (digit != 0 && digit != 1)
{
return FALSE;
}
}
return TRUE;
答案 2 :(得分:1)
其他答案中显示的好的直接算法是O(n),是n
数字的数字。由于n很小(即使使用64位整数,我们也不会超过20位),应该考虑实现“更好”的算法,并且“高效”的含义是有争议的;给定的O(n)算法可以被认为是高效的。
我们可以考虑稀疏数组,因为在4亿个数字中,只有2 ^ 9(两个符号,9个“位置”)具有所需属性。我觉得应该从比特中出现某种模式,因此可以有一个利用这个的解决方案。所以,我已经将所有包含0和1的十进制数字转换为十六进制,注意到模式并实现了利用它的最简单的代码 - 肯定可以进行进一步的改进,例如:考虑到如果x是偶数且具有属性,则“table”可以减半,那么x + 1也具有该属性。
支票只是
bool only01(uint32_t n)
{
uint32_t i = n & 0xff;
uint32_t r = n >> 8;
return map01[i][0] == r || map01[i][1] == r;
}
完整表格(map01)和测试代码可用at this gist。
使用time
并将输出重定向到/dev/null
,运行测试(“搜索”具有0到2亿之间属性的数字 - 没有理由超越),使用real 0m4.031s
user 0m3.948s
并将输出重定向到real 0m15.530s
user 0m15.221s
:< / p>
{{1}}
从另一个答案中选择另一个解决方案进行相同测试的运行:
{{1}}
答案 3 :(得分:0)
我能想到的最佳解决方案,不使用字符串:
while(n)
{
x = n%10;
if(x>1)
return -1;
n /= 10;
}
return 0;
答案 4 :(得分:0)
您使用基数10,因此,每次检查% 10
:
int justOnesAndZeros(int num) {
while ( num )
{
if ( ( num % 10 != 1 ) && ( num % 10 != 0 ) )
{
return FALSE;
}
num /= 10;
}
return TRUE;
}