求高精度阶乘求和测试数据。。。。。

forhonor123 2011-07-24 10:27:12
题目就是
Description

用高精度计算出S=1!+2!+3!+…+n!
其中“!”表示阶乘,例如:5!=5*4*3*2*1。
输入正整数N,输出计算结果S。

很常见的一道题,我们学校的判定系统由于暑假暂时不能用了。。。T T
求各位已经做过这道题的大牛给个数据参考参考。。。windows自带的那个计算器好像到16就不准了。。。。
给个N=50和N=100的结果就行了。。。。

N=50, N!=30612255112661433820513310298268268310415621152126321401600620313
N=100, N!=
939394969101011121314161821242833394757718111418243
344618111724365481219315081323407122342815306122551
12661433820513310298268268310415621152126321401600620313

我的测试结果,不知对不对。。
...全文
331 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
forhonor123 2011-07-25
  • 打赏
  • 举报
回复
最后晒下代码:
#include <stdio.h>

int jiecheng(int i, int *p, int s)
{
int a = 1, b, jinwei;

jinwei = 0;
b = 0;
while(b <= s)

{
*(p+b) *= i;
if(b && jinwei)
{
*(p+b) += jinwei;
jinwei = 0;
}
if(*(p+b) > 9)
{
jinwei = *(p+b) / 10;
*(p+b) = *(p+b) % 10;
}
if(*(p+b+1) == 0 && jinwei != 0)
{
if(b + 1 > s)
{
s = b + 1;
}
}
b++;
}
return s;
}
void qiuhe(int x, int *p, int *q)
{
int i = 1, j, ns = 0, jinwei, os = 0, t;

while(x >= i)
{
j = 0;
jinwei = 0;
os = jiecheng(i,p,os);
while(j <= ns || j <= os)
{
*(q+j) += *(p+j);
if(j && jinwei)
{
*(q+j) += jinwei;
jinwei = 0;
}
if(*(q+j) > 9)
{
jinwei = *(q+j) / 10;
*(q+j) = *(q+j) % 10;
}
if(*(q+j+1) == 0 && jinwei)
{
if(j + 1 > ns)
{
ns = j + 1;
t = 3;
}
}
if(*(q+j+1) == 0 && os > ns)
{
if(j + 1 > ns)
{
if(t != 3)
{
for(t=os; t>ns; t--)
{
*(q+t) = *(p+t);
}
ns = os;
break;
}
}
t = 2;
}

j++;
}
i++;
}
for(t=ns; t>=0; t--)
printf("%d", *(q+t));
printf("\n%d", ns);
}
int main(void)
{
int a[30000] = {1}, b, c[30000]={0};

scanf("%d", &b);
qiuhe(b,a,c);

return 0;
}
再次感谢pathuang68和zouyuncheng
forhonor123 2011-07-25
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 zouyuncheng 的回复:]
1到50的阶乘各(包括50)是:31035053229546199656252032972759319953190362094566672920420940313
1到100的阶乘各(包括100)是:942690016837099792608598341244735398720707226139826724429383593056246782234795060234002940935991364……
[/Quote]
非常感谢,是我程序有问题,已解决。
forhonor123 2011-07-25
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 pathuang68 的回复:]
引用 5 楼 forhonor123 的回复:

引用 3 楼 pathuang68 的回复:
引用 2 楼 yq_118 的回复:

明显不对,大数的阶乘后面都是n个0。

这个到不是,楼主求的是1!+2!+... 100!的阶乘,而不是100!的阶乘。如果只是100!那后面自然有很多love了

程序错误。。。你总不是让我去改吧。。。。
unclear identifier……
[/Quote]
非常感谢,在你的提示下,我发现我程序执行到16时就错了,刚才和小狗同学的数据对比了一下,已经完成了,呵呵。
pathuang68 2011-07-25
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 forhonor123 的回复:]

引用 3 楼 pathuang68 的回复:
引用 2 楼 yq_118 的回复:

明显不对,大数的阶乘后面都是n个0。

这个到不是,楼主求的是1!+2!+... 100!的阶乘,而不是100!的阶乘。如果只是100!那后面自然有很多love了

程序错误。。。你总不是让我去改吧。。。。
unclear identifier reverse...
[/Quote]
程序没有用到任何很特别的函数,reverse是STL中的算法。程序绝对木有错滴,在给你之前俺再VS2010上试过了。你用什么编译器?具体出错信息是什么?

#include <time.h>可以去掉不要,是我原来用于计算需要多少时间的,但放在那里也不会出错。:)

