我有一个包含字符的向量。这些字符只能是字母表中的26个大写字母,因此表示这些字符的位数可以从8减少到5.然后我需要将结果写入文件,以便以后使用。
我目前的想法是A..Z的3个最高有效位都是相同的,因此我可以使用5个最低有效位来唯一地识别字符?但是我很难将这些未格式化的数据写入文件。
我将如何执行此操作并将结果写入文件?
答案 0 :(得分:1)
要将字符缩小为5位,您可以使用ch
& 0x1F
或ch - 'A'
;既不适用于EBCDIC,也不适用于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年代,它也是方式 太慢了。如果你的字符串相当短,今天可能是 足够。否则,你需要一个更复杂的 算法,跟踪已经使用了多少位 在最后一个字节中,并进行适当的移位和掩码 一次插入尽可能多的位:最多两次移位和 或每次插入的操作,而不是这里的情况。 这就是我最终使用的。 (但我没有代码 我不能轻易发布一个例子。)
答案 1 :(得分:0)
您可以使用的最小数据单位是8位。您将不得不采用位移,但您只能以8位为一组读取/写入数据,因此您需要额外的逻辑来处理它。如果您的输入至少有8个5位字母,则一次合并8个字母,使总共40位,并将其写入文件为5个8位字节。根据需要继续,直到剩下少于8个5位的字母,然后将它们合并在一起并将余数填充到8的偶数倍并将其写入文件。
答案 2 :(得分:0)
我有一个[chars]矢量,只能是26个大写字母
您可以相对轻松地编写代码:将文本拆分为八个字符的块,并将编码后的文本写入五个字节的块中,如下所示:
76543210 76543210 76543210 76543210 76543210 76543210 76543210 76543210
ORIGINAL: 000AAAAA 000BBBBB 000CCCCC 000DDDDD 000EEEEE 000FFFFF 000GGGGG 000HHHHH
76543210 76543210 76543210 76543210 76543210
ENCODED: AAAAABBB BBCCCCCD DDDDEEEE EFFFFFGG GGGHHHHH
如果您的最后一个块没有足够的字符,请使用“pad”字符(全部),这些字符不用于编码26个字母中的任何一个。
答案 3 :(得分:0)
我认为您只需使用gzip编写压缩文件就可以获得更多成功和轻松。
答案 4 :(得分:0)
您可以尝试使用我的PackedArray代码。
它实现了一个随机访问容器,其中项目在位级别打包。换句话说,它就像你能够操纵一个例如uint9_t
或uint17_t
数组:
PackedArray principle:
. compact storage of <= 32 bits items
. items are tightly packed into a buffer of uint32_t integers
PackedArray requirements:
. you must know in advance how many bits are needed to hold a single item
. you must know in advance how many items you want to store
. when packing, behavior is undefined if items have more than bitsPerItem bits
PackedArray general in memory representation:
|-------------------------------------------------- - - -
| b0 | b1 | b2 |
|-------------------------------------------------- - - -
| i0 | i1 | i2 | i3 | i4 | i5 | i6 | i7 | i8 | i9 |
|-------------------------------------------------- - - -
. items are tightly packed together
. several items end up inside the same buffer cell, e.g. i0, i1, i2
. some items span two buffer cells, e.g. i3, i6