数组是数据结构中最基本的结构形式,它是一种顺序式的结构,存储的是同一类型的数据。每个数组元素都拥有下标(index)和元素值(value),下标方便存取数据,而元素值就是被存储的数据。

    数组使用静态的内存空间配置方式。这也是数组的一个很不方便的地方,在经常需要重新分配数据的存储空间的应用上,往往使用数组就显得非常影响效率;而且,对数组的添加、删除、排序的操作也是比较麻烦以及低效的。

    在.net里提供了一种ArrayList的结构,在过去很长一段时间里,我经常会在需要使用集合对象的时候想到它(主要是受早先starter kits的影响),但是ArrayList还是由数组构成的,虽然它在添加元素,删除元素等方面比数组方便了,但是从效率上讲,毕竟它还是基于数组的结构。所谓换汤不换药。

    其实,今天我不是想来说数组怎么怎么不好的,而是发挥数组的一些优点,来作一些原本相对复杂的事情,比如,当我们需要计算一个阶乘,而计算结果又超出了我们的数据类型所能存储的范围。

目的:
    设计一个可以容纳40位数字的求n!的程序。

思路:
    首先,明确我们要解决的问题,在.net的数据结构中,整形数据类型的最大范围是-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807(0 到 18,446,744,073,709,551,615),而当我们计算的这个结果需要有40位,就没有适合的数据结构来存储这个数据。这个时候我们可以借助数组,预先声明一个大小为40的数组,负责存储每一个位数上的整数。
    接下来,就是程序设计的思路,聚个例子作为示范,假如我们要计算5!:

第一步:1!
数组内容

4

3

2

1

0

0

0

1


第二步:2!
数组内容

4

3

2

1

0

0

0

2*1


第三步:3!
数组内容

4

3

2

1

0

0

0

2*3


第二步:4!
数组内容

4

3

2

1

0

0

0

6*4


第二步:2!
数组内容

4

3

2

1

0

0

2*5

4*5


    很明显,我们需要做的就是对数组的每一个元素进行累积,超过10以后向前进一位。

