数组位操作

介绍

 

因为数组在内存中是一段连续的空间,所以数字的位连续起来,可以表示是一个超大的数字


例如这个样子,代表一个数字


 

位操作简介

 

左移运算符(<<)

腾出的位置用0填充,超出边界的位将被丢弃

 

右移运算符(>>)

对于无符号整数,腾出的位置用0填充,超出边界的位将被丢弃

对于有符号整数,腾出的位置用1填充,超出边界的位将被丢弃

 

非运算符(~)

0的位变1,1的位变0

 

与运算符(&)

000
010
100
111

 

 

 

 

或运算符(|)

000
011
101
111

 

 

 

 

异或运算符(^)

000
011
101
110

 

 

 

 


 

几种常用的按位操作运算符技术

 

打开位

num表示操作数,pos + 1表示操作数的第pos + 1位

1 num |= (1 << pos);
2 num = num | (1 << pos);

因为1和0同1做或运算得到1,所以打开了位。

而1和0同0做或运算得到其本身,所以对其他位无影响。

 

切换位

num表示操作数,pos + 1表示操作数的第pos + 1位

1 num ^= (1 << pos);
2 num = num ^ (1 << pos);

因为1与1做异或运算得到0,0与1做异或运算得到1,所以就把打开位关闭,把关闭位打开

而1和0同0做异或运算得到的其本身,所以对其他位无影响

 

关闭位

num表示操作数,pos + 1表示操作数的第pos + 1位

1 num &= ~(1 << pos);
2 num = num & ~(1 << pos);

因为1和0同0做与运算得到0,所以关闭了位

而1和0同1做与运算得到其本身,所以对其他位无影响

 

测试位(是否为1)

num表示操作数,pos + 1表示操作数的第pos + 1位

1 num & (1 << pos);

因为1和0同0做与运算得到0,所以除了第pos + 1位的其他所有为都被设置为0

而1和0同1做与运算得到其本身,所以,当第pos + 1位是1时,该表达式的值得到1,否则,得到0


 

以C++类来实现

 

我们需要设定几个函数

1 void set(int pos);    //把位置pos设置成1
2 void reset(int pos);    //将位置pos设置成0
3 int count() const;    //输出一共有多少个为1的位
4 bool test(int pos) const;    //位置pos是否是1
5 bool any() const;    //是否有是1的位
6 bool none() const;    //是否没有是1的位
7 bool all() const;    //是否所有位都是1

 

以下是类声明文件的代码,因为我们要实现的是数组位操作,所以需要完成运算符的重载

 1 #ifndef BITSET_H
 2 #define BITSET_H
 3 
 4 #include<iostream>
 5 class bitset {
 6 private:
 7     int* a;
 8     int size;
 9 public:
10     bitset(int s);
11     ~bitset();
12     void set(int pos);
13     void reset(int pos);
14     int count() const;
15     bool test(int pos) const;
16     bool any() const;
17     bool none() const;
18     bool all() const;
19 
20     bitset& operator&= (const bitset& b);
21     bitset& operator|= (const bitset& b);
22     bitset& operator^= (const bitset& b);
23     bitset& operator= (const bitset& b);
24     bitset& operator <<= (int pos);
25     bitset& operator >>= (int pos);
26     bitset operator~() const;
27     bitset operator&(const bitset& b) const;
28     bitset operator|(const bitset& b) const;
29     bitset operator^(const bitset& b) const;
30     bitset operator<<(int pos) const;
31     bitset operator>>(int pos) const;
32     bool operator== (const bitset& b) const;
33     bool operator!= (const bitset& b) const;
34     bool operator[] (int pos) const;
35     friend std::ostream& operator << (std::ostream& os, const bitset& s)
36 };
37 
38 #endif

 

 

 

接下来重点谈谈,左移与右移的重载

左移:

为了简化,我将以4位数字来代表一个整数

对此,我们进行左移,最直接的想法应该就是使用一个循环来让数组的每一个数都左移相同的pos吧

但是这么做会出现这样的情况,假如pos是1

左移后是

而实际上应该是

因此,我们在对a[i]移位后,要判断a[i - 1]的最左边的位是否为1,如果是1则需要将a[i]的最右边的位设定为1

 

右移:

同样为了简化,我将以4位数字来代表一个整数,并沿用上面的例子

最简单是思想还是使用一个循环来让数组的每一个数都右移相同的pos吧

但是这么做会出现这样的情况,假如pos是1

右移后是

而实际上应该是

因此,我们在对a[i]移位后,要判断a[i + 1]的最右边的位是否为1,如果是1则需要将a[i]的最左边的位设定为1,否则设定为0

 

