可憎的数字

可憎的数字

如果一个数字在其二进制展开中有奇数个1,则被认为是奇异数。前10个奇异数是1,2,4,7,10,11,13,14,16,19,21。有趣的是,所有2的幂都是奇异数,因为它们只有1个位被设置。

下面的文章详细讨论了两种判断一个数字是否为可恶数字的方法。

问题陈述

这个问题的目的是检查给定的数字是否是一个可恶的数字,即它是一个在其二进制展开中具有奇数个设置位的正数。

令人厌恶的数字示例

Input: 34

登录后复制

Output: Non-Odious Number

登录后复制登录后复制

说明

34的二进制表示是10010。

设置位数 = 2。

由于1的数量是偶数,34不是一个可怕的数字。

Input: 1024

登录后复制

Output: Odious Number

登录后复制

说明

1024的二进制表示为10000000000。

设置位数 = 1。

由于1024是2的幂,所以只有1个设置位。因此它是一个可怕的数字。

Input: 53

登录后复制

Output: Non-Odious Number

登录后复制登录后复制

说明

(53)10 = (110101)2

设置位数 = 4。

因此,它不是一个可憎的数字。

解决方案

为了判断一个数是否是可恶的,我们必须知道设置的位数是奇数还是偶数。这里的主要任务是统计数字的二进制展开中设置的位数。可以采用以下技术来计算位数,然后检查结果是奇数还是偶数。

Naive Approach

的中文翻译为:

天真的方法

使用循环和右移运算符逐一遍历数字的所有位。

如果位值为1,则将计数增加一。

检查 count 的最终值是奇数还是偶数。

显示答案。

伪代码

函数 no_of_set_bits()

初始化计数 = 0

当 (n > 0)

if ((n & 1) > 0)   Increment countRight Shift n

登录后复制

返回计数

函数 is_odious()

如果 (count 是奇数)

返回真

其他

返回错误

函数main()

初始化 n

函数调用 no_of_set_bits()

调用函数 is_odious()

打印输出

示例:C++ 程序

该程序检查一个数字是否令人厌恶。它通过在函数 no_of_set_bits() 中每次迭代结束时右移 n 的值来检查循环每次迭代中最右边的位。

#includeusing namespace std;// this function counts the number of set bits by analyzing the rightmost bit using a while loop till n > 0.// it performs logical & operation between 1 and n to determine if the rightmost bit is set or not.// if it is set, count is incremented by 1// right shift the value of n to make the bit left of the rightmost bit, the new rightmost bit.int no_of_set_bits(int n){   int count = 0;   while (n > 0){         // if the rightmost bit is 1: increment count      if ((n & 1) > 0){         count++;      }            // right shift the value of n to examine the next bit      n = n >> 1;   }   return count;}// this function determines if count of set bits is odd or even// odd -> odiousbool is_odious(int count){   // if count is odd return true   if (count % 2 != 0){      return true;   }   return false;}// main functionint main(){   int n = 27;   int countBits = no_of_set_bits(n);   if (is_odious(countBits)){      cout 

输出

27 is Non-Odious Number

登录后复制

时间和空间的分析

时间复杂度:O(log(n)),因为 n 的二进制展开需要 log2n 位,我们检查所有位以检查设置的位。

空间复杂度:O(1),因为没有使用额外的空间。

Brian Kernighan 的算法方法

该算法可用于以更有效的方式计算数字的设置位数。然后可以使用函数 is_odious() 来确定该数字是否令人厌恶。

这种方法的基本原理是重复清除数字最右边的设置位,同时跟踪需要多少次迭代才能达到零。涉及的步骤是 -

将计数初始化为0

当数字大于零时,在数字与其 2 的补码之间执行按位 & 以取消设置最右边的设置位。

每次循环迭代都会增加计数。

检查最终计数是否为奇数。

显示结果。

示例

设数字为10。10的二进制展开为1010。可以观察到它有2个设置位。

循环迭代 1 -

n = 10n & (n-1) =  10 & 91010   (n)1001   (n - 1)1000   (n = 8)

登录后复制

循环迭代 2 -

n = 8n & (n-1) = 8 & 71000    (n)0111(n-1)0       (n = 0) 

登录后复制

迭代次数 = 设置位数 = 2。

伪代码

函数 no_of_set_bits()

初始化计数 = 0

当 (n > 0)

n = n & (n-1)

增加计数

返回计数

函数 is_odious()

与之前的方法相同

函数main()

与之前的方法相同

示例:C++ 程序

这个程序通过计算需要取消所有设置位所需的迭代次数来计算设置位的数量。为了取消位,我们对n和n-1执行位与操作。这是因为n-1的二进制表示会翻转n的最右边的设置位以及其后面的所有位。

