6

任意の長さの文字列から 128 ビットのデータ ブロックを操作する関数があります。文字列が 128 ビットのチャンクに均等に割り切れない場合は、それに応じてパディングされます。

目的は、関数に渡される文字列のデータを変換することです。

私は当初、次のような文字列をループすることを考えていました。

//This might have stupid errors.  Hopefully it stillg gets the point across.
for (int i = 0; i < strn.size(); i += 16)
{
    string block = strn.substr(i, i + 15);
    strn.replace(i, i + 15, block);
}

これでうまくいくと思いますが、これを行うにはもっとエレガントな方法が必要だと思います。頭に浮かんだ 1 つのアイデアstrnは、クラスにカプセル化し、その内容を 128 ビットのチャンクで読み取ることができる独自の反復子を実装することでした。これは魅力的です。コンストラクターがパディングを処理でき、現在使用している関数の一部を非公開にすることができるため、誤用の可能性を回避できます。これは実りあるアプローチのように思えますか? もしそうなら、どうやって自分のイテレータを実装するのですか? 私は C++ に非常に不慣れなので、詳細な説明は大歓迎です。

他の、おそらくより良いアプローチはありますか?

ありがとう!

4

2 に答える 2

3

多くのアプローチがあります。より単純で簡単なものの 1 つは次のようになります。正確に 128 ビットのサイズの独自の型を作成できます。シンプルstructに仕事をします。

typedef struct
{
    char buf[16];
} _128bit;

そして、それを使用して文字列を反復処理します。文字列の先頭をこの構造体型にキャスト_128bit* start = (_128bit*)buffer;し、整数ポインター演算を使用して反復処理を開始します。上のすべての操作startは、そのサイズに関して操作されます。たとえば、start++は 128 ビット前方に移動します。start--128 ビット戻します。目的の位置に到達したら、目的のタイプに再キャストし、操作を実行します。

于 2012-11-06T17:02:33.473 に答える
1

おそらく、独自の for ループを使用して、インデックスを作成するのではなく、イテレータを使用してこれを行うでしょう。

const int NUM_BITS_IN_CHUNK = 128;
const int CHUNK_SIZE = NUM_BITS_IN_CHUNK / CHAR_BIT;

for(std::string::const_iterator iter = str.begin(); iter < str.end(); iter += CHUNK_SIZE)
{
    your_func(iter, iter + CHUNK_SIZE);
}

boost::iterator_adaptor コードは次のようになります。この例では、わかりやすくするために、チャンクあたり 16 バイトではなく 4 バイトしか取得していないことに注意してください。

#include <iostream>
#include <string>

#include <boost/iterator_adaptors.hpp>

struct string_chunk_iterator : public boost::iterator_adaptor<string_chunk_iterator, std::string::const_iterator>
{
    string_chunk_iterator(const std::string::const_iterator& base) : iterator_adaptor(base) { }

private:
    friend class boost::iterator_core_access;
    void increment() { this->base_reference() = this->base() + 4; }
    void advance(typename iterator_adaptor::difference_type n)
    {
        this->base_reference() = this->base() + (4 * n);
    }
};

int main()
{
    const std::string tester(20, 'A');

    string_chunk_iterator iter(tester.begin());
    string_chunk_iterator str_end(tester.end());

    for(; iter != str_end; ++iter)
    {
        std::string chunk(&*iter, &*(iter + 1));

        std::cout << chunk << std::endl;
    }

    return 0;
}
于 2012-11-06T21:50:01.183 に答える