在C中查找^ 2 + b ^ 2的所有组合

时间:2013-04-22 10:33:50

标签: c

我正在尝试找到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。

6 个答案:

答案 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,例如vectorlist,您可以推送找到的元素。在堆上自动分配内存段。

一些评论: 可以使用加法代替乘法计数平方。 (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,但如果没有该规则,它将保留确切数量的元素。

相关问题