0

我必须编写一个可以一次读取三个字节数据的算法,例如:

例如,假设用户输入:Uof

二进制中的 Uof 将显示为 01010101 01101111 01100110

我需要帮助将其分成四个相等的部分,每个部分六位,如下所示:

010101 (21)

010110 (22)

111101 (61)

100110 (38)

我只被允许使用整数。我可以读取第一个字符,将其向右移动两个并得到结果 21 没问题。

获得 22 对我来说毫无意义。任何指针都会有所帮助,不需要确切的解决方案,但是有什么可以让我思考的东西?

4

2 回答 2

1

问你自己:

  • 每个部分的 6 位来自哪里?

  • 如何将位移动到值中的不同位置?

  • 我怎样才能结合两个值,以便只取每个有趣的位?

为了帮助您回答第三个问题,您还可以问自己:

  • 我如何屏蔽一个值,以使有趣的位保持原样,而非有趣的位全部变为 0(或全部变为 1)?
于 2012-09-17T23:39:43.943 回答
0

好的,首先,我们将尝试将 3 个字节放入一个整数中。我们将使用移位和OR逻辑。假设我们有a,bc输入变量。(Uof将分别拆分为a,bc)。

我们首先为b变量增加 1 个字节的空间:

(b << 8)

所以01101111转化为0110111100000000

现在我们OR c进入b,所以零实际上是c

((b << 8) | c))

现在,我们对a. 我们在 的右边保留了更多的 16 位a,所以我们可以OR得到最后一个表达式。

((a << 16) | ((b << 8) | c))

到目前为止,我们已将所有位合并为一个 4 字节整数。

我们现在只需要将它分成 4 个部分,每个部分 6 位。我们将为此使用掩码逻辑。

首先,当我们使用“掩码”逻辑时,我们必须自己制作掩码。我们的掩码是0x3F(取自二进制数111111,即6位),所以当我们AND数的时候,有了这个掩码,我们就可以提取出右边的前6位:

r1 = (merged & 0x00003F);

代表r1什么result 1

现在,同样的事情,但合并后的数字向右 6 位,所以我们可以取下一个 6 位数字,以此类推:

r1 = ((merged >> 0)  & 0x3F);
r2 = ((merged >> 6)  & 0x3F);
r3 = ((merged >> 12) & 0x3F);
r4 = ((merged >> 18) & 0x3F);

因此,最终代码将是:

char /*or int*/ a, b, c;
int merged, r1, r2, r3, r4;

scanf(" %c %c %c", &a, &b, &c);

merged = ((a << 16) | ((b << 8) | c));

r1 = ((merged >> 0)  & 0x3F);
r2 = ((merged >> 6)  & 0x3F);
r3 = ((merged >> 12) & 0x3F);
r4 = ((merged >> 18) & 0x3F);

printf("%d %d %d %d\n", r1, r2, r3, r4);

编辑:我已经更正了面具部分。

于 2012-09-18T00:07:22.627 回答