模拟手项求和的问题
opencell吧
全部回复
仅看楼主
level 11
IveArthur 楼主
一楼喂百度
2014年02月14日 04点02分 1
level 11
IveArthur 楼主
#include<stdio.h>
#include<time.h>
int main(void)
{
void Fibonacci(int n);
int m;
printf("请输入Fibonacci第几项:");
scanf("%d",&m);
Fibonacci(m);
printf("\n");
}
void Fibonacci(int n)
{
void imitation_addition(char a[],char b[],char c[]);
char r[30000]={'\0'},s[30000]={'\0'},t[30000]={'\0'};
char *p1,*p2,*p3;
int i,j,counter;
int time;
time=clock();
p1=&r[0];
p2=&s[0];
p3=&t[0];
//printf("%d\n",n);
r[0]='1';
s[0]='1';
if(n<3)
t[0]='1';
if(n>2)
{
for(i=3;i<=n;i++)
{
imitation_addition(p1,p2,p3);
for(j=0;s[j]!='\0';j++)
{
r[j]=s[j];
}
for(j=0;t[j]!='\0';j++)
{
s[j]=t[j];
}
}
}
printf("费时:%d毫秒,%d秒\n",clock()-time,(clock()-time)/1000);
for(i=0;t[i]!='\0';i++)
{
counter=i;
}
printf("Fibonacci第%d项有%d位数.\n",n,counter);
printf("Fibonacci第%d项为:\n",n);
for(i=0;t[i]!='\0';i++)
{
printf("%c",t[i]);
}
}
void imitation_addition(char a[],char b[],char c[])
{
int i,j,k=0,temp=0,tempa=0,tempb=0;
int midvalue;
for(i=0;c[i]!='\0';i++)
c[i]='\0';
for(i=0;a[i]!='\0';i++)
tempa++;
for(i=0;b[i]!='\0';i++)
tempb++
2014年02月14日 04点02分 2
level 11
IveArthur 楼主
;
for(i=tempa-1,j=tempb-1;i>=0||j>=0;i--,j--,k++)
{
if(c[k]=='1')
{
if(i<0)
c[k]=c[k]+b[j]-'0';
else if(j<0)
c[k]=c[k]+a[i]-'0';
else
c[k]=c[k]+a[i]+b[j]-'0'-'0';
}
else
{
if(i<0)
c[k]=c[k]+b[j];
else if(j<0)
c[k]=c[k]+a[i];
else
c[k]=c[k]+a[i]+b[j]-'0';
}
if(c[k]>'9')
{
c[k+1]='1';
c[k]=c[k]-10;
}
}
for(i=0;c[i]!='\0';i++)//逆序存放字符数组
{
temp++;
}
for(i=0;i<temp/2;i++)
{
midvalue=*(c+i);
*(c+i)=*(c+temp-i-1);
*(c+temp-i-1)=midvalue;
}
}
2014年02月14日 04点02分 3
level 11
IveArthur 楼主
如果要变成递归的话应该怎么办还有就是怎么优化这个程序(写的非常烂)
2014年02月14日 04点02分 4
2014年02月14日 04点02分
level 6
不是求和?
1。求某个项:
version1:
int main(){
printf("项数:");int n;
scanf("%d",&n);
int a,b,c;
if(n==1||n==2){c=1;}
if(n==3){c=2;}
else {
for(int i=0;i<n-3;i++){
//C99 i可声明在内
a=b;b=c;c=a+b; }
}
printf("\n第%d个项为",n);
printf(",有%d位",printf("%d",c));
return 0;}
version2: (递归效率低,且容易造成栈溢出)
int func(int n){
if(n==1||n==2){return 1;}
else {return func(n-1)+func(n-2);}
}
int main(){
printf("项数:");int n;
scanf("%d",&n);
printf("\n第%d个项为",n);
printf(",有%d位",
printf("%d",func(n)));
return 0;}
2014年02月14日 11点02分 5
你这个算法到后面就溢出了,比如我输入100,显示只有一位
2014年02月14日 12点02分
@regexepx 还有就是version1根本不是fibnacci的算法吧,第一万项才几十位
2014年02月14日 12点02分
@IveArthur 我上机实践一下
2014年02月14日 12点02分
@IveArthur 哦,忘了一开始a=1,b=1,c=2
2014年02月14日 12点02分
level 6
2.求和通式
Sn={[(1+√5)/2]^(n+2)-[(1-√5)/2]^(n+2)}/√5-1
我也试着二项展开什么的化简,不过似乎没简化多少。
把优化参数开高点也差不多了。
#include "math.h"
int main(){
printf("项数:");int n;
scanf("%d",&n);
double t=sqrt(5.0);
printf("\n项数和为%d",(int)
(pow(0.5+0.5*t,n+2)+
pow(0.5-0.5*t,n+2) )/t-1 );
return 0;}
2014年02月14日 11点02分 6
还有就算是通项公式如果不用字符数组也会很快溢出
2014年02月14日 12点02分
@IveArthur version1怎么会溢出?
2014年02月14日 12点02分
@IveArthur 哦,知道了。如果是很大的数字,直接用python
2014年02月14日 12点02分
回复 regexepx :感觉就算是python写fib函数也算不了,我用的是 def fib(x): if x=1: return 1 elif x=2: return 1 else: return fib(x-1)+fib(x-2)
2014年02月14日 12点02分
level 6
printf("\n项数和为%d",(int)
(
(pow(0.5+0.5*t,n+2)+
pow(0.5-0.5*t,n+2) )/t-1
)
);
2014年02月14日 11点02分 7
level 11
IveArthur 楼主
@regexepx ,是手机的问题?
2014年02月14日 12点02分 9
可能我代码有错?我没有试过直接写的
2014年02月14日 12点02分
level 11
IveArthur 楼主
你看看这张,python写的,很久都没算出来@regexepx
2014年02月14日 12点02分 10
别急。。等会验证
2014年02月14日 12点02分
我的情况一样,确实100就卡了
2014年02月14日 12点02分
@温厚且温柔的鱼丸0h 确实,不管哪个编程语言,这样算都会溢出,我还试了一下common lisp和perl,都一样
2014年02月14日 12点02分
@IveArthur C没问题,perl懒得试
2014年02月14日 12点02分
level 11
IveArthur 楼主
2014年02月14日 12点02分 12
我这里的错误在哪里
2014年02月14日 12点02分
@IveArthur 最后一个printf的lld是什么东西?
2014年02月14日 12点02分
回复 regexepx :这个是long long int的转换说明,这样可以多打出几个数字
2014年02月14日 12点02分
@温厚且温柔的鱼丸0h 初步推断绝对是初始化的问题
2014年02月14日 12点02分
level 11
IveArthur 楼主
等一下,你看,如果把lld改为d的话出现了这样的状况@regexepx
2014年02月14日 12点02分 13
我试试用%u看看
2014年02月14日 12点02分
@regexepx 即使是改成%u,错误依旧啊第一万项只有十六位数
2014年02月14日 12点02分
@IveArthur 我的错,确实溢出了。我又把a,b,c换成long long int型,用lld,成功了
2014年02月14日 12点02分
@温厚且温柔的鱼丸0h 仍然不行,显示 项数:10000 第10000个项为-2872092127636481573
2014年02月14日 12点02分
level 11
IveArthur 楼主
请输入Fibonacci第几项:1000
费时:81026毫秒,81秒
Fibonacci第1000项有208位数.
Fibonacci第1000项为:
4346655768693745643568852767504062580256466051737178040248172908953655541794905
18904038798
40079255169295922593080322634775209689623239873322471161642996440906533
18793829896
9649928516003704476
13779516684
9228875
@regexepx
你的算法的值不正确
2014年02月14日 13点02分 14
不对,你又哪里弄错了,帖代码
2014年02月14日 13点02分
我是18位
2014年02月14日 13点02分
level 6
So讨论结束?。。你这帖讨论的不是算法,是大数处理嘛。。我去研究下为何python不对(虽说慢也不至于这样。。)
2014年02月14日 13点02分 15
算结束吧~python也要靠特殊算法才能求值
2014年02月14日 13点02分
level 11
IveArthur 楼主
看代码@regexepx
2014年02月14日 13点02分 16
你的结果是 项数:1000 第1000个项为817770325994397771
2014年02月14日 13点02分
第5行,long long int
2014年02月14日 13点02分
2014年02月14日 13点02分
回复 regexepx :long long就是long long int的缩写,是一样的
2014年02月14日 13点02分
level 11
IveArthur 楼主
看图说话@regexepx
2014年02月14日 13点02分 17
你看,很多数字都为负数
2014年02月14日 13点02分
运行的前几项都差不多
2014年02月14日 13点02分
level 6
@IveArthur 代码:
a=b=1.0;c=2.0
for i in range(0,1000-3):
a=b;b=c;c=a+b;
print c
2014年02月14日 13点02分 19
最后的显示是科学计数法,4开头
2014年02月14日 13点02分
@温厚且温柔的鱼丸0h ,肯定不止18位啦
2014年02月14日 13点02分
彻底没问题了~python里用递归的话会造成那样的问题~可能还是堆栈的设计问题吧
2014年02月14日 13点02分
1