前几天干了一件比较无聊的事儿——抄了一遍C++ STL bitset的源代码,把不懂的宏定义去掉了,发现(暂时)还能用,嘿嘿。

#ifndef BITSET_H
#define BITSET_H
#include <string>
#include <stdexcept>
#include <iostream> template <size_t Bits>
class BitSet {
public:
typedef bool element_type;
typedef unsigned int Type; class Reference {
friend class BitSet<Bits>;
public:
~Reference() {} Reference& operator=(bool val) {
p->set(pos, val);
return *this;
} Reference& operator=(const Reference& bitRef) {
p->set(pos, bool(bitRef));
return *this;
} Reference& flip() {
p->flip(pos);
return *this;
} bool operator~() const {
return !p->test(pos);
} operator bool() const {
return p->test(pos);
} private:
Reference() : p(0), pos(0) {} Reference(BitSet<Bits>& bitSet, size_t pos) : p(&bitSet), pos(pos) {} BitSet<Bits> *p;
size_t pos;
}; bool at(size_t pos) const {
return test(pos);
} Reference at(size_t pos) {
return Reference(*this, pos);
} bool operator[](size_t pos) const {
return test(pos);
} Reference operator[](size_t pos) {
return Reference(*this, pos);
} BitSet() {
tidy();
} BitSet(unsigned long long val) {
tidy();
for (size_t pos = 0; val != 0 && pos < Bits; val >>= 1, ++pos) {
if (val & 1)
set(pos);
}
} BitSet(const std::string& str,
std::string::size_type pos = 0,
std::string::size_type count = std::string::npos,
char e0 = '0',
char e1 = '1') {
construct(str, pos, count, e0, e1);
} BitSet(const char *ptr,
std::string::size_type count = std::string::npos,
char e0 = '0',
char e1 = '1') {
construct(count == std::string::npos ?
std::string(ptr) : std::string(ptr, count), 0, count, e0, e1);
} void construct(const std::string& str,
std::string::size_type pos,
std::string::size_type count,
char e0,
char e1) {
std::string::size_type num;
if (str.size() < pos)
xran();
if (str.size() - pos < count)
count = str.size() - pos;
if (Bits < count)
count = Bits;
tidy(); for (pos += count, num = 0; num < count; ++num) {
if (str[--pos] == e1)
set(num);
else if (str[pos] != e0)
xinv();
}
} BitSet<Bits>& operator&=(const BitSet<Bits>& right) {
for (ptrdiff_t pos = Words; 0 <= pos; --pos) {
array[pos] &= right.getWord(pos);
}
return *this;
} BitSet<Bits>& operator|=(const BitSet<Bits>& right) {
for (ptrdiff_t pos = Words; 0 <= pos; --pos) {
array[pos] |= right.getWord(pos);
}
return *this;
} BitSet<Bits>& operator^=(const BitSet<Bits>& right) {
for (ptrdiff_t pos = Words; 0 <= pos; --pos) {
array[pos] ^= right.getWord(pos);
}
return *this;
} BitSet<Bits>& operator<<=(size_t pos) {
const ptrdiff_t wordShift = (ptrdiff_t)(pos / BitsPerWord);
if (wordShift != 0) {
for (ptrdiff_t wpos = Words; 0 <= wpos; --wpos)
array[wpos] = (wordShift <= wpos ?
array[wpos - wordShift] : 0);
}
if ((pos %= BitsPerWord) != 0) {
// 0 < pos < BitsPerWord, shift by bits
for (ptrdiff_t wpos = Words; 0 < wpos; --wpos)
array[wpos] = (Type)((array[wpos] << pos) |
(array[wpos - 1]) >> (BitsPerWord - pos));
array[0] <<= pos;
}
trim();
return *this;
} BitSet<Bits>& operator>>=(size_t pos) {
const ptrdiff_t wordShift = (ptrdiff_t)(pos / BitsPerWord);
if (wordShift != 0) {
for (ptrdiff_t wpos = 0; wpos <= Words; ++wpos)
array[wpos] =
(wordShift <= Words - wpos ? array[wpos + wordShift] : 0);
}
if ((pos %= BitsPerWord) != 0) {
for (ptrdiff_t wpos = 0; wpos < Words; ++wpos)
array[wpos] = (Type)((array[wpos] >> pos) |
(array[wpos + 1] << (BitsPerWord - pos)));
array[Words] >>= pos;
}
return *this;
} BitSet<Bits>& set() {
tidy((Type)~0);
return *this;
} BitSet<Bits>& set(size_t pos, bool val = true) {
if (Bits <= pos)
xran();
if (val)
array[pos / BitsPerWord] |= (Type)1 << pos % BitsPerWord;
else
array[pos / BitsPerWord] &= ~((Type)1 << pos % BitsPerWord);
return *this;
} BitSet<Bits>& reset() {
tidy();
return *this;
} BitSet<Bits>& reset(size_t pos) {
return set(pos, false);
} BitSet<Bits>& operator~() const {
return BitSet<Bits>(*this).flip();
} BitSet<Bits>& flip() {
for (ptrdiff_t pos = Words; 0 <= pos; --pos)
array[pos] = (Type)~array[pos];
trim();
return *this;
} BitSet<Bits>& flip(size_t pos) {
if (Bits <= pos)
xran();
array[pos / BitsPerWord] ^= (Type)1 << pos % BitsPerWord;
return *this;
} unsigned long to_ulong() const {
unsigned long long val = to_ullong();
unsigned long ans = (unsigned long)val;
if (ans != val)
xofllo();
return ans;
} unsigned long long to_ullong() const {
ptrdiff_t pos = Words;
for (; (ptrdiff_t)(sizeof(unsigned long long) / sizeof(Type)) <= pos; --pos) {
if (array[pos] != 0)
xofllo();
}
unsigned long long val = array[pos];
while (0 <= --pos)
val = ((val << (BitsPerWord - 1)) << 1) | array[pos];
return val;
} std::string to_string(char e0 = '0', char e1 = '1') const {
std::string str;
str.reserve(Bits);
std::string::size_type pos = Bits;
while (0 < pos) {
if (test(--pos))
str += e1;
else
str += e0;
}
return str;
} size_t count() const {
const char *const BitsPerByte =
"\0\1\1\2\1\2\2\3\1\2\2\3\2\3\3\4"
"\1\2\2\3\2\3\3\4\2\3\3\4\3\4\4\5"
"\1\2\2\3\2\3\3\4\2\3\3\4\3\4\4\5"
"\2\3\3\4\3\4\4\5\3\4\4\5\4\5\5\6"
"\1\2\2\3\2\3\3\4\2\3\3\4\3\4\4\5"
"\2\3\3\4\3\4\4\5\3\4\4\5\4\5\5\6"
"\2\3\3\4\3\4\4\5\3\4\4\5\4\5\5\6"
"\3\4\4\5\4\5\5\6\4\5\5\6\5\6\6\7"
"\1\2\2\3\2\3\3\4\2\3\3\4\3\4\4\5"
"\2\3\3\4\3\4\4\5\3\4\4\5\4\5\5\6"
"\2\3\3\4\3\4\4\5\3\4\4\5\4\5\5\6"
"\3\4\4\5\4\5\5\6\4\5\5\6\5\6\6\7"
"\2\3\3\4\3\4\4\5\3\4\4\5\4\5\5\6"
"\3\4\4\5\4\5\5\6\4\5\5\6\5\6\6\7"
"\3\4\4\5\4\5\5\6\4\5\5\6\5\6\6\7"
"\4\5\5\6\5\6\6\7\5\6\6\7\6\7\7\x8";
const unsigned char *ptr = (const unsigned char *)(const void *)array;
const unsigned char *const end = ptr + sizeof(array);
size_t val = 0;
for (; ptr != end; ++ptr)
val += BitsPerByte[*ptr];
return val;
} size_t size() const {
return Bits;
} bool operator==(const BitSet<Bits>& right) const {
for (ptrdiff_t pos = Words; 0 <= pos; --pos) {
if (array[pos] != right.getWord(pos))
return false;
}
return true;
} bool operator!=(const BitSet<Bits>& right) const {
return !(*this == right);
} bool test(size_t pos) const {
if (Bits < pos)
xran();
return (array[pos / BitsPerWord] & ((Type)1 << pos % BitsPerWord)) != 0;
} bool any() const {
for (ptrdiff_t pos = Words; 0 <= pos; --pos) {
if (array[pos] != 0)
return true;
}
return false;
} bool none() const {
return !any();
} bool all() const {
return count() == size();
} BitSet<Bits> operator<<(size_t pos) const {
return BitSet<Bits>(*this) <<= pos;
} BitSet<Bits> operator>>(size_t pos) const {
return BitSet<Bits>(*this) >>= pos;
} Type getWord(size_t pos) const {
return array[pos];
} private:
static const ptrdiff_t BitsPerWord = (ptrdiff_t)(CHAR_BIT * sizeof(Type));
static const ptrdiff_t Words =
(ptrdiff_t)(Bits == 0 ? 0 : (Bits - 1) / BitsPerWord); void tidy(Type val = 0) {
for (ptrdiff_t pos = Words; 0 <= pos; --pos)
array[pos] = val;
if (val != 0)
trim();
} void trim() {
if (Bits % BitsPerWord != 0)
array[Words] &= ((Type)1 << Bits % BitsPerWord) - 1;
} void xinv() const {
throw std::invalid_argument("invalid BitSet<N> char");
} void xofllo() const {
throw std::overflow_error("BitSet<N> overflow");
} void xran() const {
throw std::out_of_range("invalid BitSet<N> position");
} Type array[Words + 1];
}; template<size_t Bits>
BitSet<Bits> operator&(const BitSet<Bits>& left, const BitSet<Bits>& right) {
BitSet<Bits> ans = left;
return ans &= right;
} template<size_t Bits>
BitSet<Bits> operator|(const BitSet<Bits>& left, const BitSet<Bits>& right) {
BitSet<Bits> ans = left;
return ans |= right;
} template<size_t Bits>
BitSet<Bits> operator^(const BitSet<Bits>& left, const BitSet<Bits>& right) {
BitSet<Bits> ans = left;
return ans ^= right;
} template<size_t Bits>
std::ostream& operator<<(std::ostream& os, const BitSet<Bits>& right) {
return os << right.to_string();
} template<size_t Bits>
std::istream& operator>>(std::istream& is, BitSet<Bits>& right) {
char e1 = '1';
char e0 = '0';
std::ios_base::iostate state = std::ios_base::goodbit;
bool changed = false;
std::string str;
const std::istream::sentry ok(is); if (ok) {
try {
int meta = is.rdbuf()->sgetc();
for (size_t count = right.size();
0 < count;
meta = is.rdbuf()->snextc(), --count) {
char c;
if (meta == EOF) {
state |= std::ios_base::eofbit;
break;
}
else if ((c = (char)meta) != e0 && c != e1)
break;
else if (str.max_size() <= str.size()) {
state |= std::ios_base::failbit;
break;
}
else {
if (c == e1)
str.append(1, '1');
else
str.append(1, '0');
changed = true;
}
}
}
catch (...) {
is.setstate(std::ios_base::badbit, true);
}
}
if (!changed)
state |= std::ios_base::failbit;
is.setstate(state);
right = BitSet<Bits>(str);
return is;
} #endif

