难瓜学编程 2021-08-20 20:43 采纳率: 66.7%
浏览 47
已结题

新学的位运算,不会用,请给出一种简单的方法

数组压缩
描述

小k同学得到了两个数组 A 和 B ,长度均为 n,包含了 0∼30000 之间的正整数.

她想把两个数组压缩成一个.

int encodeInteger(int x, int n) {
    n = n << (1 << (1 << (1 << 1)));
    x = x | n;
    return x;
}

void encodeArray(int *A, int *B, int n){
    for (int i = 0; i < n; i++) {
        A[i] = encodeInteger(A[i], B[i]);
    }
}


小k把 数组A 和 数组B传递给 函数encodeArray ,并更新数组 A,丢弃数组B。

现在小k想通过新的数组A,恢复原来的两个数组A和数组B. 你能帮她恢复吗?

输入格式

第一行包括一个整数 1≤T≤100, 表示测试数据的个数.

每个测试数据的第一行包括一个整数 1≤n≤10000, 数组的大小.

之后 n 行是修改过的数组 A 的内容.

输出格式

对每个测试数据, 先输出是第几个测试数据.

第二行输出 n 个数, 空格隔开, 末尾无空格, 表示原数组 A.

第三行输出 n 个数, 空格隔开, 末尾无空格, 表示原数组 B.

样例输入

1
4
196613
655370
196620
131079
样例输出

Case 1:
5 10 12 7
3 10 3 2

  • 写回答

1条回答 默认 最新

  • include_iostream_ 2021-08-20 21:32
    关注

    首先,2的15次方是32768,30000小于这个数,因此原数组每个数字的二进制形式都在15位以内。由于输入都非负,不用考虑负数。
    看encodeInteger:(1<<(1<<(1<<1)))就是16,因此第一条语句相当于n=n<<16,根据左移属性,低16位填0,原始数据移到高16位。由于原始数据均不超过16位,因此绝不会有位丢失。
    返回的x是x和n按位或,换言之,就是把x存储在低16位,n存储在高16位进行拼接。这个过程显然不会产生数据丢失。由于原始数据均小于15位,拼接后数据即便以有符号int读入,右移时也不必考虑负数右移的UB行为。
    由于x传的是A的对应数据,n则是B的对应数据,相当于新的A数组中,A的高16位是原来B在这里的数据,低16位是A原来的数据。
    至此,解法很简单了。假定输入数组是in[i],则(原来数据中)A[i]的值为in[i] & 0xFFFF,B[i]是in[i] >> 16。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 9月5日
  • 已采纳回答 8月28日
  • 创建了问题 8月20日

悬赏问题

  • ¥15 目详情-五一模拟赛详情页
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?
  • ¥15 加热介质是液体,换热器壳侧导热系数和总的导热系数怎么算
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line