1 bitMap实现

原理:用位 来表示某个数字是否存在。比如0~63,可以用4个字节(64位)来表示是否存在。存在,对应位为1,不存在为0。由此可以极大节约存储空间。

  1. public class BitMap {
  2. private long[] bits;
  3. public BitMap(int max) {
  4. bits = new long[(max + 64) >> 6];
  5. }
  6. public void add(int val) {
  7. if (((val + 64) >> 6) > bits.length) {
  8. bits = new long[(val + 64) >> 6];
  9. }
  10. // val&63 等同于 val%64 求val摸64的余数
  11. // val >> 6 等同于 val/64 求val存储在bitMap数组第几个下标位置
  12. bits[val >> 6] |= (1L << (val & 63));
  13. }
  14. public void delete(int val) {
  15. if (((val + 64) >> 6) <= bits.length) {
  16. bits[val >> 6] &= ~(1L << (val & 63));
  17. }
  18. }
  19. public boolean contains(int val) {
  20. if (((val + 64) >> 6) <= bits.length) {
  21. return (bits[val >> 6] & (1L << (val & 63))) != 0;
  22. }
  23. return false;
  24. }
  25. }

2 位运算实现加、减、乘、除

  1. /**
  2. * 用位运算实现加法
  3. *
  4. * @param num1 被加数num
  5. * @param num2 加数num
  6. * @return 返回两个加数的和
  7. */
  8. public int add(int num1, int num2) {
  9. int sum = num1;
  10. while (num2 != 0) {
  11. sum = num1 ^ num2;
  12. num2 = (num1 & num2) << 1;
  13. num1 = sum;
  14. }
  15. return sum;
  16. }
  17. /**
  18. * 用位运算实现2个数相减
  19. *
  20. * @param num1 被减数
  21. * @param num2 减数
  22. * @return 差
  23. */
  24. public int minus(int num1, int num2) {
  25. return add(num1, add(~num2, 1));
  26. }
  27. /**
  28. * 用位运算实现乘法
  29. *
  30. * @param num1 被乘数
  31. * @param num2 乘数
  32. * @return 乘积
  33. */
  34. public int multi(int num1, int num2) {
  35. int res = 0;
  36. while (num2 != 0) {
  37. if ((num2 & 1) != 0) {
  38. res = add(num1, res);
  39. }
  40. num1 = num1 << 1;
  41. num2 = num2 >>> 1;
  42. }
  43. return res;
  44. }
  45. /**
  46. * 用位运算实现除法
  47. *
  48. * @param num1 被除数
  49. * @param num2 除数
  50. * @return 商
  51. */
  52. public int div(int num1, int num2) {
  53. //当被除数、除数都为系统最小时,返回1
  54. if (num1 == Integer.MIN_VALUE && num2 == Integer.MIN_VALUE) {
  55. return 1;
  56. //当被除数不为系统最小,除数为系统最小时,返回0
  57. } else if (num2 == Integer.MIN_VALUE) {
  58. return 0;
  59. } else if (num1 == Integer.MIN_VALUE) {
  60. //当被除数为系统最小,除数为-1时,返回系统最大(理论为系统最大+1,
  61. // 但是没有系统最大+1的数,约定返回系统最大
  62. if (num2 == add(~1, 1)) {
  63. return Integer.MAX_VALUE;
  64. } else {
  65. int temp = division(add(num1, 1), num2);
  66. return add(temp, division(minus(num1, multi(temp, num2)), num2));
  67. }
  68. } else {
  69. return division(num1, num2);
  70. }
  71. }
  72. /**
  73. * 当被除数、除数不为系统最小时
  74. *
  75. * @param num1 被除数
  76. * @param num2 除数
  77. * @return 商
  78. */
  79. private int division(int num1, int num2) {
  80. int x = isNeg(num1) ? add(~num1, 1) : num1;
  81. int y = isNeg(num2) ? add(~num2, 1) : num2;
  82. int res = 0;
  83. for (int i = 30; i >= 0; i = minus(i, 1)) {
  84. if ((x >> i) >= y) {
  85. res |= (1 << i);
  86. x = minus(x, y << i);
  87. }
  88. }
  89. return isNeg(num1) ^ isNeg(num2) ? add(~res, 1) : res;
  90. }
  91. /**
  92. * 判断是否为负
  93. *
  94. * @param num 整数
  95. * @return 为负返回true
  96. */
  97. private boolean isNeg(int num) {
  98. return num < 0;
  99. }