BitSet的更多相关文章

  1. strtok源码 bitset 空间压缩

    源代码里有一段: unsigned char map[32]; /* Clear control map */ for (count = 0; count < 32; count++) map[ ...

  2. DFS序+线段树+bitset CF 620E New Year Tree(圣诞树)

    题目链接 题意: 一棵以1为根的树,树上每个节点有颜色标记(<=60),有两种操作: 1. 可以把某个节点的子树的节点(包括本身)都改成某种颜色 2. 查询某个节点的子树上(包括本身)有多少个不 ...

  3. 把《c++ primer》读薄(3-3 标准库bitset类型)

    督促读书,总结精华,提炼笔记,抛砖引玉,有不合适的地方,欢迎留言指正. //开头 #include <bitset> using std::bitset; 问题1.标准库bitset类型( ...

  4. BitSet构造函数的两种特例

    C++11之后,bitset的构造函数新加了两种形式: bitset<bits>::bitset (const string& str, string::size_type str ...

  5. Bitset<>用于unordered container时的默认hash函数

    自从c++11起,bitset用于unordered container,将会提供默认的hash函数. 在gcc中,相关代码如下: // DR 1182. /// std::hash speciali ...

  6. hdu 4920 Matrix multiplication bitset优化常数

    Matrix multiplication Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/ ...

  7. hdu 5506 GT and set dfs+bitset优化

    GT and set Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Probl ...

  8. (DFS、bitset)AOJ-0525 Osenbei

    题目地址 简要题意: 给出n行m列的0.1矩阵,每次操作可以将任意一行或一列反转,即这一行或一列中0变为1,1变为0.问通过任意多次这样的变换,最多可以使矩阵中有多少个1. 思路分析: 行数比较小,先 ...

  9. Gym 100917J---Judgement(01背包+bitset)

    题目链接 http://codeforces.com/gym/100917/problem/J Description standard input/outputStatements The jury ...

  10. C++二进制文件中读写bitset

    这个比较简单,直接上代码: bitset< > *b = >(); bitset< > *c = >(); ofstream out("I:\\test. ...

随机推荐

  1. 开发一个struts2的实例

    前面一篇博客(实现struts2框架)带大家对基于mvc业务流程熟悉了一下,现在我们就用对mvc实现最好的框架struts2来开发一个应用实例.虽然现在MyEclipse8.5以上版本已经开始支持St ...

  2. 移植最新u-boot(裁剪和修改默认参数)之韦东山笔记

    1.下载.建立source insight工程.编译.烧写.如果无运行分析原因 tar xjf u-boot-2012.04.01.tar.bz2 cd u-boot-2012.04.01 make ...

  3. 类、对象以及jvm运行内存解析

    一.JVM内存的分析: 第一步:存放在硬盘上的程序首先要被加载到内存空间中. 第二步:内存中的jvm找到程序中main函数作为入口,然后开始执行. 第三步:执行过程中的内存管理:内存分为四个部分: 栈 ...

  4. [改善Java代码] 枚举项数量限定为64个以内

    建议89:枚举项的数量限制在64个以内 为了更好的使用枚举,java 提供了两个枚举集合:EnumSet和EnumMap,这两个集合的使用都比较简单,EnumSet表示其元素必须是某一枚举的枚举项,E ...

  5. poj 3278 Catch That Cow 优化深搜

    这题的思想很简单,就是每次找出队列里面花费时间最少的来走下一步,这样当我们找到k点后,所花费的时间一定是最少的. 但要用一个标记数组vis[200010],用来标记是否走过.否则会内存溢出. #inc ...

  6. kettle学习-day1-介绍、下载、安装

    QQ群:306059317\ 技术支持:荷露叮咚网络学苑http://www.heludd.com/kettle 下载最新版,获取视频教程 kettle安装: 1).下载需要安装的kettle版本,官 ...

  7. 备忘====[HttpPost]和[AcceptVerbs(HttpVerbs.Post)]区别

    1.共同点:[HttpPost]和[AcceptVerbs(HttpVerbs.Post)]都是只接受POST请求过来的数据. 2.不同点:在MVC中如果想一个action既可以回应POST请求也可以 ...

  8. jQuery选项卡插件、Tabs插件

    效果图: <!DOCTYPE html> <html> <head> <title></title> <script src=&quo ...

  9. jQuery概述,代码举例及最新版下载

    jQuery是一个快速的,小巧的,具有强大功能的JavaScript库. 它的基本功能包括: 1)访问和操作DOM元素 2)控制页面样式(可以兼容各种浏览器) 3)对页面事件的处理 4)大量插件在页面 ...

  10. android自学笔记(1):android简介

    Android是一种基于Linux的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由Google公司和开放手机联盟领导及开发.尚未有统一中文名称,中国大陆地区较 多人使用“安卓 ...