c - 使用 c 和位移来解决特定需求

标签 c algorithm bit-shift

我有一个 16 个字母的字母表。给定一个句子,我想计算每个字母的频率,然后使用巧妙的位移将所有频率封装在一个数字中。让我们假设这些句子每个都是 100 个字母,并且假设没有字母出现超过 31 次,我想要这样的东西:

A: occurs 2 times -> 0010
B: occurs 10 times -> 1010
C: occurs 7 times -> 0111

等等。

现在,我想将这些连接起来: 001010100111...

我只是集中了上面的频率。为了方便地存储数字,我想将上面的二进制转换为 64 位无符号整数。

我的另一个要求是有这么长的时间并重新提取每个字母的频率。因此,我需要能够生成小数,然后将其解析为各个频率位。

我将如何在 c 中做到这一点?我可以对这些频率进行位移和相加,但这意味着我在重叠频率。另一个问题是在提取频率时,我怎么知道要移动多少位,因为尾随 0 是微不足道的并且不保存在小数中,但它们在我的算法中非常重要。

有什么好主意吗?谢谢。

最佳答案

你有两个问题:一个数学问题和一个编码问题。

让我们暂时忽略数学问题。您可以构建一个包含 16 个整数的数组,并在扫描文本时计算每个字母的出现次数。如果您假设没有一个字母出现超过 15 次,那么您不必担心溢出,您可以很容易地将计数放入 64 位整数中。你会写:

int counts[16];  // has the counts
unsigned long long freqs;  // this holds the encoded value

// after you compute the counts
freqs = 0;
for (int i = 0; i < 16; ++i)
{
    freqs <<= 4;
    freqs |= (counts[i] & 0xF);
}

此时,第一个字母的计数在 freqs 的前 4 位,最后一个字母的计数在后 4 位。所有其他计数都介于两者之间。每一个恰好占据 64 位数字的 4 位。

现在,如果您希望能够使用更大的文本执行此操作,或者一个字母出现的次数可能超过 15 次,则必须在计数后缩放数字,使最大值不超过 15。这就是数学原理我提到的问题。我想你可能会想出如何处理那个。您只需要缩放数字即可。

关于c - 使用 c 和位移来解决特定需求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17775529/

相关文章:

将 'space' 连接到数组的末尾

c++ - 按字典序升序对矩阵的行进行排序

algorithm - 加权无向图中的最长路径

c - 在 C 中提取整数(假设 32 位整数)中的 8 个半字节有哪些方法?

c - 使用套接字发送和接收文件

c - 读取数组时发生访问冲突

c++ - 为什么结构的 sizeof 不等于每个成员的 sizeof 之和?

javascript - 最长夜晚的最佳搜索算法 - Javascript

Java位移位结果为负数

c# - 把10位数和6位数写成short?