使用许多变量简化和减少代码的简便方法

时间:2017-09-18 00:27:05

标签: algorithm bit-manipulation

我有一堆变量,基本上可以用4位表示。它会是什么样的:

0000 1100 0110 1010

等等。现在我必须采取其中的两个并以一些独特的方式组合它们以获得输出。例如:

如果我有0000和1100(1100和0000将是相同的),我想得到一些独特的十进制或二进制,稍后我只需要一个select语句来返回我想要的。

如果可能的话,我宁愿没有大量的陈述。像:

if (a = 0000 and b = 0000) or (a = 0000 and b = 0000)
if (a = 0000 and b = 0001) or (a = 0001 and b = 0000)
if (a = 0000 and b = 0011) or (a = 0011 and b = 0000)
if (a = 0000 and b = 0111) or (a = 0111 and b = 0000)
if (a = 0000 and b = 1111) or (a = 1111 and b = 0000)
if (a = 0000 and b = 0010) or (a = 0010 and b = 0000)
if (a = 0000 and b = 0110) or (a = 0110 and b = 0000)
if (a = 0000 and b = 1110) or (a = 1110 and b = 0000)
if (a = 0000 and b = 0100) or (a = 0100 and b = 0000)
if (a = 0000 and b = 1100) or (a = 1100 and b = 0000)
if (a = 0000 and b = 1000) or (a = 1000 and b = 0000)
if (a = 0000 and b = 1010) or (a = 1010 and b = 0000)
if (a = 0000 and b = 0101) or (a = 0101 and b = 0000)
if (a = 0000 and b = 1001) or (a = 1001 and b = 0000)
if (a = 0000 and b = 1011) or (a = 1011 and b = 0000)

....

if (a = 1010 and b = 0000) or (a = 0000 and b = 1010)
if (a = 1010 and b = 0001) or (a = 0001 and b = 1010)
if (a = 1010 and b = 0011) or (a = 0011 and b = 1010)
if (a = 1010 and b = 0111) or (a = 0111 and b = 1010)
if (a = 1010 and b = 1111) or (a = 1111 and b = 1010)
if (a = 1010 and b = 0010) or (a = 0010 and b = 1010)
if (a = 1010 and b = 0110) or (a = 0110 and b = 1010)
if (a = 1010 and b = 1110) or (a = 1110 and b = 1010)
if (a = 1010 and b = 0100) or (a = 0100 and b = 1010)
if (a = 1010 and b = 1100) or (a = 1100 and b = 1010)
if (a = 1010 and b = 1000) or (a = 1000 and b = 1010)
if (a = 1010 and b = 1010) or (a = 1010 and b = 1010)
if (a = 1010 and b = 0101) or (a = 0101 and b = 1010)
if (a = 1010 and b = 1001) or (a = 1001 and b = 1010)
if (a = 1010 and b = 1011) or (a = 1011 and b = 1010)

....

if (a = 1111 and b = 0000) or (a = 0000 and b = 1111)
if (a = 1111 and b = 0001) or (a = 0001 and b = 1111)
if (a = 1111 and b = 0011) or (a = 0011 and b = 1111)
if (a = 1111 and b = 0111) or (a = 0111 and b = 1111)
if (a = 1111 and b = 1111) or (a = 1111 and b = 1111)
if (a = 1111 and b = 0010) or (a = 0010 and b = 0000)
if (a = 1111 and b = 0110) or (a = 0110 and b = 0000)
if (a = 1111 and b = 1110) or (a = 1110 and b = 0000)
if (a = 1111 and b = 0100) or (a = 0100 and b = 1111)
if (a = 1111 and b = 1100) or (a = 1100 and b = 1111)
if (a = 1111 and b = 1000) or (a = 1000 and b = 1111)
if (a = 1111 and b = 1010) or (a = 1010 and b = 1111)
if (a = 1111 and b = 0101) or (a = 0101 and b = 1111)
if (a = 1111 and b = 1001) or (a = 1001 and b = 1111)
if (a = 1111 and b = 1011) or (a = 1011 and b = 1111)

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

创建70个输出值的数组,以及与a和b的每个组合关联的输出索引的2D数组,如下所示:

output = [10,20,7,11...]          // 70 values
combis = [[1,5,68,4,5,5,2,50...],
          [5,45,69,24,5,3,14...],
          ...
          [26,1,26,2,65,23,1...]] // 16x16 indexes
return output[combis[a][b]]

这使得输出值与导致特定输出的组合分开,并且可能更符合逻辑且更易于维护。

您可以为a:b和b:a列出带有重复项的16x16索引,或者具有三角形2D数组,如果b大于a,则切换a和b:

output = [10,20,7,11...]          // 70 values
combis = [[1],
          [2,45],
          [6,14,2],
          ...
          [26,1,26,2,65,23,1...]] // 1+2+3+...+16 indexes
if (b > a) return output[combis[b][a]]
else return output[combis[a][b]]

根据您使用的语言,查找表的大小可能会对算法的速度产生重大影响。在为this answer编写JavaScript代码示例时,我发现大表中的一个查找比使用较小表的双查找方法慢得多,并且具有大约200个元素的意外阈值。因此,如果速度很重要,您应该编写几个版本,例如使用平面阵列而不是2D阵列,并比较它们的速度。

答案 1 :(得分:1)

您可以构建一个运算符表,并使用a和b对其进行索引:

result = functors[a][b](a, b);

如果操作员是可交换的,那么如果您在拨打电话之前订购a和b,则只需要设置16 * 16/2仿函数:

result = (a < b ? functors[a][b](a, b) : functors[b][a](a, b));