用上面的程序算出来的结果是:

94269.........313

居然说那串数字中有非法字符。
玩笑 2011-07-25
  • 打赏
  • 举报
回复
1到50的阶乘各(包括50)是:31035053229546199656252032972759319953190362094566672920420940313
1到100的阶乘各(包括100)是:94269001683709979260859834124473539872070722613982672442938359305624678223479506023400294093599136466986609124347432647622826870038220556442336528920420940313
1到500的阶乘各(包括500)是:1222581999810786173488382263893486121736784649845260488587055662127413631697914209099541725989446667613701624271378831210621838417780811766002473336942870600195037012201905233810236995284666050368045972495314286948596890492959045138704466475196055082304091214424335155644013903958356823605973150159110295578782843348252925883263557585556478987722745938465211447729783160621865568392455888286712354379272785542107324774997192436923989074655546365212898701875799458234466791378320221140358905721655475503366304295011345436395868843079546378053608723961924505161575921825309198649451288200312309059880509012275371359184552944166761037071150384173845166703990330636505622758303549033598720775172343137459008549361297203752431405977559950082400276439557196120290170551660607313565028810793747453185145183036587639267895948090547733582550623337958494636037989666434209666688780729576638277517618320396232253506068607096479320263132522604054741925038640750661849690108363701190203548476572823422774327197718781800269558204647391176582851167312182026188795156620056856503340092247479478684738621107994804323593105039052556442336528920420940313
#include <stdio.h>
#include <stdlib.h>

typedef struct node {
int n;
struct node * next;
} NODE;

NODE * jc(int);
void print(NODE *);
void blj(NODE *, NODE *);
NODE * newnode(int n) ;

int main()
{
NODE * head = newnode(0);
NODE * temp = NULL;
int x = 0;
printf("输入计算多少内的阶乘之和:");
scanf("%d", &x);
for(int n = 1; n <= x; ++n){
temp = jc(n);
blj(head, temp);
print(temp);
//print(jc(n));
printf("\n");
}
printf("\n1到%d的阶乘各(包括%d)是:", x, x);
print(head);
printf("\n");
return 0;
}


void print(NODE * head) {
if(head) {
print(head->next);
printf("%1d", head->n);
free(head);
}
}

NODE * newnode(int n) {
NODE * head;
head = (NODE *)malloc(sizeof(NODE));
head->n = n;
head->next = NULL;
return head;
}

void jw(NODE * head, long n) {
if(n>0) {
int x = head->n + n%10;
head->n = x%10;
if((x>=10 || n>=10) && head->next == NULL) head->next = newnode(0);
jw(head->next, x/10);
jw(head->next, n/10);
}
}

void blj(NODE * head, NODE * temp) {
if(temp) {
jw(head, temp->n);
if(head->next == NULL && temp->next) head->next = newnode(0);
blj(head->next, temp->next);
//(head->next == NULL && temp->next) ? blj((head->next = newnode(0)), temp->next) : blj(head->next, temp->next);
}
}

NODE * lj(NODE * head, int n) {
if(head) {
lj(head->next, n);
long x = head->n * n;
head->n = 0;
jw(head, x);
}
return head;
}

NODE * jc(int n) {
return n==1 ? newnode(1) : lj(jc(n-1), n);
}


之前发过的代码,代码当初只是为了试递归和链表而写的,不是为了解决阶乘问题,因为效果不行
forhonor123 2011-07-24
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 pathuang68 的回复:]
引用 2 楼 yq_118 的回复:

明显不对,大数的阶乘后面都是n个0。

这个到不是,楼主求的是1!+2!+... 100!的阶乘,而不是100!的阶乘。如果只是100!那后面自然有很多love了
[/Quote]
程序错误。。。你总不是让我去改吧。。。。
unclear identifier reverse...
forhonor123 2011-07-24
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 pathuang68 的回复:]
参考下面的代码:

C/C++ code

#include <iostream>
#include <string>
#include <time.h>

using namespace std;
int COMPARE(string number1, string number2)
{
int j;

int length1 = number1.s……
[/Quote]
程序拷下了,我看看哈
pathuang68 2011-07-24
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 yq_118 的回复:]

明显不对,大数的阶乘后面都是n个0。
[/Quote]
这个到不是,楼主求的是1!+2!+... 100!的阶乘,而不是100!的阶乘。如果只是100!那后面自然有很多love了
stein42 2011-07-24
  • 打赏
  • 举报
回复
明显不对,大数的阶乘后面都是n个0。
pathuang68 2011-07-24
  • 打赏
  • 举报
