繁体   English   中英

寻找原始毕达哥拉斯三元组的算法

algorithm for finding primitive pythagorean triples

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

这是我的代码:

// PPT.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>

#define LOWER_BOUND 1
#define UPPER_BOUND 20

struct ppt
{
    int v1;
    int v2;
    int v3;
    ppt *next;
};

typedef struct ppt PPT;
typedef PPT *ppt_ptr;


void insert_ppt(ppt_ptr *h_ptr, ppt_ptr *t_ptr, int u1, int u2, int u3);

void print_ppt(ppt_ptr curr_ptr);

int is_prime(int n);

int is_pythagorean_triplet(int v1, int v2, int v3);

int different_triples(int v1, int v2, int v3,  int u1, int u2, int u3);  

int are_exact_multiples(int p, int q, int r,  int l, int m, int n);  

int is_unique_and_insertable(ppt_ptr curr_ptr, int v1, int v2, int v3);  

//====================================================================

int _tmain(int argc, _TCHAR* argv[])
{
    ppt_ptr head_ptr = NULL;
    ppt_ptr tail_ptr = NULL;

    for (int a = LOWER_BOUND;  a <= UPPER_BOUND; a++)
    {
        for (int b = LOWER_BOUND;  b <= UPPER_BOUND;  b++)
        {
            for (int c = LOWER_BOUND;  c <= UPPER_BOUND; c++)
            {
                if(is_pythagorean_triplet(a,b,c) == 1)
                {
                    if(head_ptr == NULL)
                    {
                        //printf("%d %d %d",a,b,c);
                        insert_ppt(&head_ptr,&tail_ptr,a,b,c);
                    }
                    //printf("%d %d %d",a,b,c);
                    if(is_unique_and_insertable(tail_ptr,a,b,c) == 1)
                    {   
                        //printf("%d %d %d\n",a,b,c);
                        insert_ppt(&head_ptr,&tail_ptr,a,b,c);
                    }
                }
            }
        }
    }

    //print_ppt(head_ptr);
    getchar();
    getchar();
    return 0;
}

此函数在列表末尾插入一个新节点

void insert_ppt(ppt_ptr *h_ptr, ppt_ptr *t_ptr, int u1, int u2, int u3)
{
    ppt_ptr new_ptr;

    new_ptr = ppt_ptr( malloc( sizeof(PPT) ) );

    if(new_ptr != NULL)
    {
        new_ptr->v1   = u1;
        new_ptr->v2   = u2;
        new_ptr->v3   = u3;
        new_ptr->next = NULL;

        if(*h_ptr == NULL)
        {
            *h_ptr = new_ptr;
        }
        else
        {
            (*t_ptr)->next = new_ptr;
        }

        *t_ptr = new_ptr;
    }
    else
    {
        printf("%d %d %d not inserted. No memory available.\n",u1,u2,u3);
    }
}

此功能打印列表

void print_ppt(ppt_ptr curr_ptr)
{
    if(curr_ptr == NULL)
    {
        printf("List is empty.\n\n");
    }
    else
    {
        while(curr_ptr != NULL)
        {
            printf("%d %d %d\n",curr_ptr->v1,curr_ptr->v2,curr_ptr->v3);
            curr_ptr = curr_ptr->next;
        }
    }
}

此函数确定数字是否为质数

