这个程序是找到三个四位数的素数,这样它们是彼此的排列,它们之间的差异为3320。现在,以下程序正确生成素数但执行停止或仅在值1000之后挂起。为什么会发生这种情况,如何更正?
#include<stdlib.h>
#include<stdio.h>
#define LIMIT 1000000
long int arr[LIMIT];
int Bsearch(long int *primes,long int low,long int high,long int search)
{
while(low<=high)
{
long int mid=(low+high)/2;
if(search<primes[mid])
{
high=mid+1;
}
else if(search>primes[mid])
{
low=mid+1;
}
else if(search==primes[mid])
return 1;
}
return 0;
}
int checkPermu(long int *primes,long int i,long int j,long int k)
{
long int prod1=1;
long int prod2=1;
long int prod3=1;
for(int i=0;i<3;i++)
{
prod1*=primes[i%10];prod2*=primes[j%10];prod3*=primes[k%10];
i/=10;j/=10;k/=10;
}
prod1*=primes[i];prod2*=primes[j];prod3*=primes[k];
if(prod1==prod2==prod3)
return 1;
else
return 0;
}
int main()
{
for(long int i=1;i<LIMIT;i++)
{
arr[i]=1;
}
for(long int i=2;i<LIMIT;i++)
{
if(arr[i]==1)
{
for(long int j=2;i*j<LIMIT;j++)
{
arr[i*j]=0;
}
}
}
long int index=0;
long int count=0;
//count number of primes
for(long int i=1;i<LIMIT;i++)
{
if(arr[i]==1) count++;
}
long int primes[count];
for(long int i=2,index=1;i<LIMIT;i++)
{
if(arr[i]==1)
primes[index++]=i;
}
for(long int i=1000;i<9999;i++)
{
printf("\nCurrent num : %ld\n",i);
if(Bsearch(primes,1,count-1,i))
{
printf("Hello1!");
if(Bsearch(primes,1,count-1,i+3330))
{
printf("\nHello2!");
if(Bsearch(primes,1,count-1,i+3330+3330))
{
printf("\nHello3!");
if(checkPermu(primes,i,i+3330,i+3330+3330))
{
printf("\nFinal Hello!");
printf("required sequence : %ld%ld%ld",i,i+3330,i+3330+3330);
exit(0);
}
}
}
}
}
return 0;
}
答案 0 :(得分:1)
您的代码中存在许多错误。
在函数Bsearch
中,您正在搜索数组中的值。如果不存在怎么办?在您的情况下,1000
不是素数。所以,你无法在数组中找到它。只有当值完全匹配时,才会离开循环。在这种情况下不会发生最终无限循环
在函数checkPermu
中,有两个变量声明为i
。这意味着您要隐藏作为参数传递的i
。为避免它,请给它一些其他名称。
现在,为了避免第一种情况,您可以在C++
,lower_bound中使用内置函数,或者相应地修改代码。这是您编辑的代码。
#include <stdlib.h>
#include <stdio.h>
#define LIMIT 1000000
long int arr[LIMIT];
int Binary_Search(long int a[], int low, int high, long int e)
{
if ( low < 0) return 0;
if (low>=high )
{
if ( e <= a[low] ) return low;
return low+1;
}
int mid=(low+high)/2;
if ( e> a[mid])
return Binary_Search(a,mid+1,high,e);
return Binary_Search(a,low,mid,e);
}
int Bsearch(long int *primes,long int low,long int high,long int search)
{
int idx = Binary_Search(primes, low, high+1,search);
if(primes[idx]==search)
return 1;
return 0;
}
int checkPermu(long int *primes,long int ii,long int j,long int k)
{
long int prod1=1;
long int prod2=1;
long int prod3=1;
for(int i=0;i<3;i++)
{
prod1*=primes[ii%10];prod2*=primes[j%10];prod3*=primes[k%10];
ii/=10;j/=10;k/=10;
}
prod1*=primes[ii];prod2*=primes[j];prod3*=primes[k];
if(prod1==prod2==prod3)
return 1;
else
return 0;
}
int main()
{
for(long int i=1;i<LIMIT;i++)
{
arr[i]=1;
}
for(long int i=2;i<LIMIT;i++)
{
if(arr[i]==1)
{
for(long int j=2;i*j<LIMIT;j++)
{
arr[i*j]=0;
}
}
}
long int index=0;
long int count=0;
//count number of primes
for(long int i=1;i<LIMIT;i++)
{
if(arr[i]==1) count++;
}
long int primes[count];
for(long int i=2,index=1;i<LIMIT;i++)
{
if(arr[i]==1)
primes[index++]=i;
}
//Bsearch(primes,1,count-1,1000);
for(long int i=1000;i<9999;i++)
{
printf("\nCurrent num : %ld\n",i);
if(Bsearch(primes,1,count-1,i))
{
printf("Hello1!\n");
if(Bsearch(primes,1,count-1,i+3330))
{
printf("\nHello2!\n");
if(Bsearch(primes,1,count-1,i+3330+3330))
{
printf("\nHello3!\n");
if(checkPermu(primes,i,i+3330,i+3330+3330))
{
printf("\nFinal Hello!\n");
printf("required sequence : %ld%ld%ld",i,i+3330,i+3330+3330);
exit(0);
}
}
}
}
}
return 0;
}
答案 1 :(得分:0)
首先,挂起的原因可能是由于这一行:
long int primes[count];
count
这里是78499,你在堆栈上分配313996个字节。堆栈大小可能比这小,并且堆栈溢出似乎在我的情况下导致bash或cmd.exe问题(盲目猜测,它是cmd.exe)。
将其更改为
long int *primes = malloc(count * sizeof *primes);
解决了这个问题。
然而,您的代码的实际问题是您的二进制搜索永远不会终止。因此,修复以前的错误,您的代码处于无限循环中,因此您看不到任何输出。我建议您尝试弄清楚为什么您的二进制搜索不会因练习而终止,但在现实生活中,请使用标准库中的bsearch
。