5

我试图找到 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 194 221 250 250 281 314 349 349 386 425 466 554 601 554 601 650 701 650 701 754 809 866 866 866 925 925 986 100 117 100 117 136 136 136 157 136 157 180 180 205 261 292 261 292 292 261 292 292 292 292 292 292 292 292325 360 397 436 477 520 分段错误:11

我应该对我的代码进行哪些修改?

更新

除了数组问题,我的代码还有什么问题吗?例如,它仍然打印 100 作为第一个值,它似乎不是 a^2 + b^2 的任何组合,即使 b = 0 也是如此。

更新 2

没关系,忘了a = 10,b = 0,这将是100。

4

6 回答 6

5

尝试:

int poss_n[(MAX + 1) * (MAX + 1)] = {0};

这样您就可以分配足够的内存来存储您的答案。

于 2013-04-22T10:35:48.310 回答
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++;
            }
        }
    }
}
于 2013-04-22T10:37:03.733 回答
0
int poss_n[] = {0};  

这将定义包含一个元素的数组,稍后当您尝试访问索引 > 1 的元素时会导致 Segfault

于 2013-04-22T10:35:59.703 回答
0

正如其他人已经说过的那样,您在堆栈上分配的空间太少。堆栈从高地址开始递减。因此,首先您覆盖破坏它的堆栈数据,然后您到达堆栈的末尾并尝试写入未分配给您或根本未分配的内存空间。CPU 产生一个异常,这就是Segmentation fault错误发生的原因。

此外,您可以在堆上而不是在堆栈上使用malloc(3)分配一些内存,当您发现更多结果时,您可以使用 realloc 进行扩展。它使用更多的系统 CPU 资源,但减少了内存过度分配。

在某些 un*ces 上,您还可以使用alloca(3)函数在堆栈上动态分配内存。它的行为非常相似some_type array[some_value],但some_value可以计算运行时而不是编译时间。

您也可以使用C++ STL 容器,例如vectorandlist和您可以推送找到的元素。在堆上自动分配内存段。

一些评论: 可以使用加法而不是乘法计数平方。(a+1)^2 - a^2 = 2a + 1。因此将 (a<<1) + 1 添加到从 0 开始的临时变量。类似的可以应用于 b。如果总和超过 999,也可以从内部循环中跳转。您不需要检查剩余值。值 b 可以从 (int)sqrt(100-a*a) 开始(或使用临时变量来跟踪第一个 b 值)以减少内部循环的数量。

于 2013-04-22T10:43:51.453 回答
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++;
            }
        }
    }
}
于 2013-04-22T10:49:06.320 回答
0

这里有很多答案,但没有一个很准确。

Ff 我们假设只有唯一的输出被打印出来,循环应该是这样的(正如 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< 值 <999,它将包含更多元素,但如果没有该规则,它将包含确切数量的元素。

于 2013-04-22T11:33:20.880 回答