// Function 1
int is_prime(int n)
{
    int num_of_factors = 0;
    int i = 1;

    for (i=1; i<=n; i++)
    {
        if (n % i  == 0)
        {
            num_of_factors ++;
        }
    }

    if (num_of_factors == 2)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

此函数确定三联体是否为毕达哥拉斯

// Function 2
int is_pythagorean_triplet(int v1, int v2, int v3)
{
    if ( (v1*v1 + v2*v2 == v3*v3) || (v2*v2 + v3*v3 == v1*v1) || (v1*v1 + v3*v3 == v2*v2) )
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

此函数确定三元组是否唯一,这是我遇到的问题

int is_unique_and_insertable(ppt_ptr curr_ptr, int v1, int v2, int v3)
{
    if(curr_ptr == NULL)
    {
        //printf("List is empty.\n\n");
    }
    else
    {
        if(curr_ptr != NULL)
        {
            //printf("%d %d %d\n",curr_ptr->v1,curr_ptr->v2,curr_ptr->v3);
            int u1 = curr_ptr->v1;
            int u2 = curr_ptr->v2;
            int u3 = curr_ptr->v3;

            if( (different_triples(v1,v2,v3,u1,u2,u3)) && 
                (!are_exact_multiples(v1,v2,v3,u1,u2,u3) ) )
            {
                printf("%d %d %d\n",curr_ptr->v1,curr_ptr->v2,curr_ptr->v3);
                return 1;
            }

            //printf("yoyoyo");
            curr_ptr = curr_ptr->next;
        }
    }
    return 0;
}

此函数确定三元组是否唯一

// Definition:  This function checks if <v1,v2,v3> and <u1,u2,u3> are different triplets
//              or not.  If they are different triplets, it returns 1.
int different_triples(int v1, int v2, int v3,  int u1, int u2, int u3)
{
    if (v1==u1 && v2==u2 &&  v3==u3)
        return 0;
    else if (v1==u1 && v2==u3 && v3==u2)
        return 0;
    else if (v1==u2 && v2==u1 && v3==u3)
        return 0;
    else if (v1==u2 && v2==u3 && v3==u1)
        return
    else if (v1==u3 && v2==u2 && v3==u1)
        return 0;
    else if (v1==u3 && v2==u1 && v3==u2)
        return 0;
    else
        return 1;
}

此函数确定三元组是否是三元组的倍数

// This function tests if the triplet <p,q,r> is an exact multiple of <l,m,n> in any order
//   (arrangement/permutation)
int  are_exact_multiples(int v1, int v2, int v3,  int u1, int u2, int u3)
{
    if (v1%u1==0 && v2%u2==0 &&  v3%u3==0)
        return 1;
    else if (u1%v1==0 && u2%v2==0 &&  u3%v3==0)
        return 1;
    else if (v1%u1==0 && v2%u3==0 && v3%u2==0)
        return 1;
    else if (u1%v1==0 && u2%v3==0 && u3%v2==0)
        return 1;
    else if (v1%u2==0 && v2%u1==0 && v3%u3==0)
        return 1;
    else if (v1%u2==0 && v2%u3==0 && v3%u1==0)
        return 1;
    else if (u1%v2==0 && u2%v1==0 && u3%v3==0)
        return 1;
    else if (u1%v2==0 && u2%v3==0 && u3%v1==0)
        return 1;
    else if (v1%u3==0 && v2%u2==0 && v3%u1==0)
        return 1;
    else if (v1%u3==0 && v2%u1==0 && v3%u2==0)
        return 1;
    else if (u1%v3==0 && u2%v2==0 && u3%v1==0)
        return 1;
    else if (u1%v3==0 && u2%v1==0 && u3%v2==0)
        return 1;
    else
        return 0;
}

我知道算法尚未优化...我稍后会做。 有人可以帮我使这段代码起作用。

1 个回复

您的函数is_unique_and_insertable大概应该检查列表中是否已经存在等效的三元组(相同数字,不同顺序),或者新的三元组是列表中三元组的倍数(模排列)。 但是它只将新的三元组与第一个列表元素进行比较,该函数中没有循环语句或递归。

int is_unique_and_insertable(ppt_ptr curr_ptr, int v1, int v2, int v3)
{
    if(curr_ptr == NULL)
    {
        //printf("List is empty.\n\n");
    }
    else
    {
        if(curr_ptr != NULL)
        {
            //printf("%d %d %d\n",curr_ptr->v1,curr_ptr->v2,curr_ptr->v3);
            int u1 = curr_ptr->v1;
            int u2 = curr_ptr->v2;
            int u3 = curr_ptr->v3;

            if( (different_triples(v1,v2,v3,u1,u2,u3)) && 
                (!are_exact_multiples(v1,v2,v3,u1,u2,u3) ) )
            {
                printf("%d %d %d\n",curr_ptr->v1,curr_ptr->v2,curr_ptr->v3);
                return 1;
            }

            //printf("yoyoyo");
            curr_ptr = curr_ptr->next;
        }
    }
    return 0;
}

如果您使用while(curr_ptr != NULL)则可以将其与不仅仅是第一个元素进行比较。 但是,它仍然具有错误的逻辑,一旦发现新的三进制不是倍数,就返回true(1)。

逻辑必须是相反的,如果遇到等效的三元组(或新的三元组是其三倍数的三元组),则仅当遍历整个列表而未遇到该三元组时,才返回false(0)。返回true:

int is_unique_and_insertable(ppt_ptr curr_ptr, int v1, int v2, int v3)
{
    while(curr_ptr != NULL)
    {
        int u1 = curr_ptr->v1;
        int u2 = curr_ptr->v2;
        int u3 = curr_ptr->v3;
        if (!different_triples(v1, v2, v3, u1, u2, u3) || are_exact_multiples(v1, v2, v3, u1, u2, u3))
        {
            return 0;
        }
        curr_ptr = curr_ptr->next;
    }
    return 1;
}

are_exact_multiples您更接近正确的程序,但是are_exact_multiples函数出错,它将声明(15, 36, 39) are_exact_multiples (15, 36, 39)(3, 4, 5) (15, 36, 39)的倍数,尽管不是。

如果只考虑三元组(a, b, c)a <= b <= c (实际上是a < b < c ,则将获得更简单容易的正确程序,因为毕达哥拉斯三元组不能有两个组件相等)。

您说过以后会处理效率问题,但是请尽快执行,因为is_prime函数效率很低。 找到第一个平凡除数后,应立即停止,并且在达到平方根时可以停止:

int is_prime(int n)
{
    if (n < 2) return 0;
    if (n%2 == 0) return n == 2;
    for(int d = 3; d*d <= n; d += 2)
    {
        if (n%d == 0) return 0;
    }
    return 1;
}
2 寻找毕达哥拉斯三元组

我一直在尝试使用Mathematica中的Do和If语句来查找勾股三元组。 我需要测试两个整数(a,b)是否构成毕达哥拉斯三重奏,其中:1 &lt;= a &lt;= 100 &amp;&amp; 1 &lt;= b &lt;= 100 该片段为打印提供了三倍,实际上是毕达哥拉斯的 ...

3 java中勾股三元组的有效算法

所以我尝试使用java制作一个程序。 它的输入是整数,整数被认为是 3 个整数 a、b 和 c 的和( a^2 + b^2 = c^2 ),它的输出是 c^2。 为此,我扩展方程组合a^2 + b^2 - c^2 = 0和c = sum - a - b ,得到Math.pow(sum, 2) - 2 ...

4 在 Python 中生成原始勾股三元组列表

[改进封闭式问题] 我看到很多问题都提出了非常相似的问题,但是我一直无法找到涉及这个欧几里得公式的足够答案。 我想尝试创建一个公式,该公式生成一个包含所有勾股三元组的列表,直到给定的数字,比如 k。 毕达哥拉斯三元组是 (x,y,z),其中 x^2 + y^2 = z^2。 它应该满足条件使得 x ...

5 使用python在列表中查找勾股数三元组的数量?

我正在编写一个问题的解决方案,其中代码将在给定列表 a 的列表中找到勾股三元组的数量。 但是,当我将代码提交给自动评分器时,有些测试用例我的代码失败了,但我不知道出了什么问题。 请帮我指出我的错误...... “勾股三元组”是勾股定理的整数解,例如,32+42=52。 给定一个正整数列表,找出 ...

6 寻找毕达哥拉斯三重奏:欧几里德的公式

我正在研究Project Euler中的问题9 : 恰好存在一个毕达哥拉斯三元组,其中a + b + c = 1000.找到产品abc。 我编写的以下代码使用Euclid的公式来生成素数。 出于某种原因,我的代码返回“0”作为答案; 即使变量值对于前几个循环是正确的。 由 ...

2012-03-31 02:48:25 2 1579   c++
7 在涉及勾股三元组和集合的算法中找不到我的错误

我试图找到答案“鉴于L是电线的长度,因为可以精确地形成一个L等于1,500,000的L值多少个正整数?”, Euler项目#75 。 我并没有要求正确的答案,也没有要求找到它的代码。 我将解释如何尝试解决此问题,仅请您指出我的错误之处。 我试图解决Java和Common Lisp中的问 ...

8 使用欧几里德的公式找出所有毕达哥拉斯三元组

该程序的目标是使用欧几里德公式(a = m ^ 2 -n ^ 2,b = 2mn,c = m ^ 2 + n ^)找到小于500的每个值(a,b,c)的所有毕达哥拉斯三元组2.)所以这是我的代码。 我试过这个,我的输出什么都没有。 我认为它的工作方式是:对于小于/等于500且从1开始的 ...

9 找到所有小于500的毕达哥拉斯三元组[关闭]

我需要编写一个程序,以查找所有a,b和c到500的勾股三元组。这是我的代码: 我的for语句检查c中的每个值,然后是b,然后是a。 所以我的问题似乎在if语句内。 它检查平方和b平方是否等于c平方。 没关系。 不过,在and语句之后会发生一些有趣的事情。 如果我使c * c & ...

2014-02-20 04:55:16 3 11435   c++
10 Java 的勾股数三元组计算

所以我需要帮助计算勾股数,基本上我希望输出看起来像这样: 等等。 我需要计算部分的帮助并确保我没有重复项(即 5 12 13 和 12 5 13)。 想法? 有人可以引导我走向正确的方向吗? 这是我到目前为止的代码: ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2021 STACKOOM.COM