1

Shannon-Fano コーディング アルゴリズムを実装しており、シンボル コードをビットとして出力したいと考えています。

たとえば、次のコードでは、入力ファイル (ストリーム) からシンボルを 1 行ずつ読み取り、アルゴリズムによって形成された(からの) シンボル コードfinで を埋めてから、 の内容で を構築します。次に、ビットセットを出力しようとしましたが、出力ファイルでは、ビットセットの「true」または「false」の各値が 1 ビットではなく 1 バイトを占めます。std::stringstd::map<unsigned short, std::string> symbolCodesboost::dynamic_bitsetcurrentOutString

if (fin.is_open() && fout.is_open()) {
    std::string currentInString;
    std::string currentOutString;

    while (getline(fin, currentInString)) {
        boost::dynamic_bitset<> bitSet;
        for (auto & ref : currentInString) {
            currentOutString += symbolCodes[ref];
        }

        for (auto & ref : currentOutString) {
            if (ref == '0') bitSet.push_back(0);
            if (ref == '1') bitSet.push_back(1);
        }
        fout << bitSet;

        bitSet.clear();
        currentOutString.erase();
    }
}

foutストリームはstd::ios_base::binaryモードで開かれます。たとえば、「ファイル」という単語があり、コードはe: 00, f: 01, i: 10, l: 11. ビットセットを出力して、出力ファイルが 8 バイトではなく 8 ビットを占めるようにするにはどうすればよいですか?

ご協力いただきありがとうございます。言葉の間違いの可能性があることをお詫び申し上げます。

4

1 に答える 1

2

これは実際にはdynamic_bitsetのせいではありません。のiostreamです。

次のコードが出力されます

123
----.

cout:

#include <iostream>
#include <boost/dynamic_bitset.hpp>

int main() {
    using namespace std;
    using namespace boost;

    auto bitset = dynamic_bitset<>(32, 0x0a333231); // "123\n" in little endian
    bitset.append(0x2d2d2d2d); // "----"
    bitset.append(0x0a2e); // ".\n"
    // bitset.size() is at least 96 here

    auto ulong_mask = dynamic_bitset<>(bitset.size(), 0xFFFFFFFFul);
    while(bitset.any()) {
        unsigned long ulong = (bitset & ulong_mask).to_ulong();
        cout.write(reinterpret_cast<char*>(&ulong), sizeof(ulong));

        bitset >>= 32;
    }
}

cout.write()の代わりに を使用していることに注意してくださいoperator <<。書式設定やASCII文字列への変換なしで、バイトをそのままitoa()出力します(または同様のものを考えてください)。


もう 1 点:dynamic_bitsetは連続したストレージの保証やアクセスを提供しないため、できればより大きなサイズのチャンクごとに大きなビットセットを読み取る必要があります。例えばunsigned long

一部のアーキテクチャでsizeof(unsigned long)は 8 になるため、実際にはより大きな値を使用してulong_mask(ULONG_MAXそうする必要があります)、それに応じてシフトすることができ(8 * sizeof(unsigned long))ます。それを使用します。(上記の 32 は、図をわかりやすくするためにハードコードされています)。

于 2013-09-29T14:57:15.607 に答える