数组的进一步使用
數(shù)組是數(shù)據(jù)結(jié)構(gòu)中最基本的結(jié)構(gòu)形式,它是一種順序式的結(jié)構(gòu),存儲的是同一類型的數(shù)據(jù)。每個數(shù)組元素都擁有下標(index)和元素值(value),下標方便存取數(shù)據(jù),而元素值就是被存儲的數(shù)據(jù)。
??? 數(shù)組使用靜態(tài)的內(nèi)存空間配置方式。這也是數(shù)組的一個很不方便的地方,在經(jīng)常需要重新分配數(shù)據(jù)的存儲空間的應用上,往往使用數(shù)組就顯得非常影響效率;而且,對數(shù)組的添加、刪除、排序的操作也是比較麻煩以及低效的。
??? 在.net里提供了一種ArrayList的結(jié)構(gòu),在過去很長一段時間里,我經(jīng)常會在需要使用集合對象的時候想到它(主要是受早先starter kits的影響),但是ArrayList還是由數(shù)組構(gòu)成的,雖然它在添加元素,刪除元素等方面比數(shù)組方便了,但是從效率上講,畢竟它還是基于數(shù)組的結(jié)構(gòu)。所謂換湯不換藥。
??? 其實,今天我不是想來說數(shù)組怎么怎么不好的,而是發(fā)揮數(shù)組的一些優(yōu)點,來作一些原本相對復雜的事情,比如,當我們需要計算一個階乘,而計算結(jié)果又超出了我們的數(shù)據(jù)類型所能存儲的范圍。
目的:
??? 設計一個可以容納40位數(shù)字的求n!的程序。
思路:
??? 首先,明確我們要解決的問題,在.net的數(shù)據(jù)結(jié)構(gòu)中,整形數(shù)據(jù)類型的最大范圍是-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807(0 到 18,446,744,073,709,551,615),而當我們計算的這個結(jié)果需要有40位,就沒有適合的數(shù)據(jù)結(jié)構(gòu)來存儲這個數(shù)據(jù)。這個時候我們可以借助數(shù)組,預先聲明一個大小為40的數(shù)組,負責存儲每一個位數(shù)上的整數(shù)。
??? 接下來,就是程序設計的思路,聚個例子作為示范,假如我們要計算5!:
第一步:1!
數(shù)組內(nèi)容
??2
??3namespace?DsPractice.Array.Factorial
??4{
??5????/**////?<summary>
??6????///?利用數(shù)組的方式求解指定數(shù)字的階乘。
??7????///?</summary>
??8????class?Demo
??9????{
?10????????/**////?<summary>
?11????????///?應用程序的主入口點。
?12????????///?</summary>
?13????????[STAThread]
?14????????static?void?Main(string[]?args)
?15????????{
?16????????????DoCalculate();
?17????????}
?18
?19????????public?static?void?DoCalculate()
?20????????{
?21????????????//?選擇算法
?22????????????int?type?=?new?NumberReader("Please choose an algorithm: /r/n1. Type A;/r/n2. Type B.",?1,?2).GetNumber();
?23????????????
?24????????????//?獲取要計算的數(shù)字
?25????????????int?number?=?new?NumberReader("Please input a number to calculate factorial:").GetNumber();
?26
?27????????????//?獲得存放計算結(jié)果的數(shù)組的長度
?28????????????int?length?=?new?NumberReader("Please input a number of array digit:").GetNumber();
?29
?30????????????//?創(chuàng)建一個階乘計算對象
?31????????????Factorial?factorial?=?new?Factorial(number,?length);
?32
?33????????????//?計算并顯示結(jié)果
?34????????????factorial.ShowResult(type);
?35
?36????????????//?提示用戶繼續(xù)或結(jié)束
?37????????????int?res?=?new?NumberReader("Do you wannar try again?/r/n1. Yes;/r/n2. No.",?1,?2).GetNumber();
?38
?39????????????//?如果繼續(xù)執(zhí)行,則返回重新調(diào)用
?40????????????if?(res?==?1)
?41????????????{
?42????????????????DoCalculate();
?43????????????}
?44????????}
?45
?46????????public?class?NumberReader
?47????????{
?48????????????private?int?_min?=?-999;
?49
?50????????????private?int?_max?=?999;
?51
?52????????????private?string?_strNumber;
?53
?54????????????public?NumberReader(string?todo)
?55????????????{
?56????????????????//?提示輸入數(shù)字
?57????????????????Console.WriteLine(todo);
?58????????????????//?獲取數(shù)字字符串
?59????????????????_strNumber?=?Console.ReadLine();
?60????????????}
?61
?62????????????public?NumberReader(string?todo,?int?min,?int?max)?:?this(todo)
?63????????????{
?64????????????????this._max?=?max;
?65????????????????this._min?=?min;
?66????????????}
?67
?68????????????public?int?GetNumber()
?69????????????{
?70????????????????int?number?=?0;
?71
?72????????????????try
?73????????????????{
?74????????????????????number?=?int.Parse(this._strNumber);
?75
?76????????????????????if?(number?>?this._max?||?number?<?this._min)
?77????????????????????{
?78????????????????????????throw?new?Exception();
?79????????????????????}
?80????????????????}
?81????????????????catch?(System.FormatException?formatEx)
?82????????????????{
?83????????????????????number?=?new?NumberReader("Input format error! Please input again: ").GetNumber();
?84????????????????}
?85????????????????catch?(System.Exception?ex)
?86????????????????{
?87????????????????????number?=?new?NumberReader("Input error! Please input again: ").GetNumber();
?88????????????????}
?89
?90????????????????return?number;
?91????????????}
?92????????}
?93
?94????????public?class?Factorial
?95????????{
?96????????????//?要計算的數(shù)字
?97????????????private?int?_number?=?0;
?98
?99????????????//?結(jié)果的位數(shù)
100????????????private?int?_digit?=?1;
101
102????????????//?存放結(jié)果的數(shù)組
103????????????private?int[]?_data?=?null;
104
105????????????//?復雜度標記
106????????????private?int?_complex?=?0;
107
108????????????public?Factorial(int?number)?:?this(number,?40)
109????????????{}
110
111????????????public?Factorial(int?number,?int?digit)
112????????????{
113????????????????this._number?=?number;
114????????????????this._data?=?new?int[digit];
115????????????????this._data[0]?=?1;
116????????????}
117
118????????????private?void?CalculateA()
119????????????{
120????????????????try
121????????????????{
122????????????????????for?(int?i=1;?i<=this._number;?i++)
123????????????????????{
124????????????????????????int?digit;
125????????????????????????for?(digit=this._data.GetLength(0);?digit>0;?digit--)
126????????????????????????{
127????????????????????????????this._complex?++;
128????????????????????????????this._data[digit-1]?=?this._data[digit-1]?*?i;
129????????????????????????
130????????????????????????????if?(this._data[digit-1]?>=?10)
131????????????????????????????{????????????????????????????
132????????????????????????????????for?(int?j=digit;?j<this._data.GetLength(0);?j++)
133????????????????????????????????{
134????????????????????????????????????this._complex?++;
135????????????????????????????????????this._data[j]?+=?this._data[j-1]?/?10;
136????????????????????????????????????
137????????????????????????????????????this._complex?++;
138????????????????????????????????????this._data[j-1]?=?this._data[j-1]?%?10;
139????????????????????????????????}
140????????????????????????????}
141????????????????????????}
142????????????????????}
143????????????????}
144????????????????catch
145????????????????{
146????????????????????return;
147????????????????}
148????????????}
149
150????????????private?void?CalculateB()
151????????????{
152????????????????//?初始位數(shù)為個位,也就是1
153????????????????try
154????????????????{
155????????????????????for?(int?i=1;?i<=this._number;?i++)
156????????????????????{
157????????????????????????//?數(shù)組元素的運算
158????????????????????????for?(int?j=1;?j<=this._digit;?j++)
159????????????????????????{
160????????????????????????????this._complex?++;
161????????????????????????????this._data[j-1]?*=?i;
162????????????????????????}
163????????????????????????//?從個位開始,根據(jù)每一位的數(shù)字判斷是否需要進位
164????????????????????????for?(int?j=1;?j<=this._digit;?j++)
165????????????????????????{
166????????????????????????????//?如果當前位大于等于10,則依次向前進一位
167????????????????????????????if?(this._data[j-1]?>=?10)
168????????????????????????????{
169????????????????????????????????//?從當前位開始,根據(jù)每一位的數(shù)字進行進位
170????????????????????????????????for?(int?m=j;?m<=this._digit;?m++)
171????????????????????????????????{
172????????????????????????????????????if?(this._data[this._digit-1]?>=?10)
173????????????????????????????????????{
174????????????????????????????????????????this._complex?++;
175????????????????????????????????????????this._digit++;
176????????????????????????????????????}
177
178????????????????????????????????????this._complex?++;
179????????????????????????????????????this._data[m]?+=?this._data[m-1]?/?10;
180
181????????????????????????????????????this._complex?++;
182????????????????????????????????????this._data[m-1]?=?this._data[m-1]?%?10;
183????????????????????????????????}
184????????????????????????????}
185????????????????????????}
186????????????????????}
187????????????????}
188????????????????catch
189????????????????{
190????????????????????return;
191????????????????}
192????????????}
193
194????????????public?void?ShowResult(int?type)
195????????????{
196????????????????Console.Write("Result?is?");
197????????????????switch(type)
198????????????????{
199????????????????????case?1:
200????????????????????????this.CalculateA();
201
202????????????????????????for?(int?i=this._data.GetLength(0)-1;?i>=0;?i--)
203????????????????????????{
204????????????????????????????Console.Write(this._data[i].ToString());
205????????????????????????}
206
207????????????????????????break;
208????????????????????default:
209????????????????????????this.CalculateB();
210
211????????????????????????for?(int?i=this._digit-1;?i>=0;?i--)
212????????????????????????{
213????????????????????????????Console.Write(this._data[i].ToString());
214????????????????????????}
215
216????????????????????????break;
217????????????????}
218????????????????Console.WriteLine();
219????????????????Console.WriteLine("Code?complex?is?"?+?this._complex.ToString());
220????????????}
221????????}
222????}
223}
224
??? 數(shù)組使用靜態(tài)的內(nèi)存空間配置方式。這也是數(shù)組的一個很不方便的地方,在經(jīng)常需要重新分配數(shù)據(jù)的存儲空間的應用上,往往使用數(shù)組就顯得非常影響效率;而且,對數(shù)組的添加、刪除、排序的操作也是比較麻煩以及低效的。
??? 在.net里提供了一種ArrayList的結(jié)構(gòu),在過去很長一段時間里,我經(jīng)常會在需要使用集合對象的時候想到它(主要是受早先starter kits的影響),但是ArrayList還是由數(shù)組構(gòu)成的,雖然它在添加元素,刪除元素等方面比數(shù)組方便了,但是從效率上講,畢竟它還是基于數(shù)組的結(jié)構(gòu)。所謂換湯不換藥。
??? 其實,今天我不是想來說數(shù)組怎么怎么不好的,而是發(fā)揮數(shù)組的一些優(yōu)點,來作一些原本相對復雜的事情,比如,當我們需要計算一個階乘,而計算結(jié)果又超出了我們的數(shù)據(jù)類型所能存儲的范圍。
目的:
??? 設計一個可以容納40位數(shù)字的求n!的程序。
思路:
??? 首先,明確我們要解決的問題,在.net的數(shù)據(jù)結(jié)構(gòu)中,整形數(shù)據(jù)類型的最大范圍是-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807(0 到 18,446,744,073,709,551,615),而當我們計算的這個結(jié)果需要有40位,就沒有適合的數(shù)據(jù)結(jié)構(gòu)來存儲這個數(shù)據(jù)。這個時候我們可以借助數(shù)組,預先聲明一個大小為40的數(shù)組,負責存儲每一個位數(shù)上的整數(shù)。
??? 接下來,就是程序設計的思路,聚個例子作為示范,假如我們要計算5!:
第一步:1!
數(shù)組內(nèi)容
| 4 | 3 | 2 | 1 |
| 0 | 0 | 0 | 1 |
第二步:2!
數(shù)組內(nèi)容
| 4 | 3 | 2 | 1 |
| 0 | 0 | 0 | 2*1 |
第三步:3!
數(shù)組內(nèi)容
| 4 | 3 | 2 | 1 |
| 0 | 0 | 0 | 2*3 |
第二步:4!
數(shù)組內(nèi)容
| 4 | 3 | 2 | 1 |
| 0 | 0 | 0 | 6*4 |
第二步:2!
數(shù)組內(nèi)容
| 4 | 3 | 2 | 1 |
| 0 | 0 | 2*5 | 4*5 |
??? 很明顯,我們需要做的就是對數(shù)組的每一個元素進行累積,超過10以后向前進一位。
程序源碼:
?
??1using?System;??2
??3namespace?DsPractice.Array.Factorial
??4{
??5????/**////?<summary>
??6????///?利用數(shù)組的方式求解指定數(shù)字的階乘。
??7????///?</summary>
??8????class?Demo
??9????{
?10????????/**////?<summary>
?11????????///?應用程序的主入口點。
?12????????///?</summary>
?13????????[STAThread]
?14????????static?void?Main(string[]?args)
?15????????{
?16????????????DoCalculate();
?17????????}
?18
?19????????public?static?void?DoCalculate()
?20????????{
?21????????????//?選擇算法
?22????????????int?type?=?new?NumberReader("Please choose an algorithm: /r/n1. Type A;/r/n2. Type B.",?1,?2).GetNumber();
?23????????????
?24????????????//?獲取要計算的數(shù)字
?25????????????int?number?=?new?NumberReader("Please input a number to calculate factorial:").GetNumber();
?26
?27????????????//?獲得存放計算結(jié)果的數(shù)組的長度
?28????????????int?length?=?new?NumberReader("Please input a number of array digit:").GetNumber();
?29
?30????????????//?創(chuàng)建一個階乘計算對象
?31????????????Factorial?factorial?=?new?Factorial(number,?length);
?32
?33????????????//?計算并顯示結(jié)果
?34????????????factorial.ShowResult(type);
?35
?36????????????//?提示用戶繼續(xù)或結(jié)束
?37????????????int?res?=?new?NumberReader("Do you wannar try again?/r/n1. Yes;/r/n2. No.",?1,?2).GetNumber();
?38
?39????????????//?如果繼續(xù)執(zhí)行,則返回重新調(diào)用
?40????????????if?(res?==?1)
?41????????????{
?42????????????????DoCalculate();
?43????????????}
?44????????}
?45
?46????????public?class?NumberReader
?47????????{
?48????????????private?int?_min?=?-999;
?49
?50????????????private?int?_max?=?999;
?51
?52????????????private?string?_strNumber;
?53
?54????????????public?NumberReader(string?todo)
?55????????????{
?56????????????????//?提示輸入數(shù)字
?57????????????????Console.WriteLine(todo);
?58????????????????//?獲取數(shù)字字符串
?59????????????????_strNumber?=?Console.ReadLine();
?60????????????}
?61
?62????????????public?NumberReader(string?todo,?int?min,?int?max)?:?this(todo)
?63????????????{
?64????????????????this._max?=?max;
?65????????????????this._min?=?min;
?66????????????}
?67
?68????????????public?int?GetNumber()
?69????????????{
?70????????????????int?number?=?0;
?71
?72????????????????try
?73????????????????{
?74????????????????????number?=?int.Parse(this._strNumber);
?75
?76????????????????????if?(number?>?this._max?||?number?<?this._min)
?77????????????????????{
?78????????????????????????throw?new?Exception();
?79????????????????????}
?80????????????????}
?81????????????????catch?(System.FormatException?formatEx)
?82????????????????{
?83????????????????????number?=?new?NumberReader("Input format error! Please input again: ").GetNumber();
?84????????????????}
?85????????????????catch?(System.Exception?ex)
?86????????????????{
?87????????????????????number?=?new?NumberReader("Input error! Please input again: ").GetNumber();
?88????????????????}
?89
?90????????????????return?number;
?91????????????}
?92????????}
?93
?94????????public?class?Factorial
?95????????{
?96????????????//?要計算的數(shù)字
?97????????????private?int?_number?=?0;
?98
?99????????????//?結(jié)果的位數(shù)
100????????????private?int?_digit?=?1;
101
102????????????//?存放結(jié)果的數(shù)組
103????????????private?int[]?_data?=?null;
104
105????????????//?復雜度標記
106????????????private?int?_complex?=?0;
107
108????????????public?Factorial(int?number)?:?this(number,?40)
109????????????{}
110
111????????????public?Factorial(int?number,?int?digit)
112????????????{
113????????????????this._number?=?number;
114????????????????this._data?=?new?int[digit];
115????????????????this._data[0]?=?1;
116????????????}
117
118????????????private?void?CalculateA()
119????????????{
120????????????????try
121????????????????{
122????????????????????for?(int?i=1;?i<=this._number;?i++)
123????????????????????{
124????????????????????????int?digit;
125????????????????????????for?(digit=this._data.GetLength(0);?digit>0;?digit--)
126????????????????????????{
127????????????????????????????this._complex?++;
128????????????????????????????this._data[digit-1]?=?this._data[digit-1]?*?i;
129????????????????????????
130????????????????????????????if?(this._data[digit-1]?>=?10)
131????????????????????????????{????????????????????????????
132????????????????????????????????for?(int?j=digit;?j<this._data.GetLength(0);?j++)
133????????????????????????????????{
134????????????????????????????????????this._complex?++;
135????????????????????????????????????this._data[j]?+=?this._data[j-1]?/?10;
136????????????????????????????????????
137????????????????????????????????????this._complex?++;
138????????????????????????????????????this._data[j-1]?=?this._data[j-1]?%?10;
139????????????????????????????????}
140????????????????????????????}
141????????????????????????}
142????????????????????}
143????????????????}
144????????????????catch
145????????????????{
146????????????????????return;
147????????????????}
148????????????}
149
150????????????private?void?CalculateB()
151????????????{
152????????????????//?初始位數(shù)為個位,也就是1
153????????????????try
154????????????????{
155????????????????????for?(int?i=1;?i<=this._number;?i++)
156????????????????????{
157????????????????????????//?數(shù)組元素的運算
158????????????????????????for?(int?j=1;?j<=this._digit;?j++)
159????????????????????????{
160????????????????????????????this._complex?++;
161????????????????????????????this._data[j-1]?*=?i;
162????????????????????????}
163????????????????????????//?從個位開始,根據(jù)每一位的數(shù)字判斷是否需要進位
164????????????????????????for?(int?j=1;?j<=this._digit;?j++)
165????????????????????????{
166????????????????????????????//?如果當前位大于等于10,則依次向前進一位
167????????????????????????????if?(this._data[j-1]?>=?10)
168????????????????????????????{
169????????????????????????????????//?從當前位開始,根據(jù)每一位的數(shù)字進行進位
170????????????????????????????????for?(int?m=j;?m<=this._digit;?m++)
171????????????????????????????????{
172????????????????????????????????????if?(this._data[this._digit-1]?>=?10)
173????????????????????????????????????{
174????????????????????????????????????????this._complex?++;
175????????????????????????????????????????this._digit++;
176????????????????????????????????????}
177
178????????????????????????????????????this._complex?++;
179????????????????????????????????????this._data[m]?+=?this._data[m-1]?/?10;
180
181????????????????????????????????????this._complex?++;
182????????????????????????????????????this._data[m-1]?=?this._data[m-1]?%?10;
183????????????????????????????????}
184????????????????????????????}
185????????????????????????}
186????????????????????}
187????????????????}
188????????????????catch
189????????????????{
190????????????????????return;
191????????????????}
192????????????}
193
194????????????public?void?ShowResult(int?type)
195????????????{
196????????????????Console.Write("Result?is?");
197????????????????switch(type)
198????????????????{
199????????????????????case?1:
200????????????????????????this.CalculateA();
201
202????????????????????????for?(int?i=this._data.GetLength(0)-1;?i>=0;?i--)
203????????????????????????{
204????????????????????????????Console.Write(this._data[i].ToString());
205????????????????????????}
206
207????????????????????????break;
208????????????????????default:
209????????????????????????this.CalculateB();
210
211????????????????????????for?(int?i=this._digit-1;?i>=0;?i--)
212????????????????????????{
213????????????????????????????Console.Write(this._data[i].ToString());
214????????????????????????}
215
216????????????????????????break;
217????????????????}
218????????????????Console.WriteLine();
219????????????????Console.WriteLine("Code?complex?is?"?+?this._complex.ToString());
220????????????}
221????????}
222????}
223}
224
??? 以上源碼提供了兩種算法,各自的復雜度都可以很清楚的查看到,如果有興趣的朋友可以再提供一些其他的更有效的算法。?
?
總結(jié)
- 上一篇: b照多少钱啊?
- 下一篇: 开一家儿童乐园加盟店需要多少钱