数组的进一步使用
數組是數據結構中最基本的結構形式,它是一種順序式的結構,存儲的是同一類型的數據。每個數組元素都擁有下標(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!
數組內容
??2
??3namespace?DsPractice.Array.Factorial
??4{
??5????/**////?<summary>
??6????///?利用數組的方式求解指定數字的階乘。
??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????????????//?獲取要計算的數字
?25????????????int?number?=?new?NumberReader("Please input a number to calculate factorial:").GetNumber();
?26
?27????????????//?獲得存放計算結果的數組的長度
?28????????????int?length?=?new?NumberReader("Please input a number of array digit:").GetNumber();
?29
?30????????????//?創建一個階乘計算對象
?31????????????Factorial?factorial?=?new?Factorial(number,?length);
?32
?33????????????//?計算并顯示結果
?34????????????factorial.ShowResult(type);
?35
?36????????????//?提示用戶繼續或結束
?37????????????int?res?=?new?NumberReader("Do you wannar try again?/r/n1. Yes;/r/n2. No.",?1,?2).GetNumber();
?38
?39????????????//?如果繼續執行,則返回重新調用
?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????????????????//?提示輸入數字
?57????????????????Console.WriteLine(todo);
?58????????????????//?獲取數字字符串
?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????????????//?要計算的數字
?97????????????private?int?_number?=?0;
?98
?99????????????//?結果的位數
100????????????private?int?_digit?=?1;
101
102????????????//?存放結果的數組
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????????????????//?初始位數為個位,也就是1
153????????????????try
154????????????????{
155????????????????????for?(int?i=1;?i<=this._number;?i++)
156????????????????????{
157????????????????????????//?數組元素的運算
158????????????????????????for?(int?j=1;?j<=this._digit;?j++)
159????????????????????????{
160????????????????????????????this._complex?++;
161????????????????????????????this._data[j-1]?*=?i;
162????????????????????????}
163????????????????????????//?從個位開始,根據每一位的數字判斷是否需要進位
164????????????????????????for?(int?j=1;?j<=this._digit;?j++)
165????????????????????????{
166????????????????????????????//?如果當前位大于等于10,則依次向前進一位
167????????????????????????????if?(this._data[j-1]?>=?10)
168????????????????????????????{
169????????????????????????????????//?從當前位開始,根據每一位的數字進行進位
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
??? 數組使用靜態的內存空間配置方式。這也是數組的一個很不方便的地方,在經常需要重新分配數據的存儲空間的應用上,往往使用數組就顯得非常影響效率;而且,對數組的添加、刪除、排序的操作也是比較麻煩以及低效的。
??? 在.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以后向前進一位。
程序源碼:
?
??1using?System;??2
??3namespace?DsPractice.Array.Factorial
??4{
??5????/**////?<summary>
??6????///?利用數組的方式求解指定數字的階乘。
??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????????????//?獲取要計算的數字
?25????????????int?number?=?new?NumberReader("Please input a number to calculate factorial:").GetNumber();
?26
?27????????????//?獲得存放計算結果的數組的長度
?28????????????int?length?=?new?NumberReader("Please input a number of array digit:").GetNumber();
?29
?30????????????//?創建一個階乘計算對象
?31????????????Factorial?factorial?=?new?Factorial(number,?length);
?32
?33????????????//?計算并顯示結果
?34????????????factorial.ShowResult(type);
?35
?36????????????//?提示用戶繼續或結束
?37????????????int?res?=?new?NumberReader("Do you wannar try again?/r/n1. Yes;/r/n2. No.",?1,?2).GetNumber();
?38
?39????????????//?如果繼續執行,則返回重新調用
?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????????????????//?提示輸入數字
?57????????????????Console.WriteLine(todo);
?58????????????????//?獲取數字字符串
?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????????????//?要計算的數字
?97????????????private?int?_number?=?0;
?98
?99????????????//?結果的位數
100????????????private?int?_digit?=?1;
101
102????????????//?存放結果的數組
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????????????????//?初始位數為個位,也就是1
153????????????????try
154????????????????{
155????????????????????for?(int?i=1;?i<=this._number;?i++)
156????????????????????{
157????????????????????????//?數組元素的運算
158????????????????????????for?(int?j=1;?j<=this._digit;?j++)
159????????????????????????{
160????????????????????????????this._complex?++;
161????????????????????????????this._data[j-1]?*=?i;
162????????????????????????}
163????????????????????????//?從個位開始,根據每一位的數字判斷是否需要進位
164????????????????????????for?(int?j=1;?j<=this._digit;?j++)
165????????????????????????{
166????????????????????????????//?如果當前位大于等于10,則依次向前進一位
167????????????????????????????if?(this._data[j-1]?>=?10)
168????????????????????????????{
169????????????????????????????????//?從當前位開始,根據每一位的數字進行進位
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
??? 以上源碼提供了兩種算法,各自的復雜度都可以很清楚的查看到,如果有興趣的朋友可以再提供一些其他的更有效的算法。?
?
總結
- 上一篇: b照多少钱啊?
- 下一篇: HttpHand和HttpModule的