我正在尝试找到x的所有组合,其中x = a ^ 2 + b ^ 2,x介于100和999之间。
到目前为止我已经:
#include <stdio.h>
#include <stdlib.h>
#define MAX 31 // given that 31^2 = 961
int main(){
int i = 0;
int poss_n[] = {0};
for (int a=0; a <= MAX; a++){
for (int b=0; b <= MAX; b++){
if (a*a + b*b >= 100 && a*a + b*b <= 999){
poss_n[i] = a*a + b*b;
printf("%i\n", poss_n[i]);
i++;
}
}
}
}
然而,它仅提供部分正确的输出,并且过早地以分段错误11结束:
100 1380405074 144 169 196 225 256 289 324 361 400 441 484 529 576 625 676 729 784 841 900 961 101 122 145 170 197 226 257 290 325 362 401 442 485 530 577 626 677 730 785 842 901 962 104 125 148 173 200 229 260 293 328 365 404 445 488 533 580 629 680 733 788 845 904 965 109 130 153 178 205 234 265 298 333 370 409 450 493 538 585 634 685 738 793 850 909 970 116 137 160 185 212 241 272 305 340 377 416 457 500 545 592 641 692 745 800 857 916 977 106 125 146 169 194 221 250 281 314 349 386 425 466 509 554 601 650 701 754 809 866 925 986 100 117 136 157 180 205 232 261 292 325 360 397 436 477 520 分段错误:11
我应该对代码进行哪些修改?
更新
除了数组问题,我的代码还有什么问题吗?例如,它仍然打印100作为第一个值,它似乎不是^ 2 + b ^ 2的任何组合,即使b = 0。
更新2
没关系,忘了a = 10,b = 0,这将是100。
答案 0 :(得分:5)
尝试:
int poss_n[(MAX + 1) * (MAX + 1)] = {0};
这样您就可以分配足够的内存来存储答案。
答案 1 :(得分:1)
您的错误是您没有分配地点来保存结果。
试试这个:
#include <stdio.h>
#include <stdlib.h>
#define MAX 31 // given that 31^2 = 961
int main(){
int i = 0;
int poss_n[(MAX + 1) * (MAX + 1)] = {0}; //<<- Give it a size
int result; //<<- Using this to reduce calculation of the value multiple times.
for (int a=0; a <= MAX; a++){
for (int b=0; b <= MAX; b++){
result = a*a + b*b;
if (result >= 100 && result <= 999){
poss_n[i] = result ;
printf("%i\n", result);
i++;
}
}
}
}
答案 2 :(得分:0)
int poss_n[] = {0};
这将定义包含一个元素的数组,当您尝试访问索引为&gt;的元素时,将导致Segfault。 1
答案 3 :(得分:0)
正如其他人已经说过,你在堆栈上分配的空间太少了。堆栈从高地址开始减少。所以首先你覆盖破坏它的堆栈数据,然后到达堆栈的末尾,你尝试写入一个未分配给你的内存空间,或者根本没有分配。 CPU会生成异常,这就是发生Segmentation fault
错误的原因。
此外,您可以在堆上为malloc(3)分配一些内存而不在堆栈上,当您找到更多结果时可以使用realloc进行扩展。它使用更多系统CPU资源,但会减少内存分配。
在某些un * ces上您还可以使用alloca(3)函数在堆栈上动态分配内存。它的行为与some_type array[some_value]
非常相似,但some_value
可以计算运行时间而不是编译时间。
此外,您可以使用C++ STL containers,例如vector
和list
,您可以推送找到的元素。在堆上自动分配内存段。
一些评论: 可以使用加法代替乘法计数平方。 (a + 1)^ 2-a ^ 2 = 2a + 1.因此,将(a <&lt; 1)+ 1添加到从0开始的临时变量。类似地可以应用于b。 如果总和超过999,也可以从内部循环跳转。您不需要检查剩余的值。 值b可以从(int)sqrt(100-a * a)开始(或使用temp varible来跟踪第一个b值)以减少内部循环的数量。
答案 4 :(得分:0)
试试这个,它会起作用
#include <stdio.h>
#include <stdlib.h>
#define MAX 31 // given that 31^2 = 961
int main(){
int i = 0;
int poss_n[301];
int a,b;
for (a=0; a <= MAX; a++){
for (b=0; b <= MAX; b++){
if (a*a + b*b >= 100 && a*a + b*b <= 999){
poss_n[i] = a*a + b*b;
printf("%i\t i = %d , a = %d , b = %d\n", poss_n[i],i,a,b);
i++;
}
}
}
}
答案 5 :(得分:0)
这里有很多答案,但都不是很准确。
如果我们假设只打印出唯一的输出,循环应如下所示(正如Roee Gavirel所说):
for (int a=0; a <= MAX; a++){
for (int b=a; b <= MAX; b++){
poss_n将保留这个数量的元素:(32+(32-1)+(32-2)+..+1)=1/2*32*(32+1)
所以应该定义为:
int elements = MAX+1;
int *poss_n = (int*)malloc ((1/2)*(elements)*(elements+1));
由于规则100&lt;
它将具有更多元素。值&lt; 999,但如果没有该规则,它将保留确切数量的元素。