C++のbitset(ビットセット)に関する興味深い事実
C++の標準テンプレートライブラリ(STL)には、bitsetというコンテナが定義されています。bitsetは、変数の各ビット(0と1)単位で直接操作を行うためのコンテナで、値をバイナリ表現として扱いたい場面で活躍します。ここでは、bitsetについて知っておくと便利な特徴を3つ紹介します。
1. bitsetは文字列のように扱える
bitsetは、0と1のみを有効な値とするビットのコンテナです。開始インデックスと要素数を指定すれば、既存のbitsetの一部を使って新しいbitsetを作成し、末尾に連結することもできます。
たとえば、ビット列「01001110」のインデックス2から4要素を取り出すと「0011」が得られ、これをbitsetの末尾に追加します。この方法で定義される8ビットのbitsetの値は「00000011」になります。
コード例
#include <bitset>
#include <string>
#include <iostream>
int main() {
std::string bit_string = "10010110";
std::bitset<8> b1(bit_string, 1, 4);
std::cout << b1 << '\n';
return 0;
}
出力結果
00000010
2. 文字列からbitsetを構築する
0と1以外の文字でも、2種類の文字だけで構成された文字列なら、bitsetに変換できます。どの文字を0、どの文字を1として解釈するかを指定できるのがポイントです。
たとえば「xyxxyyx」という文字列があるとき、x=0、y=1と対応付ければ、同じ長さのbitset「0100110」を作成できます。
この処理には、次のようなコンストラクタが用意されています。
bitset(str, offSet, size, zeroVal, oneVal);
各パラメータの意味は以下の通りです。
- str:bitsetの作成元となる文字列
- offSet:文字列の読み込み開始位置(インデックス)
- size:作成するbitsetのサイズ
- zeroVal:0として扱う文字
- oneVal:1として扱う文字
コード例
#include <bitset>
#include <string>
#include <iostream>
using namespace std;
int main() {
string bitstr = "xyxxyyyx";
bitset<8> bits(bitstr, 0, bitstr.size(), 'x', 'y');
cout << "bitsetの値 : " << bits << '\n';
}
出力結果
bitsetの値 : 01001110
3. bitsetを文字列に変換する
bitsetには、bitsetを文字列へ変換するためのto_string()関数が用意されています。生成される文字列の長さはbitsetの長さと同一で、要素の並び順もbitsetと同じです。つまり、bitsetの先頭の要素が文字列の先頭の文字になります。
たとえば、bitset「01010100」を文字列に変換すると「01010100」が得られます。
さらに、引数で任意の2文字を指定すれば、0と1を別の文字に置き換えて出力することも可能です。これは、文字列からbitsetを構築する処理のちょうど逆にあたります。
コード例
#include <iostream>
#include <bitset>
using namespace std;
int main() {
bitset<8> b(19);
cout << "bitsetの値 : " << b << endl;
cout << "bitsetの文字列変換結果 : " << b.to_string() << endl;
cout << "0をT、1をPに置き換えた文字列変換結果 : ";
cout << b.to_string('T', 'P') << endl;
}
出力結果
bitsetの値 : 00010011 bitsetの文字列変換結果 : 00010011 0をT、1をPに置き換えた文字列変換結果 : TTTPTTPP
bitsetには、ここで紹介した以外にもさまざまな操作が用意されており、AND・OR・XORなどのビット演算子もそのまま利用できます。まずは本記事で紹介した基本機能と性質をしっかり押さえておくとよいでしょう。
-
C++で文字列をトークン化する方法:stringstreamとgetline()による分割テクニック
この記事では、C++における文字列のトークン化(分割)の方法について解説します。C言語では、文字配列に対してstrtok()関数を使用することで文字列を分割できましたが、C++ではstd::stringクラスを扱うため、少し異なるアプローチが必要です。C++の機能を活用して文字列を分割するには、まずstd::stringをstringstream(文字列ストリーム)に変換します。その後、getline()関数を使うことで、指定した区切り文字(デリミタ)ごとに文字列を切り出すことができます。getline()関数は、以下の3つの引数を受け取ります。入力元となる文字列ストリーム出力結果を格納する文
-
C++で文字列をトークン化(分割)する2つの方法を解説
文字列のトークン化(分割)とは、1つの文字列を区切り文字(スペースやカンマなど)を基準に、複数の部分文字列へ分割する処理のことです。C++では、標準ライブラリだけでもいくつかの方法で実現できます。本記事では、代表的な2つの方法をサンプルコード付きで紹介します。方法1:stringstreamを使って空白で分割する1つ目の方法は、stringstreamを使ってスペースで区切られた単語を順に読み取る方法です。この方法はやや制限がありますが、適切なチェックを加えれば十分に目的を果たすことができます。サンプルコード#include <vector> #include <string