C 寻找整数的正确后代
我被困在一个基本的算法问题上,我不知道如何解决它C 寻找整数的正确后代,c,algorithm,binary,proper,C,Algorithm,Binary,Proper,我被困在一个基本的算法问题上,我不知道如何解决它 基本上我想列出所有整数的正确后代。也就是说,如果我的数字是21,我想使用它的二进制表示(10101),列出所有至少有一个公共位值为1和21且小于21的数字。这里的结果应该是101001000110001100 正确后代的数学定义如下: 设h是小于2^m的非负数h=d0+d1*2^1+…+dm-1*2^(m-1)其中di=0或1 设h'为另一非负,如h'=d0'+d1'*2^1+…+dm-1'*2^(m-1)其中di'=0或1 h'是h的后代
基本上我想列出所有整数的正确后代。也就是说,如果我的数字是21,我想使用它的二进制表示(10101),列出所有至少有一个公共位值为1和21且小于21的数字。这里的结果应该是101001000110001100 正确后代的数学定义如下:
- 设h是小于2^m的非负数<代码>h=d0+d1*2^1+…+dm-1*2^(m-1)其中di=0或1
- 设h'为另一非负,如
其中di'=0或1h'=d0'+d1'*2^1+…+dm-1'*2^(m-1)
- h'是h的后代,如果di'好的话,那么我最终用C编写了一个代码,它看起来很不好看,可能经过了可怕的优化,但仍然可以正常工作。可能有更简单的解决方案,但出于知识目的,这里是我的:
#include <stdio.h> #include <stdbool.h> #include <stdlib.h> unsigned int pui(unsigned int a, unsigned int b) { if (b == 0) return 1; if (b == 1) return a; if (b % 2 == 0) return pui(a * a, b / 2); else return pui(a * a, (b - 1) / 2); } unsigned int testBit(unsigned int h, unsigned int offset) { unsigned int mask = 1 << offset; return (h & mask); } bool isInList(unsigned int x, unsigned int *output_size, unsigned int **output) { for (int i = 0; i < *output_size; i++) { if (*(*output + i) == x) { return true; } } return false; } void listDescendants(unsigned int h, unsigned int *output_size, unsigned int **output, int *currently_processing) { unsigned int max_offset = 0; unsigned int temp_h = h; unsigned int initial_output_size = *output_size; while (temp_h > 0) { max_offset++; temp_h /= 2; } unsigned int h_radix2[max_offset]; for (int i = 0; i < max_offset; i++) { if (testBit(h, i)) { if (h > pui(2, i) && !isInList(h - pui(2, i), output_size, output)) { *(*output + *output_size) = h - pui(2, i); *output_size += 1; } } } if (*currently_processing < (int)*output_size) { *currently_processing += 1; listDescendants(*(*output + *currently_processing), output_size, output, currently_processing); } } int main() { int currently_processing = -1; unsigned int size = 0; unsigned int *output = malloc(300 * sizeof(unsigned int)); listDescendants(21, &size, &output, ¤tly_processing); printf("size = %u\n", size); for (int i = 0; i < size; i++) { printf("%u ", output[i]); } printf("\n"); return 0; }
您可以使用递归解决方案,如以下解决方案 我有点懒,所以我没有把数字放在列表中,只是简单地打印出来,而且我还打印了0和给定的数字 我相信你可以很容易地调整代码,让它做你想要的#包括 #包括 #包括 无符号整数pui(无符号整数a、无符号整数b) { 如果(b==0) 返回1; 如果(b==1) 返回a; 如果(b%2==0) 返回pui(a*a,b/2); 其他的 返回贝氏指数(a*a,(b-1)/2); } 无符号整数测试位(无符号整数h,无符号整数偏移) { 无符号整数掩码=1(0) { 最大偏移量++; 温度h/=2; } 无符号整数h_半径2[最大偏移量]; 对于(int i=0;i
pui(2,i)和&!isInList(h-pui(2,i),输出大小,输出)) { *(*输出+*输出大小)=h-pui(2,i); *输出_大小+=1; } } } if(*当前处理<(整数)*输出大小) { *当前_处理+=1; 列表子体(**输出+*当前处理)、输出大小、输出、当前处理); } } int main() { int当前_处理=-1; 无符号整数大小=0; 无符号整数*输出=malloc(300*sizeof(无符号整数)); 列表子体(21、大小、输出和当前处理); printf(“大小=%u\n”,大小); 对于(int i=0;i #include <stdio.h> #define CHAR_BIT 8 void ProperDescendantsRecursive(unsigned int num, unsigned int bit_index) { if (CHAR_BIT * sizeof(unsigned int) - 1 == bit_index) { printf("%u\n", num); } else { unsigned int mask = 1U << bit_index; if (num & mask) { /* with the bit at index bit_index is off */ ProperDescendantsRecursive(num ^ mask, bit_index + 1); /* with the bit at index bit_index is on */ ProperDescendantsRecursive(num, bit_index + 1); } else { ProperDescendantsRecursive(num, bit_index + 1); } } } void ProperDescendants(unsigned int num) { ProperDescendantsRecursive(num, 0); } int main(void) { ProperDescendants(21); return 0; }
这里有一个非常简单的方法:枚举
和n-1
之间的所有整数,并打印那些严格包含在1
中的整数,即:n
(i&n)=i
void list_descendants(int n) { printf("descendants of %d:", n); for (int i = n; i --> 1;) { if ((i & n) == i) printf(" %d", i); } printf("\n"); }
我们很高兴您与我们在一起,我们需要查看您的代码以帮助您调试它。如果你没有algo,请先开发它。这里有一个想法:检查所有
位,将它们逐个归零。然后,对于每个结果,递归运行算法以查找“后代”的“后代”。“列出至少有一个公共位值为1的所有数字”,则正确答案还包括11、111等。您的规范中有错误。1
在Python和C中是您的朋友将原始数据分解为2的幂(21=16+4+1),对这些进行一次计算,对于幂集中的每个集进行一次求和,求和列表就是您想要的后代列表。只是想知道&
是什么。而pui
s在哪里?pui只是一个基本的求幂函数(pui(2,i)返回2^i)。我忘了把文件放进去。包括以下内容(将它们添加到文件中):#包括#包括#包括#include
是过分的。您可以编写2^n作为pui
1第一次打印缺少参数,但我认为这是最好的解决方案。非常感谢。
void list_descendants(int n) { printf("descendants of %d:", n); for (int i = n; i --> 1;) { if ((i & n) == i) printf(" %d", i); } printf("\n"); }