回复
参考下面的代码:

#include <iostream>
#include <string>
#include <time.h>

using namespace std;
int COMPARE(string number1, string number2)
{
int j;

int length1 = number1.size();
int length2 = number2.size();

if(number1.size() == 0) number1 = "0";
if(number2.size() == 0) number2 = "0";

j = 0;
for(int i = 0; i < length1; ++i)
{
if(number1[i] == '0') ++j;
else break;
}
number1 = number1.substr(j);

j = 0;
for(int i = 0; i < length2; ++i)
{
if(number2[i] == '0') ++j;
else break;
}
number2 = number2.substr(j);

length1 = number1.size();
length2 = number2.size();

if(length1 > length2)
{
return 1;
}
else if(length1 == length2)
{
if(number1.compare(number2) > 0)
{
return 1;
}
else if(number1.compare(number2) == 0)
{
return 0;
}
else
{
return -1;
}
}
else
{
return -1;
}

return 0;
}


string PLUS(string number1,string number2)
{
int i;
int length1 = number1.size();
int length2 = number2.size();

string result="";

reverse(number1.begin(), number1.end());
reverse(number2.begin(), number2.end());

for(i = 0; i < length1 && i < length2; i++)
{
char c = (char)(number1[i] + number2[i] - 48);
result = result + c;
}

while(i < length1)
{
result = result + number1[i];
++i;
}

while(i < length2)
{
result = result + number2[i];
++i;
}

int carry = 0;
for(i = 0; i < (int)result.size(); ++i)
{
int value = result[i] - 48 + carry;
result[i] = (char)(value % 10 + 48);
carry = value / 10;
}

if(carry !=0 )
{
result = result + (char)(carry + 48);
}

for(i = result.size() - 1; i >= 0; i--)
{
if(result[i] != '0') break;
}

result = result.substr(0, i + 1);

reverse(result.begin(), result.end());
if(result.length() == 0) result = "0";
return result;
}


string MINUS(string number1,string number2)
{
int i;
string result = "";

int length1 = number1.size();
int length2 = number2.size();

if(COMPARE(number2,number1) > 0)
{
return "-" + MINUS(number2, number1);
}

reverse(number1.begin(),number1.end());
reverse(number2.begin(),number2.end());

for(i = 0; i < length1 && i < length2; i++)
{
char c = number1[i] - number2[i] + 48;
result = result + c;
}

if(i < length1)
{
for(; i < length1; i++)
{
result = result + number1[i];
}
}

int carry = 0;
for(i = 0; i < (int)result.length(); i++)
{
int value = result[i] - 48 + carry;
if(value < 0)
{
value = value + 10;
carry = -1;
}
else carry = 0;
result[i]=(char)(value + 48);
}

for(i = result.size() - 1; i >= 0; i--)
{
if(result[i] != '0')break;
}

result = result.substr(0, i+1);

reverse(result.begin(), result.end());
if(result.length()==0) result = "0";
return result;
}


string MULTIPLY(string number1, string number2)
{
int i, j;
int *iresult;
int length1 = number1.size();
int length2 = number2.size();
string result = "";

reverse(number1.begin(), number1.end());
reverse(number2.begin(), number2.end());

iresult = (int*)malloc(sizeof(int) * (length1 + length2 + 1));
memset(iresult, 0, sizeof(int) * (length1 + length2 + 1));

for(i = 0; i < length1; i++)
{
for(j = 0; j < length2; j++)
{
iresult[i+j] += ((number1[i] - 48) * (number2[j] - 48));
}
}

int carry = 0;
for(i = 0; i < length1 + length2; i++)
{
int value = iresult[i] + carry;
iresult[i] = value % 10;
carry = value / 10;
}

for(i = length1 + length2 - 1; i >= 0; i--)
{
if(iresult[i] != 0)break;
}

for(; i >= 0; i--)
{
result = result + (char)(iresult[i]+48);
}

free(iresult);

if(result == "") result = "0";
return result;
}

string factorial(string n)
{
string temp = "1";
string i;
for(i = "1"; COMPARE(i, n) <= 0; i = PLUS(i, "1"))
{
temp = MULTIPLY(temp, i);
}
return temp;
}

int main(void)
{
string i;
string result = "0";
string N = "100";
for(i = "1"; COMPARE(i, N) <= 0; i = PLUS(i, "1"))
{
result = PLUS(result, factorial(i));
}
cout << result << endl;

return 0;
}

你的结果应该是不正确的。

69,381

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