至此,这个类最难的地方结束,下面是类定义文件的代码

  1 #include"Bitset.h"
  2 
  3 bitset::bitset(int s) : size(s) {
  4     a = new int[size];
  5     for (int i = 0; i < size; i++)
  6         a[i] = 0;
  7 }
  8 
  9 bitset::~bitset() {
 10     delete[] a;
 11     size = 0;
 12 }
 13 
 14 void bitset::set(int pos) {
 15     int x = pos / 32;
 16     int y = pos % 32;
 17     a[x] |= 1 << y;
 18 }
 19 
 20 void bitset::reset(int pos) {
 21     int x = pos / 32;
 22     int y = pos % 32;
 23     a[x] &= ~(1 << y);
 24 }
 25 
 26 int bitset::count() const {
 27     int sum = 0;
 28     for (int i = 0; i < 32 * size; i++)
 29         if (test(i)) sum++;
 30     return sum;
 31 }
 32 
 33 bool bitset::test(int pos) const {
 34     int x = pos / 32;
 35     int y = pos % 32;
 36     return (a[x] & (1 << y));
 37 }
 38 
 39 bool bitset::any() const {
 40     return count() > 0;
 41 }
 42 
 43 bool bitset::none() const {
 44     return count() == 0;
 45 }
 46 
 47 bool bitset::all() const {
 48     return count() == 32 * size;
 49 }
 50 
 51 bitset& bitset::operator&= (const bitset& b) {
 52     for (int i = 0; i < size; i++) a[i] &= b.a[i];
 53     return *this;
 54 }
 55 
 56 bitset& bitset::operator|= (const bitset& b) {
 57     for (int i = 0; i < size; i++) a[i] |= b.a[i];
 58     return *this;
 59 }
 60 
 61 bitset& bitset::operator^= (const bitset& b) {
 62     for (int i = 0; i < size; i++) a[i] ^= b.a[i];
 63     return *this;
 64 }
 65 
 66 bitset& bitset::operator <<= (int pos) {
 67     while (pos--) {
 68         for (int i = size - 1; i >= 0; i--) {
 69             a[i] <<= 1;
 70             if (i != 0) {
 71                 if (a[i - 1] & (1 << 31))
 72                     a[i] |= 1;
 73             }
 74         }
 75     }
 76     return *this;
 77 }
 78 
 79 bitset& bitset::operator>>= (int pos) {
 80     while (pos--) {
 81         for (int i = 0; i < size; i++) {
 82             a[i] >>= 1;
 83             if (i != size - 1) {
 84                 if (a[i + 1] & 1)
 85                     a[i] |= 1 << 31;
 86                 else
 87                     a[i] &= ~(1 << 31);
 88             }
 89         }
 90     }
 91     return *this;
 92 }
 93 
 94 bitset& bitset::operator= (const bitset& b) {
 95     for (int i = 0; i < size; i++) a[i] = b.a[i];
 96     return *this;
 97 }
 98 
 99 bitset bitset::operator~() const {
100     bitset s;
101     for (int i = 0; i < size; i++) s.a[i] = ~a[i];
102     return s;
103 }
104 
105 bitset bitset::operator& (const bitset& b) const {
106     bitset s;
107     s = *this;
108     return s &= b;
109 }
110 
111 bitset bitset::operator| (const bitset& b) const {
112     bitset s;
113     s = *this;
114     return s |= b;
115 }
116 
117 bitset bitset::operator^ (const bitset& b) const {
118     bitset s;
119     s = *this;
120     return s ^= b;
121 }
122 
123 bitset bitset::operator << (int pos) const {
124     bitset s;
125     s = *this;
126     return s <<= pos;
127 }
128 
129 bitset bitset::operator >> (int pos) const {
130     bitset s;
131     s = *this;
132     return s >>= pos;
133 }
134 
135 bool bitset::operator== (const bitset& b) const {
136     for (int i = 0; i < size; i++)
137         if (a[i] != b.a[i]) return false;
138     return true;
139 }
140 
141 bool bitset::operator!= (const bitset& b) const {
142     for (int i = 0; i < size; i++)
143         if (a[i] != b.a[i]) return true;
144     return false;
145 }
146 
147 bool bitset::operator[] (int pos) const {
148     return test(pos);
149 }
150 
151 std::ostream& operator << (std::ostream& os, const bitset& s) {
152     for (int i = s.size - 1; i >= 0; i--) {
153         for (int j = 31; j >= 0; j--) {
154             if (s.a[i] & (1 << j)) os << 1;
155             else os << 0;
156         }
157     }
158     return os;
159 }

 

转载于:https://www.cnblogs.com/alan23/p/5285907.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值