关于bitset的实现

这算不算我的第一篇解题报告?虽然不是算法题。
原题:程序填空,实现一个类似于STL中bitset的MyBitset,输出指定结果。

#include <iostream>
#include <cstring>
using namespace std;
template <int bitNum>
struct MyBitset 
{
	char a[bitNum/8+1];
	MyBitset() { memset(a,0,sizeof(a));};
	void Set(int i,int v) {
		char & c = a[i/8];
		int bp = i % 8;
		if( v ) 
			c |= (1 << bp);
		else 
			c &= ~(1 << bp);
	}
// 在此处补充你的代码
void Print() {
		for(int i = 0;i < bitNum; ++i) 
			cout << (*this) [i];
		cout << endl;
	}

};

int main()
{
	int n;
	int i,j,k,v;
	while( cin >>  n) {
		MyBitset<20> bs;
		for(int i = 0;i < n; ++i) {
			int t;
			cin >> t;
			bs.Set(t,1);
		}
		bs.Print();
		cin >> i >> j >> k >> v;
		bs[k] = v;
		bs[i] = bs[j] = bs[k];
		bs.Print();
		cin >> i >> j >> k >> v;
		bs[k] = v;
		(bs[i] = bs[j]) = bs[k];
		bs.Print();
	}
	return 0;
}

输入
多组数据
每组数据:
第一行是整数 n , 1 <= n < 20;
第二行是n个整数 k1,k2… kn,均在范围 [0,19]内。
第三行是 四个整数 i1,j1,k1,v1 。 0 <= i1,j1,k1 <= 19, v1值为0或1
第三行是 四个整数 i2,j2,k2,v2 。 0 <= i2,j2,k2 <= 19, v2值为0或1
输出
对每组数据,共输出3行,每行20位,每位为1或者0。最左边称为第0位
第一行: 第 k1,k2 … kn位为1,其余位为0。
第二行: 将第一行中的第 i1,j1,k1位变为 v1,其余位不变
第三行: 将第二行中的第i2位和k2位变为v2,其余位不变

样例输入
4
0 1 2 8
7 19 0 1
7 2 8 0
1
1
1 1 1 0
1 1 1 1
样例输出
11100000100000000000
11100001100000000001
11100000000000000001
01000000000000000000
00000000000000000000
01000000000000000000
提示
推荐使用内部类,内部类中使用引用成员。引用成员要在构造函数中初始化。

我一开始纠结的点在哪里呢,我不知道怎么从char中取出某一位的引用。但是后来看了bitset的源代码才知道我傻逼在哪里。我们只要取出这个char数组中的某一个char,然后把position记录下来就可以了,到时候在其他函数当中通过位运算即可实现改变某一位的操作。实际上那个Set函数就是一个很好的提示。
然后第二个点是我在纠结是采用指针还是题目所述的引用。发现内部的reference类无法访问外部类的char数组。于是我就设置了一个p指针,让它指向内部类,把它强制转换为外部类的指针——当然是傻逼操作,因为内部类和外部类基本上没有什么逻辑上的联系,这和继承和派生有本质的区别。
后来参考了一份别人的代码才意识到这个问题,在reference的构造函数当中加了个参数,也就是MyBitset &p。重载[]的时候直接返回reference(position,*this)。
最后一个傻逼的点……debug了一个小时,就是我把所有函数的类型都习惯性地设置为reference &,导致在赋值的时候,=右边reference对象的position也被改成了=左边reference对象的position,这样就无法赋值。应该在重载=的时候返回reference对象的一个复制品,而不是它的引用。
似乎这些都是之前的知识当中的一些很基本的问题,但是没有勤于复习导致忘光了。
最后虽然写了好几个小时……但是一遍AC也是挺开心的。AC代码如下:

class reference {
	public:
		char *x;
		MyBitset *p;
		int pos;
		reference() {}
		reference (int i,MyBitset &p) {
			x = &(p.a[i / 8]);
			pos = i;
		}
		reference operator =(int v) {
			if (v)
				*x |= (1 << (pos % 8));
			else
				*x &= ~(1 << (pos % 8));
			return *this;
		}
		reference operator =(reference v) {
			int tmp = (((*v.x)&(1 << (v.pos % 8))) >> (v.pos % 8));
			if (tmp)
				*x |= (1 << (pos % 8));
			else
				*x &= ~(1 << (pos % 8));
			return *this;
		}
	};
	reference operator [](int i) {
		return reference(i,*this);
	}

	friend ostream & operator <<(ostream &cout, const reference &m) {
		int tmp = (((*m.x)&(1 << (m.pos % 8))) >> (m.pos % 8));
		cout << tmp;
		return cout;
	}

猜你喜欢

转载自blog.csdn.net/weixin_44288817/article/details/89430222