程序源码:

  1数组的进一步使用_gitusing System;
  2数组的进一步使用_git
  3数组的进一步使用_gitnamespace DsPractice.Array.Factorial
  4数组的进一步使用_i++_04数组的进一步使用_数据_05数组的进一步使用_数组_06{
  5数组的进一步使用_i++_07数组的进一步使用_git_08    /**//// <summary>
  6数组的进一步使用_数据结构_09    /// 利用数组的方式求解指定数字的阶乘。
  7数组的进一步使用_数组_10    /// </summary>

  8数组的进一步使用_数据结构_09    class Demo
  9数组的进一步使用_i++_07数组的进一步使用_git_08    数组的进一步使用_数组_06{
 10数组的进一步使用_i++_07数组的进一步使用_git_08        /**//// <summary>
 11数组的进一步使用_数据结构_09        /// 应用程序的主入口点。
 12数组的进一步使用_数组_10        /// </summary>

 13数组的进一步使用_数据结构_09        [STAThread]
 14数组的进一步使用_数据结构_09        static void Main(string[] args)
 15数组的进一步使用_i++_07数组的进一步使用_git_08        数组的进一步使用_数组_06{
 16数组的进一步使用_数据结构_09            DoCalculate();
 17数组的进一步使用_数组_10        }

 18数组的进一步使用_数据结构_09
 19数组的进一步使用_数据结构_09        public static void DoCalculate()
 20数组的进一步使用_i++_07数组的进一步使用_git_08        数组的进一步使用_数组_06{
 21数组的进一步使用_数据结构_09            // 选择算法
 22数组的进一步使用_数据结构_09            int type = new NumberReader("Please choose an algorithm: \r\n1. Type A;\r\n2. Type B.", 12).GetNumber();
 23数组的进一步使用_数据结构_09            
 24数组的进一步使用_数据结构_09            // 获取要计算的数字
 25数组的进一步使用_数据结构_09            int number = new NumberReader("Please input a number to calculate factorial:").GetNumber();
 26数组的进一步使用_数据结构_09
 27数组的进一步使用_数据结构_09            // 获得存放计算结果的数组的长度
 28数组的进一步使用_数据结构_09            int length = new NumberReader("Please input a number of array digit:").GetNumber();
 29数组的进一步使用_数据结构_09
 30数组的进一步使用_数据结构_09            // 创建一个阶乘计算对象
 31数组的进一步使用_数据结构_09            Factorial factorial = new Factorial(number, length);
 32数组的进一步使用_数据结构_09
 33数组的进一步使用_数据结构_09            // 计算并显示结果
 34数组的进一步使用_数据结构_09            factorial.ShowResult(type);
 35数组的进一步使用_数据结构_09
 36数组的进一步使用_数据结构_09            // 提示用户继续或结束
 37数组的进一步使用_数据结构_09            int res = new NumberReader("Do you wannar try again?\r\n1. Yes;\r\n2. No.", 12).GetNumber();
 38数组的进一步使用_数据结构_09
 39数组的进一步使用_数据结构_09            // 如果继续执行,则返回重新调用
 40数组的进一步使用_数据结构_09            if (res == 1)
 41数组的进一步使用_i++_07数组的进一步使用_git_08            数组的进一步使用_数组_06{
 42数组的进一步使用_数据结构_09                DoCalculate();
 43数组的进一步使用_数组_10            }

 44数组的进一步使用_数组_10        }

 45数组的进一步使用_数据结构_09
 46数组的进一步使用_数据结构_09        public class NumberReader
 47数组的进一步使用_i++_07数组的进一步使用_git_08        数组的进一步使用_数组_06{
 48数组的进一步使用_数据结构_09            private int _min = -999;
 49数组的进一步使用_数据结构_09
 50数组的进一步使用_数据结构_09            private int _max = 999;
 51数组的进一步使用_数据结构_09
 52数组的进一步使用_数据结构_09            private string _strNumber;
 53数组的进一步使用_数据结构_09
 54数组的进一步使用_数据结构_09            public NumberReader(string todo)
 55数组的进一步使用_i++_07数组的进一步使用_git_08            数组的进一步使用_数组_06{
 56数组的进一步使用_数据结构_09                // 提示输入数字
 57数组的进一步使用_数据结构_09                Console.WriteLine(todo);
 58数组的进一步使用_数据结构_09                // 获取数字字符串
 59数组的进一步使用_数据结构_09                _strNumber = Console.ReadLine();
 60数组的进一步使用_数组_10            }

 61数组的进一步使用_数据结构_09
 62数组的进一步使用_数据结构_09            public NumberReader(string todo, int min, int max) : this(todo)
 63数组的进一步使用_i++_07数组的进一步使用_git_08            数组的进一步使用_数组_06{
 64数组的进一步使用_数据结构_09                this._max = max;
 65数组的进一步使用_数据结构_09                this._min = min;
 66数组的进一步使用_数组_10            }

 67数组的进一步使用_数据结构_09
 68数组的进一步使用_数据结构_09            public int GetNumber()
 69数组的进一步使用_i++_07数组的进一步使用_git_08            数组的进一步使用_数组_06{
 70数组的进一步使用_数据结构_09                int number = 0;
 71数组的进一步使用_数据结构_09
 72数组的进一步使用_数据结构_09                try
 73数组的进一步使用_i++_07数组的进一步使用_git_08                数组的进一步使用_数组_06{
 74数组的进一步使用_数据结构_09                    number = int.Parse(this._strNumber);
 75数组的进一步使用_数据结构_09
 76数组的进一步使用_数据结构_09                    if (number > this._max || number < this._min)
 77数组的进一步使用_i++_07数组的进一步使用_git_08                    数组的进一步使用_数组_06{
 78数组的进一步使用_数据结构_09                        throw new Exception();
 79数组的进一步使用_数组_10                    }

 80数组的进一步使用_数组_10                }

 81数组的进一步使用_数据结构_09                catch (System.FormatException formatEx)
 82数组的进一步使用_i++_07数组的进一步使用_git_08                数组的进一步使用_数组_06{
 83数组的进一步使用_数据结构_09                    number = new NumberReader("Input format error! Please input again: ").GetNumber();
 84数组的进一步使用_数组_10                }

 85数组的进一步使用_数据结构_09                catch (System.Exception ex)
 86数组的进一步使用_i++_07数组的进一步使用_git_08                数组的进一步使用_数组_06{
 87数组的进一步使用_数据结构_09                    number = new NumberReader("Input error! Please input again: ").GetNumber();
 88数组的进一步使用_数组_10                }

 89数组的进一步使用_数据结构_09
 90数组的进一步使用_数据结构_09                return number;
 91数组的进一步使用_数组_10            }

 92数组的进一步使用_数组_10        }

 93数组的进一步使用_数据结构_09
 94数组的进一步使用_数据结构_09        public class Factorial
 95数组的进一步使用_i++_07数组的进一步使用_git_08        数组的进一步使用_数组_06{
 96数组的进一步使用_数据结构_09            // 要计算的数字
 97数组的进一步使用_数据结构_09            private int _number = 0;
 98数组的进一步使用_数据结构_09
 99数组的进一步使用_数据结构_09            // 结果的位数
100数组的进一步使用_数据结构_09            private int _digit = 1;
101数组的进一步使用_数据结构_09
102数组的进一步使用_数据结构_09            // 存放结果的数组
103数组的进一步使用_数据结构_09            private int[] _data = null;
104数组的进一步使用_数据结构_09
105数组的进一步使用_数据结构_09            // 复杂度标记
106数组的进一步使用_数据结构_09            private int _complex = 0;
107数组的进一步使用_数据结构_09
108数组的进一步使用_数据结构_09            public Factorial(int number) : this(number, 40)
109数组的进一步使用_i++_07数组的进一步使用_git_08            数组的进一步使用_数组_06{}
110数组的进一步使用_数据结构_09
111数组的进一步使用_数据结构_09            public Factorial(int number, int digit)
112数组的进一步使用_i++_07数组的进一步使用_git_08            数组的进一步使用_数组_06{
113数组的进一步使用_数据结构_09                this._number = number;
114数组的进一步使用_数据结构_09                this._data = new int[digit];
115数组的进一步使用_数据结构_09                this._data[0= 1;
116数组的进一步使用_数组_10            }

117数组的进一步使用_数据结构_09
118数组的进一步使用_数据结构_09            private void CalculateA()
119数组的进一步使用_i++_07数组的进一步使用_git_08            数组的进一步使用_数组_06{
120数组的进一步使用_数据结构_09                try
121数组的进一步使用_i++_07数组的进一步使用_git_08                数组的进一步使用_数组_06{
122数组的进一步使用_数据结构_09                    for (int i=1; i<=this._number; i++)
123数组的进一步使用_i++_07数组的进一步使用_git_08                    数组的进一步使用_数组_06{
124数组的进一步使用_数据结构_09                        int digit;
125数组的进一步使用_数据结构_09                        for (digit=this._data.GetLength(0); digit>0; digit--)
126数组的进一步使用_i++_07数组的进一步使用_git_08                        数组的进一步使用_数组_06{
127数组的进一步使用_数据结构_09                            this._complex ++;
128数组的进一步使用_数据结构_09                            this._data[digit-1= this._data[digit-1* i;
129数组的进一步使用_数据结构_09                        
130数组的进一步使用_数据结构_09                            if (this._data[digit-1>= 10)
131数组的进一步使用_i++_07数组的进一步使用_git_08                            数组的进一步使用_数组_06{                            
132数组的进一步使用_数据结构_09                                for (int j=digit; j<this._data.GetLength(0); j++)
133数组的进一步使用_i++_07数组的进一步使用_git_08                                数组的进一步使用_数组_06{
134数组的进一步使用_数据结构_09                                    this._complex ++;
135数组的进一步使用_数据结构_09                                    this._data[j] += this._data[j-1/ 10;
136数组的进一步使用_数据结构_09                                    
137数组的进一步使用_数据结构_09                                    this._complex ++;
138数组的进一步使用_数据结构_09                                    this._data[j-1= this._data[j-1% 10;
139数组的进一步使用_数组_10                                }

140数组的进一步使用_数组_10                            }

141数组的进一步使用_数组_10                        }

142数组的进一步使用_数组_10                    }

143数组的进一步使用_数组_10                }

144数组的进一步使用_数据结构_09                catch
145数组的进一步使用_i++_07数组的进一步使用_git_08                数组的进一步使用_数组_06{
146数组的进一步使用_数据结构_09                    return;
147数组的进一步使用_数组_10                }

148数组的进一步使用_数组_10            }

149数组的进一步使用_数据结构_09
150数组的进一步使用_数据结构_09            private void CalculateB()
151数组的进一步使用_i++_07数组的进一步使用_git_08            数组的进一步使用_数组_06{
152数组的进一步使用_数据结构_09                // 初始位数为个位,也就是1
153数组的进一步使用_数据结构_09                try
154数组的进一步使用_i++_07数组的进一步使用_git_08                数组的进一步使用_数组_06{
155数组的进一步使用_数据结构_09                    for (int i=1; i<=this._number; i++)
156数组的进一步使用_i++_07数组的进一步使用_git_08                    数组的进一步使用_数组_06{
157数组的进一步使用_数据结构_09                        // 数组元素的运算
158数组的进一步使用_数据结构_09                        for (int j=1; j<=this._digit; j++)
159数组的进一步使用_i++_07数组的进一步使用_git_08                        数组的进一步使用_数组_06{
160数组的进一步使用_数据结构_09                            this._complex ++;
161数组的进一步使用_数据结构_09                            this._data[j-1*= i;
162数组的进一步使用_数组_10                        }

163数组的进一步使用_数据结构_09                        // 从个位开始,根据每一位的数字判断是否需要进位
164数组的进一步使用_数据结构_09                        for (int j=1; j<=this._digit; j++)
165数组的进一步使用_i++_07数组的进一步使用_git_08                        数组的进一步使用_数组_06{
166数组的进一步使用_数据结构_09                            // 如果当前位大于等于10,则依次向前进一位
167数组的进一步使用_数据结构_09                            if (this._data[j-1>= 10)
168数组的进一步使用_i++_07数组的进一步使用_git_08                            数组的进一步使用_数组_06{
169数组的进一步使用_数据结构_09                                // 从当前位开始,根据每一位的数字进行进位
170数组的进一步使用_数据结构_09                                for (int m=j; m<=this._digit; m++)
171数组的进一步使用_i++_07数组的进一步使用_git_08                                数组的进一步使用_数组_06{
172数组的进一步使用_数据结构_09                                    if (this._data[this._digit-1>= 10)
173数组的进一步使用_i++_07数组的进一步使用_git_08                                    数组的进一步使用_数组_06{
174数组的进一步使用_数据结构_09                                        this._complex ++;
175数组的进一步使用_数据结构_09                                        this._digit++;
176数组的进一步使用_数组_10                                    }

177数组的进一步使用_数据结构_09
178数组的进一步使用_数据结构_09                                    this._complex ++;
179数组的进一步使用_数据结构_09                                    this._data[m] += this._data[m-1/ 10;
180数组的进一步使用_数据结构_09
181数组的进一步使用_数据结构_09                                    this._complex ++;
182数组的进一步使用_数据结构_09                                    this._data[m-1= this._data[m-1% 10;
183数组的进一步使用_数组_10                                }

184数组的进一步使用_数组_10                            }

185数组的进一步使用_数组_10                        }

186数组的进一步使用_数组_10                    }

187数组的进一步使用_数组_10                }

188数组的进一步使用_数据结构_09                catch
189数组的进一步使用_i++_07数组的进一步使用_git_08                数组的进一步使用_数组_06{
190数组的进一步使用_数据结构_09                    return;
191数组的进一步使用_数组_10                }

192数组的进一步使用_数组_10            }

193数组的进一步使用_数据结构_09
194数组的进一步使用_数据结构_09            public void ShowResult(int type)
195数组的进一步使用_i++_07数组的进一步使用_git_08            数组的进一步使用_数组_06{
196数组的进一步使用_数据结构_09                Console.Write("Result is ");
197数组的进一步使用_数据结构_09                switch(type)
198数组的进一步使用_i++_07数组的进一步使用_git_08                数组的进一步使用_数组_06{
199数组的进一步使用_数据结构_09                    case 1:
200数组的进一步使用_数据结构_09                        this.CalculateA();
201数组的进一步使用_数据结构_09
202数组的进一步使用_数据结构_09                        for (int i=this._data.GetLength(0)-1; i>=0; i--)
203数组的进一步使用_i++_07数组的进一步使用_git_08                        数组的进一步使用_数组_06{
204数组的进一步使用_数据结构_09                            Console.Write(this._data[i].ToString());
205数组的进一步使用_数组_10                        }

206数组的进一步使用_数据结构_09
207数组的进一步使用_数据结构_09                        break;
208数组的进一步使用_数据结构_09                    default:
209数组的进一步使用_数据结构_09                        this.CalculateB();
210数组的进一步使用_数据结构_09
211数组的进一步使用_数据结构_09                        for (int i=this._digit-1; i>=0; i--)
212数组的进一步使用_i++_07数组的进一步使用_git_08                        数组的进一步使用_数组_06{
213数组的进一步使用_数据结构_09                            Console.Write(this._data[i].ToString());
214数组的进一步使用_数组_10                        }

215数组的进一步使用_数据结构_09
216数组的进一步使用_数据结构_09                        break;
217数组的进一步使用_数组_10                }

218数组的进一步使用_数据结构_09                Console.WriteLine();
219数组的进一步使用_数据结构_09                Console.WriteLine("Code complex is " + this._complex.ToString());
220数组的进一步使用_数组_10            }

221数组的进一步使用_数组_10        }

222数组的进一步使用_数组_10    }

223数组的进一步使用_i++_297}

224数组的进一步使用_git

    以上源码提供了两种算法,各自的复杂度都可以很清楚的查看到,如果有兴趣的朋友可以再提供一些其他的更有效的算法。