关于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;}

本文链接:https://my.lmcjl.com/post/3754.html

展开阅读全文

4 评论

留下您的评论.