C 检查整数是否为一,其中每个数字是零还是一

C 检查整数是否为一,其中每个数字是零还是一,c,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 ==

在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;
}
int containsZero(int num){
如果(num==0)
返回0;
if(num<0)
num=-num;
while(num>0){
如果(数值%10==0)
返回0;
num/=10;
}
返回-1;
}
int containsOne(int num){
如果(num==0)
返回0;
if(num<0)
num=-num;
while(num>0){
如果(数值%10==1)
返回0;
num/=10;
}
返回-1;
}

好吧,在最坏的情况下,你必须检查每个数字,因此你没有比
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 n=701;
而(n!=0&(n%10)1)
{
printf(“错误编号”);
}
其他的
{
printf(“好数字”\n);
}
不过,这是以正数为前提的。要将其转换为一般功能,请执行以下操作:

int tester(int n)
{
   if ( n < 0 )
   {
       n = -n;
   }
   while ( n != 0 && (n % 10) <= 1 )
   {
      n /= 10;
   }
   return ( (n % 10) <= 1 );
}
int测试仪(int n)
{
if(n<0)
{
n=-n;
}

当(n!=0&(n%10)时,在最坏的情况下,你必须检查每个数字,因此你不能有比
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 n=701;
而(n!=0&(n%10)1)
{
printf(“错误编号”);
}
其他的
{
printf(“好数字”\n);
}
但这假设为正数。要将其放入常规函数中,请执行以下操作:

int tester(int n)
{
   if ( n < 0 )
   {
       n = -n;
   }
   while ( n != 0 && (n % 10) <= 1 )
   {
      n /= 10;
   }
   return ( (n % 10) <= 1 );
}
int测试仪(int n)
{
if(n<0)
{
n=-n;
}

而(n!=0&(n%10)我能想到的最好的解决方案,不使用字符串:

while(n)
{
    x = n%10;
    if(x>1)
        return -1;
    n /= 10;
}
return 0;

我能想到的最好的解决方案,不使用字符串:

while(n)
{
    x = n%10;
    if(x>1)
        return -1;
    n /= 10;
}
return 0;

您可以剥下每个数字的皮并检查它。这需要
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;

您可以剥下每个数字的皮并检查它。这需要
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;

您使用基数10,因此,每次检查
%10

int justOnesAndZeros(int num) {
    while ( num )
    {
        if ( ( num % 10 != 1 ) && ( num % 10 != 0 ) )
        {
            return FALSE;
        }
        num /= 10;
    }
    return TRUE;
}

您使用基数10,因此,每次检查
%10

int justOnesAndZeros(int num) {
    while ( num )
    {
        if ( ( num % 10 != 1 ) && ( num % 10 != 0 ) )
        {
            return FALSE;
        }
        num /= 10;
    }
    return TRUE;
}
序言 其他答案中显示的好的直接算法是O(n),即
n
数字。由于n很小(即使使用64位整数,我们也不会有超过20位),因此应该考虑实现“更好”的算法,并论证“有效”的含义;给定的O(n)算法可以被认为是有效的

“解决方案” 我们可以考虑稀疏数组,因为在40亿个数字中,只有2^9(两个符号,9个“位置”)具有所需的属性。我觉得某种模式应该从位中出现,因此可能有一种解决方案利用这种模式。因此,我丢弃了所有十六进制中仅包含0和1的十进制数,注意到一种模式,并利用它实现了最简单的代码-进一步的改进肯定是可能的,例如“表”可以减半,考虑到如果x是偶数并且具有该属性,那么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)和测试代码可用

时机 使用我的解决方案运行测试(“搜索”属性介于0和20亿之间的数字-没有理由超出此范围),使用
time
,并将输出重定向到
/dev/null

real    0m4.031s
user    0m3.948s
使用另一个解决方案运行同一测试,从另一个答案中选择:

real    0m15.530s
user    0m15.221s
序言 其他答案中显示的好的直接算法是O(n),即
n
数字。由于n很小(即使使用64位整数,我们也不会有超过20位),因此应该考虑实现“更好”的算法,并论证“有效”的含义;给定的O(n)算法可以被认为是有效的

“解决方案” 我们可以考虑稀疏数组,因为在40亿个数字中,只有2^9(两个符号,9个“位置”)具有所需的属性。我觉得某种模式应该从位中出现,因此可能有一种解决方案利用这种模式。因此,我丢弃了所有十六进制中仅包含0和1的十进制数,注意到一种模式,并利用它实现了最简单的代码-进一步的改进肯定是可能的,例如“表”可以减半,考虑到如果x是偶数并且具有该属性,那么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)和测试代码可用

时机 使用我的解决方案运行测试(“搜索”属性介于0和20亿之间的数字-没有理由超出此范围),使用
time
,并将输出重定向到
/dev/null

real    0m4.031s
user    0m3.948s
使用另一个解决方案运行同一测试,从另一个答案中选择:

real    0m15.530s
user    0m15.221s


不要标记C++,如果它是一个C问题懒惰的方法:转换为字符串,检查每个字符是“0”还是“1”,我不想使用字符串,为什么你返回0或1?使用布尔函数的标准布尔值。@埃弗特为什么?Num可以被改变而没有任何问题。如果不是C问题,请不要标记C++:转换为字符串,检查每个字符是否是“0”o。r'1'我不想使用stringWhy返回0或-1?对布尔函数使用标准布尔值。@Evert why?num可以毫无问题地更改。+1-我喜欢你如何使if子句脱离循环…嗯,有点;)@到目前为止,我们还不能完全消除这种检查。毕竟,这就是我们应该检查的:Deffient意味着…?必须有一些位技巧+可能额外的数据(不是假装有一个2^32元素数组…),这可以使它成为O(1)…现在没有时间考虑它,但我会做,并带着ans回来,如果有的话;)@ShinTakezou是的,查找表很简单,请看我的更新。不过它是你号码的O(1)w.r.t.位,但它是O(L)或O(log L),其中L是表的长度。这比O(d)更糟糕。@stefan最多32位