我有一个包含字符的向量。这些字符只能是字母表中的26个大写字母,因此代表这些字符的位数可以从8减少到5。然后,我需要将结果写入文件中,以备后用。

我目前的想法是A..Z的3个最高有效位都相同,因此我可以使用5个最低有效位来唯一标识字符吗?但是,我正在努力将此未格式化的数据写入文件。

我将如何执行此操作并将结果写入文件?

最佳答案

要将字符减少到5位,可以使用ch& 0x1Fch - 'A';两者都不能与EBCDIC一起使用,但这就是
可能不是问题。 (如果是这样的话:
可以使用返回索引的所有大写字母。)

之后,它变得复杂。最简单的解决方案是
定义一个位数组,类似于:

class BitArray
{
    std::vector<unsigned char> myData;
    int byteIndex( int index ) { return index / 8; }
    unsigned char bitMask( int index ) { return 1 << (index % 8); }
    int byteCount( int bitCount )
    {
        return byteIndex( bitCount )
            + (bitIndex( bitCount) != 0 ? 1 : 0);
    }
public:
    BitArray( int size ) : myData( byteCount( size ) ) {}
    void set( index )
    {
        myData[byteIndex( index )] |= bitMask( index );
    }
    void reset( index )
    {
        myData[byteIndex( index )] &= ~bitMask( index );
    }
    bool test( index )
    {
        return (myData[byteIndex( index ) & bitMask( index )) != 0;
    }
};


(您将需要更多来提取数据,但是我不确定
格式化您需要的格式。)

然后,您遍历您的字符串:

BitArray results( 5 * s.size() );
for ( int index = 0; index != s.size(); ++ index ) {
    for ( int pos = 0; pos != 5; ++ pos ) {
        results.set( 5 * index + pos );
    }
}


这将正常工作。当我尝试使用它(或
相当遥远的过去(对霍夫曼来说)
用C编码,因为这是在1980年代),这也是
太慢了。如果您的琴弦很短,今天可能是
足够。否则,您将需要更复杂的
算法,跟踪已使用的位数
在最后一个字节中,并进行适当的移位和屏蔽
一次插入尽可能多的位:最多两次移位和
或每次插入操作,而不是这里的5。
这就是我最终使用的。 (但我没有代码
,所以我不能轻易发布示例。)

关于c++ - 将char打包为5位并将结果写入文件(C++),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23394733/

10-11 15:51