检查整数是否为每个数字为零或一个数字的整数

时间:2014-01-15 12:45:42

标签: c

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;
}

5 个答案:

答案 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 );
}

演示:http://ideone.com/jWyLdl

我们在这做什么?我们检查最后一位十进制数字(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;
}