#includeusing namespace std;// this function counts the number of set bits by unsetting the rightmost set bit using a while loop till n > 0.// it performs logical & operation between n and n - 1 to unset the rightmost set bit.// count is incremented in every iterationint no_of_set_bits(int n){   int count = 0;   while (n > 0){      // update the value of n to unset the current rightmost set bit      n = n & (n - 1);      count++;   }   return count;}// this function determines if count of set bits is odd or even// odd -> odiousbool is_odious(int count){   // if count is odd return true   if (count % 2 != 0){      return true;   }   return false;}// main functionint main(){   int n = 27;   int countBits = no_of_set_bits(n); // function call   if (is_odious(countBits)){      cout 

输出

27 is Non-Odious Number

登录后复制

时空分析

时间复杂度 - O(log(x)),其中 x 是数字中设置的位数。如果只有 1 个设置位,则循环将运行一次。

空间复杂度 - O(1),因为没有使用额外的空间。

比较上述方法

虽然第一种方法相当容易理解,但需要 log(n) 次迭代才能产生最终结果。另一方面,第二种方法采用 log(x) 迭代,其中 x 是数字的二进制展开中设置的位数。因此,它提高了性能。

结论

本文讨论了两种检查数字是否令人厌恶的方法。它还为我们提供了该方法的概念、示例、使用的算法、C++程序解决方案以及每种方法的复杂性分析。它还对两种方法进行了比较,以确定哪种方法更有效。

以上就是可憎的数字的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2584584.html

(0)
上一篇 2025年3月6日 14:50:39
下一篇 2025年3月1日 11:19:46

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • 按照降序打印数字及其频率

    给定一个int元素的数组,任务是将元素按降序排列并找出它们的出现次数。 Input : arr[]={1,1,1,2,2,2,3,3,4,5,6,7,7}Output : 7 occurs: 2   6 occurs: 1   5 occu…

    2025年3月6日
    200
  • 给定一个数字,编写一个C程序来找到斐波那契数列

    斐波那契数列是通过将前两个数字相加得到的一系列数字。 斐波那契数列从两个数字f0和f1开始。 fo和f1的初始值可以取0、1或1、1。 Fibonacci序列满足以下条件: fn = fn-1 + fn-2 算法 参考Fibonacci序列…

    2025年3月6日
    200
  • 二叉堆的数组表示

    遵循堆排序属性的完全二叉树称为二叉堆。 根据二叉堆的排序方式,它可以分为两种类型: 最小堆是节点的值大于或等于其父节点的值的堆。最小堆的根节点最小。 最大堆是节点的值小于或等于其父节点的值的堆。最大堆的根节点最大。 二叉堆的值通常表示为一个…

    2025年3月6日
    200
  • 检查是否可以使用数组中的所有数字制作一个能被3整除的C/C++程序

    在本节中,我们将看到一个数组是否包含 n 个数字,我们必须检查是否使用这些数字的所有元素生成一个数字,该数字是否能被 3 整除。如果数组元素是 {15, 24, 23, 13},那么我们可以制作像 15242313 这样的整数。能被 3 整…

    2025年3月6日
    200
  • 打印给定数字的乘法表在C中

    程序描述 打印给定数字的乘法表 算法 接受用户提供的任何需要形成乘法的数字 从 I 的值开始乘以给定数 (=1) 将给定数与 I 的值递增,直到 I 值小于或等于12. 示例 /* Program to print the multipli…

    2025年3月6日
    200
  • 最小的重复数字中的1的个数

    在这个问题中,我们只需要打印最小单位中的 1 的数量。 reunit 是一个正数,如休闲数学中的 11、111 或 1111,只有数字 1。reunit 的形式为 $mathrm{(10*n-1)/9}$ 示例 $mathrm{(10*10…

    2025年3月6日
    200
  • 加密字符串

    加密是一种通过使用某些技术或某些步骤来更改数据的技术,使其更改为另一种信息或无法直接从中收集到先前的信息。对于加密,我们必须遵循针对特定加密类型固定的某些步骤。 在这个问题中,我们将得到一个字符串,我们必须按照给定的步骤对其进行加密 &#8…

    2025年3月6日
    200
  • 找到通过插入给定数字形成的最小数字

    在给定的数字中插入一个数字意味着在给定的数字中添加一个新的数字,可以是在数字的前面、后面或者中间。我们已经给出了一个数字和一个数字,并且必须以尽可能小的方式将该数字添加到数字中。为了方便插入操作,我们将把数字转换为字符串。此外,给定的数字也…

    2025年3月6日
    200
  • C中的空指针

    C 中的 void 指针是不与任何数据类型关联的指针。它指向存储中的某个数据位置,意味着指向变量的地址。它也称为通用指针。在 C 语言中,malloc() 和 calloc() 函数返回 void * 或通用指针。 它有一些限制 &#821…

    2025年3月6日
    200
  • C程序用于判断给定的数字是否为强数

    一个强数是一个数字,其中各位数字的阶乘之和等于该数字本身。 示例 123!= 1!+2!+3!                    =1+2+6 =9 在这个例子中,123不是一个强数,因为各位数字的阶乘之和不等于该数字本身。 145!=…

    2025年3月6日
    200

发表回复

登录后才能评论