- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在进行霍夫曼编码,但我无法理解如何使用 fwrite() 将我们的编码写入输出。
假设我有这些编码:
Character A (65) gets an encoding of 101
Character B (66) gets an encoding of 1100111
但是,这些编码被保存为整数,所以
101 actually has a decimal value of 5 which is saved in memory as 00000101
1100111 actually has a decimal value of 103 which is saved in memory as 01100111
因此,当我们想使用 fwrite() 将它们写出时,假设我们使用缓冲区
int buff[4]
开始于
buff[0] buff[1] buff[2] buff[3]
XXXXXXXX - XXXXXXXX - XXXXXXXX - XXXXXXXX
(用X表示未初始化)为什么要用4个字节?因为我们需要考虑非常长的编码。如果我们有一个 27 位长的编码呢?我们需要完全填充其中的三个字节和第四个字节。
现在,假设我们需要对这一系列字符进行编码并将它们写入输出文件:
“ABB”
首先,我们对 A 进行编码,我们的 buff[] 应该变成:
buff[0] buff[1] buff[2] buff[3]
101XXXXX - XXXXXXXX - XXXXXXXX - XXXXXXXX
然后,我们需要对 B 进行编码,所以我们的 buff[] 应该变成:
buff[0] buff[1] buff[2] buff[3]
10111001 - 11XXXXXX - XXXXXXXX - XXXXXXXX
现在,buff[] 的一个字节已满,因此我们需要对该字节进行编码并将 buff[] 的其他槽向下移动
fwrite(buff[0], 1, 1, fptOutput);
/* insert code to shift buff down */
所以现在我们的 buff 变成了:
buff[0] buff[1] buff[2] buff[3]
11XXXXXX - XXXXXXXX - XXXXXXXX - XXXXXXXX
接下来,我们编码另一个“B”,我们的 buff[] 变成:
buff[0] buff[1] buff[2] buff[3]
11110011 - 1XXXXXXX - XXXXXXXX - XXXXXXXX
然后,我们再次 fwrite() buff[0] 并再次进行移位。
但是,我们没有其他任何东西要编码,所以我们必须用 0 填充剩余的字节,所以我们的 buff 现在是:
buff[0] buff[1] buff[2] buff[3]
10000000 - XXXXXXXX - XXXXXXXX - XXXXXXXX
然后 fwrite 最后一个字节,然后我们就完成了。
问题是我完全不知道如何系统地编程。我了解位操作。例如,在我们的第一个“A”编码中,我们需要将“00000101”向左移动 5 个位置,使其变为“101-----”,我理解这一步,但我不知道如何跟踪将我们的下一个编码转移到哪里。
如果我手动操作,我可以弄清楚如何根据需要移动每个变量,但我不知道如何提出一系列方程式,这些方程式适用于一个系列中的每个编码系列很长的文件。
最佳答案
您需要存储每个字符的编码数组以及每个字符编码中的位数数组,因为它们都是不同的。
然后您需要跟踪 buff 数组中还剩下多少位。
然后每次你想添加一个字符时,你都将该字符编码复制到另一个临时缓冲区中。然后你将该编码向上移动 buff 数组中已经留下的位数。然后你按位或将你的移位编码放到你的 buff 数组上。
然后您从 buff 数组中写入数据并将剩余的 buff 数据向下移动并调整 buff 数组中剩余的位数。
以下是一个将 16 位整数(短整数)数组按位向上或向下移动的函数。这有点矫枉过正,因为它会向上或向下移动位。您可以修改它以处理字节或长整数:
void
shiftBits(unsigned short int *buffer, int bufferSize, int bitsToShiftUp)
{
int wordsToShift;
int bitsToShift;
int backBitsToShift;
int iTo;
int iFrom;
if (bitsToShiftUp > 0)
{
//Shift up
wordsToShift = bitsToShiftUp / 16;
bitsToShift = bitsToShiftUp - (wordsToShift * 16);
iTo = bufferSize - 1;
iFrom = iTo - wordsToShift;
if (bitsToShift == 0)
{
while (iFrom >= 0)
{
buffer[iTo] = buffer[iFrom];
iTo--;
iFrom--;
}
while (iTo >= 0)
{
buffer[iTo] = 0;
iTo--;
}
}
else
{
backBitsToShift = 16 - bitsToShift;
while (iFrom >= 1)
{
buffer[iTo] = (buffer[iFrom] << bitsToShift) | (buffer[iFrom-1] >> backBitsToShift);
iTo--;
iFrom--;
}
if (iFrom >= 0)
{
buffer[iTo] = buffer[iFrom] << bitsToShift;
iTo--;
}
while (iTo >= 0)
{
buffer[iTo] = 0;
iTo--;
}
}
}
else if (bitsToShiftUp < 0)
{
//Shift down
wordsToShift = (-bitsToShiftUp) / 16;
bitsToShift = (-bitsToShiftUp) - (wordsToShift * 16);
iTo = 0;
iFrom = wordsToShift;
if (bitsToShift == 0)
{
while (iFrom < bufferSize)
{
buffer[iTo] = buffer[iFrom];
iTo++;
iFrom++;
}
while (iTo < bufferSize)
{
buffer[iTo] = 0;
iTo++;
}
}
else
{
backBitsToShift = 16 - bitsToShift;
while (iFrom < bufferSize - 1)
{
buffer[iTo] = (buffer[iFrom] >> bitsToShift) | (buffer[iFrom+1] << backBitsToShift);
iTo++;
iFrom++;
}
if (iFrom < bufferSize)
{
buffer[iTo] = buffer[iFrom] >> bitsToShift;
iTo++;
}
while (iTo < bufferSize)
{
buffer[iTo] = 0;
iTo++;
}
}
}
}
关于c - 将 fwrite() 与霍夫曼编码一起使用 - 位移位和位操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15081585/
我正在努力做到这一点 在我的操作中从数据库获取对象列表(确定) 在 JSP 上打印(确定) 此列表作为 JSP 中的可编辑表出现。我想修改然后将其提交回同一操作以将其保存在我的数据库中(失败。当我使用
我有以下形式的 Linq to Entities 查询: var x = from a in SomeData where ... some conditions ... select
我有以下查询。 var query = Repository.Query() .Where(p => !p.IsDeleted && p.Article.ArticleSections.Cou
我正在编写一个应用程序包,其中包含一个主类,其中主方法与GUI类分开,GUI类包含一个带有jtabbedpane的jframe,它有两个选项卡,第一个选项卡包含一个jtable,称为jtable1,第
以下代码产生错误 The nested query is not supported. Operation1='Case' Operation2='Collect' 问题是我做错了什么?我该如何解决?
我已经为 HA redis 集群(2 个副本、1 个主节点、3 个哨兵)设置了本地 docker 环境。只有哨兵暴露端口(10021、10022、10023)。 我使用的是 stackexchange
我正在 Desk.com 中构建一个“集成 URL”,它使用 Shopify Liquid 模板过滤器语法。对于开始日期为 7 天前而结束日期为现在的查询,此 URL 需要包含“开始日期”和“结束日期
你一定想过。然而情况却不理想,python中只能使用类似于 i++/i--等操作。 python中的自增操作 下面代码几乎是所有程序员在python中进行自增(减)操作的常用
我需要在每个使用 github 操作的手动构建中显示分支。例如:https://gyazo.com/2131bf83b0df1e2157480e5be842d4fb 我应该显示分支而不是一个。 最佳答
我有一个关于 Perl qr 运算符的问题: #!/usr/bin/perl -w &mysplit("a:b:c", /:/); sub mysplit { my($str, $patt
我已经使用 ArgoUML 创建了一个 ERD(实体关系图),我希望在一个类中创建两个操作,它们都具有 void 返回类型。但是,我只能创建一个返回 void 类型的操作。 例如: 我能够将 book
Github 操作仍处于测试阶段并且很新,但我希望有人可以提供帮助。我认为可以在主分支和拉取请求上运行 github 操作,如下所示: on: pull_request push: b
我正在尝试创建一个 Twilio 工作流来调用电话并记录用户所说的内容。为此,我正在使用 Record,但我不确定要在 action 参数中放置什么。 尽管我知道 Twilio 会发送有关调用该 UR
我不确定这是否可行,但值得一试。我正在使用模板缓冲区来减少使用此算法的延迟渲染器中光体积的过度绘制(当相机位于体积之外时): 使用廉价的着色器,将深度测试设置为 LEQUAL 绘制背面,将它们标记在模
有没有聪明的方法来复制 和 重命名 文件通过 GitHub 操作? 我想将一些自述文件复制到 /docs文件夹(:= 同一个 repo,不是远程的!),它们将根据它们的 frontmatter 重命名
我有一个 .csv 文件,其中第一列包含用户名。它们采用 FirstName LastName 的形式。我想获取 FirstName 并将 LastName 的第一个字符添加到它上面,然后删除空格。然
Sitecore 根据 Sitecore 树中定义的项目名称生成 URL, http://samplewebsite/Pages/Sample Page 但我们的客户有兴趣降低所有 URL(页面/示例
我正在尝试进行一些计算,但是一旦我输入金额,它就会完成。我只是希望通过单击按钮而不是自动发生这种情况。 到目前为止我做了什么: Angular JS - programming-fr
我的公司创建了一种在环境之间移动文件的复杂方法,现在我们希望将某些构建的 JS 文件(已转换和缩小)从一个 github 存储库移动到另一个。使用 github 操作可以实现这一点吗? 最佳答案 最简
在我的代码中,我创建了一个 JSONArray 对象。并向 JSONArray 对象添加了两个 JSONObject。我使用的是 json-simple-1.1.jar。我的代码是 package j
我是一名优秀的程序员,十分优秀!