菜鸟QiFang学数据结构系列(一):一维数组的高级应用--一个可容纳超多位数的求N!的程序!
Posted on 2005-01-08 10:40 菜鸟QiFang 阅读(1239) 评论(0) 编辑 收藏 举报
老菜QiFang决心改变以往的菜鸟形象,也想过过大虾瘾,于近日重新入关,闭门研究“设计模式”与“数据结构”,还望各路老鸟给予关照!让老菜早日成为老鸟! *^_^*
发现一维数组还有这种用法的,大家请看以下题目:
教材:《数据结构》C语言版 清华大学出版社的
题目:设计一个可容纳超多位数的求N!的程序。
构思:
1、N!的求法大家都清楚吧,老菜再啰嗦一下,比如:1!=1*1; 2!=2*1; 3!=3*2*1 ....依些类推。
2、声明一个足够大的数组Data[] 来存放计算出来的结果,因为现有的任何数值类都放不下这么长或更长的计算结果。
3、我们来研究一个规律:
a、 1!=1*1=1
2!=1=2
3!=3*2=6
4!=4*6=24
5!=5*24=120
//上面这步关键,看下面说明:
// 数组: 4 3 2 1 4 3 2 1
// 数值: 0 0 2*5 4*5 相当于看做是24*5,如: 0 0 10 20
//我们给每个数组只存放1位数值时,就得将现有数组里超过10的值给挪动一位,结果就变成了:
// 数组: 4 3 2 1
// 数值: 0 1 2 0
// 最后一步就是循环打印出数组内有值的数组,以最高索引值排列下来!
b、具体思路是:首先先将Data数组做初始值。再令第一位数值为1,位数也为1。再将每次相乘的乘积存回数组中。并循环处理每个数组中超过10的数,若数值超过10,刚将位数加1,原来的数除以10,商数加前一位数的数值后存回前一位数的数组中,再将余数存回原来位数的数组中。最后根据当前位数依次打印出数组里的值。 ----- 这段摘自书中内容
先看一段代码就明白了:
5、调用方法:Method1(200,100); //求100!的值结果为:195662859738407857961118354931666080074342886499720644995417374332204872604804112678108355178695515232661307223758251185210916864000000000000000000000000
共有一百五十几位!
6、菜鸟语言组织能力较差,看不懂的可以发出评论,让各路老鸟们帮忙了,呵呵.....
发现一维数组还有这种用法的,大家请看以下题目:
教材:《数据结构》C语言版 清华大学出版社的
题目:设计一个可容纳超多位数的求N!的程序。
构思:
1、N!的求法大家都清楚吧,老菜再啰嗦一下,比如:1!=1*1; 2!=2*1; 3!=3*2*1 ....依些类推。
2、声明一个足够大的数组Data[] 来存放计算出来的结果,因为现有的任何数值类都放不下这么长或更长的计算结果。
3、我们来研究一个规律:
a、 1!=1*1=1
2!=1=2
3!=3*2=6
4!=4*6=24
5!=5*24=120
//上面这步关键,看下面说明:
// 数组: 4 3 2 1 4 3 2 1
// 数值: 0 0 2*5 4*5 相当于看做是24*5,如: 0 0 10 20
//我们给每个数组只存放1位数值时,就得将现有数组里超过10的值给挪动一位,结果就变成了:
// 数组: 4 3 2 1
// 数值: 0 1 2 0
// 最后一步就是循环打印出数组内有值的数组,以最高索引值排列下来!
b、具体思路是:首先先将Data数组做初始值。再令第一位数值为1,位数也为1。再将每次相乘的乘积存回数组中。并循环处理每个数组中超过10的数,若数值超过10,刚将位数加1,原来的数除以10,商数加前一位数的数值后存回前一位数的数组中,再将余数存回原来位数的数组中。最后根据当前位数依次打印出数组里的值。 ----- 这段摘自书中内容
先看一段代码就明白了:
/// <summary>
/// 计算N!的程序
/// </summary>
/// <param name="length">存放计算结果数组的大小</param>
/// <param name="number">N的值</param>
private void Method1(int length,int number)
{
int[] Data = new int[length];
int Digit = 1; //当前数组计算位置,从1开始。
int i,j,r,k;
try
{
//给数组赋初值,都为0
for(i=1;i<length;i++)
{
Data[i] = 0;
}
Data[0] = 1;
Data[1] = 1;
for(i=1;i<number;i++)
{
//计算当前N值的运算
for(j=1;j<=Digit;j++)
Data[j] *= i;
for(j=1;j<=Digit;j++)
{
//当数组中的值大于10的时候,
if (Data[j] > 10)
{
for(r=1;r<=Digit;r++)
{
if (Data[Digit]>10)
Digit ++; //数组下标加1
//前一位的数组的值=前一位数组的值 + 此位数组的值 / 10
Data[r+1] += Data[r] / 10;
//此位数组的值 = 此位数组的值 / 10,再取余数
Data[r] = Data[r] % 10;
}
}
}
Console.Write(i.ToString() + "!=");
//根据现在数组的下标值,循环打印出N!的结果值。
for(k=Digit;k>0;k--)
Console.Write(Data[k]);
Console.Write("\r\n");
}
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
/// 计算N!的程序
/// </summary>
/// <param name="length">存放计算结果数组的大小</param>
/// <param name="number">N的值</param>
private void Method1(int length,int number)
{
int[] Data = new int[length];
int Digit = 1; //当前数组计算位置,从1开始。
int i,j,r,k;
try
{
//给数组赋初值,都为0
for(i=1;i<length;i++)
{
Data[i] = 0;
}
Data[0] = 1;
Data[1] = 1;
for(i=1;i<number;i++)
{
//计算当前N值的运算
for(j=1;j<=Digit;j++)
Data[j] *= i;
for(j=1;j<=Digit;j++)
{
//当数组中的值大于10的时候,
if (Data[j] > 10)
{
for(r=1;r<=Digit;r++)
{
if (Data[Digit]>10)
Digit ++; //数组下标加1
//前一位的数组的值=前一位数组的值 + 此位数组的值 / 10
Data[r+1] += Data[r] / 10;
//此位数组的值 = 此位数组的值 / 10,再取余数
Data[r] = Data[r] % 10;
}
}
}
Console.Write(i.ToString() + "!=");
//根据现在数组的下标值,循环打印出N!的结果值。
for(k=Digit;k>0;k--)
Console.Write(Data[k]);
Console.Write("\r\n");
}
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
5、调用方法:Method1(200,100); //求100!的值结果为:195662859738407857961118354931666080074342886499720644995417374332204872604804112678108355178695515232661307223758251185210916864000000000000000000000000
共有一百五十几位!
6、菜鸟语言组织能力较差,看不懂的可以发出评论,让各路老鸟们帮忙了,呵呵.....