当前位置:   article > 正文

C#,二进制数的非0位数统计(Bits Count)的算法与源代码_如何证明非邻接二进制表示中非零位的个数平均为k/3

如何证明非邻接二进制表示中非零位的个数平均为k/3

计算一个十进制数的二进制表示有多少位1?

1 遍历法(递归或非递归)

使用循环按位统计1的个数。

2 哈希查表法

利用一个数组或哈希生成一张表,存储不同二进制编码对应的值为1的二进制位数,那么在使用时,只需要去进行查询,即可在O(1)的时间复杂度内得到结果。
但是,此算法有个弊端,由于算法是采用空间换取时间的方法,当一个二进制数的位长超过一定限度时,对应的表也就会占据很大的空间,也就是说节约时间越多,花费的存储越多。另外此方法还会收到CPU缓存的限制,如果表太大,表在缓存的上下文切换也就越多,可能会导致性能没有想象中那么高。
所以,为了解决此问题,一般情况下,采用适当的二进制位长度来建表,比如8位、16位,这样情况下,可以对上述问题得到一个平衡,不仅可以享受到优越的性能,而且时间开销也没有遍历法高。

3 Variable-precision SWAR算法

在数学上,我们一般称上述问题为“计算汉明重量”,而当前一直效率最好的通用算法为variable-precision SWAR算法,该算法不仅在常数时间计算多个字节的汉明重量,而且不需要使用任何额外的内存。
 

4 源程序

  1. using System;
  2. using System.Text;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. namespace Legalsoft.Truffer.Algorithm
  6. {
  7. public static partial class Algorithm_Gallery
  8. {
  9. public static int Count_Setbits(int n)
  10. {
  11. // initialize the result
  12. int bitCount = 0;
  13. for (int i = 1; i <= n; i++)
  14. {
  15. bitCount += Count_Setbits_Utility(i);
  16. }
  17. return bitCount;
  18. }
  19. private static int Count_Setbits_Utility(int x)
  20. {
  21. if (x <= 0)
  22. {
  23. return 0;
  24. }
  25. return (x % 2 == 0 ? 0 : 1) + Count_Setbits_Utility(x / 2);
  26. }
  27. public static int Count_Setbits_Second(int n)
  28. {
  29. int i = 0;
  30. int ans = 0;
  31. while ((1 << i) <= n)
  32. {
  33. bool k = false;
  34. int change = 1 << i;
  35. for (int j = 0; j <= n; j++)
  36. {
  37. ans += (k) ? 1 : 0;
  38. if (change == 1)
  39. {
  40. k = !k;
  41. change = 1 << i;
  42. }
  43. else
  44. {
  45. change--;
  46. }
  47. }
  48. i++;
  49. }
  50. return ans;
  51. }
  52. private static int Leftmost_Bit(int n)
  53. {
  54. int m = 0;
  55. while (n > 1)
  56. {
  57. n = n >> 1;
  58. m++;
  59. }
  60. return m;
  61. }
  62. private static int Next_Leftmost_Bit(int n, int m)
  63. {
  64. int temp = 1 << m;
  65. while (n < temp)
  66. {
  67. temp = temp >> 1;
  68. m--;
  69. }
  70. return m;
  71. }
  72. public static int Count_Setbits_Third(int n)
  73. {
  74. int m = Leftmost_Bit(n);
  75. return Count_Setbits_Third_Utility(n, m);
  76. }
  77. public static int Count_Setbits_Third_Utility(int n, int m)
  78. {
  79. if (n == 0)
  80. {
  81. return 0;
  82. }
  83. m = Next_Leftmost_Bit(n, m);
  84. if (n == ((int)1 << (m + 1)) - 1)
  85. {
  86. return (int)(m + 1) * (1 << m);
  87. }
  88. n = n - (1 << m);
  89. return (n + 1) + Count_Setbits_Third(n) + m * (1 << (m - 1));
  90. }
  91. }
  92. }

POWER BY TRUFFER.CN
BY 315SOFT.COM

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/135088
推荐阅读
相关标签
  

闽ICP备14008679号