最近喜歡上上百度知道,回答了些問題,等級不知不覺到了六級。其中一些問題還有些意思,現在搬到這里來,也好讓有興趣的人參考參考,或者討論,希望能起到拋磚引玉的效果(via:女孩禮物網)。
這個題目是巨型整數相加減。巨型整數,即大到最大的數據類型都裝不下的整數。運算的原理其實也簡單,就像剛學數學時列豎式來,對位相加,大於9就向高位進位。具體處理時,就是將字符串形式表示的巨整數,按位放入一個數組,實現按位相加、進位,及相減、借位。
1 public class ComputeHugeNumber 2 { 3 public static string Plus(string num1, string num2) 4 { 5 if (!IsNumber(num1, num2)) 6 return "錯誤:操作數必須是整數。"; 7 8 if (num1[0] != '-' && num2[0] != '-') //如果兩數都不為負 9 return DoPlus(num1, num2); 10 else if (num1[0] != '-' && num2[0] == '-') //如果后數為負 11 { 12 return DoMinus(num1, num2.Substring(1)); 13 } 14 else if (num2[0] != '-' && num1[0] == '-') //如果前數為負 15 { 16 return DoMinus(num2, num1.Substring(1)); 17 } 18 //如果兩數都為負 19 return "-" + DoPlus(num1.Substring(1), num2.Substring(1)); 20 } 21 public static string Minus(string num1, string num2) 22 { 23 if (!IsNumber(num1, num2)) 24 return "錯誤:操作數必須是整數。"; 25 26 if (num1[0] != '-' && num2[0] != '-') 27 return DoMinus(num1, num2); 28 else if (num1[0] != '-' && num2[0] == '-') 29 { 30 return DoPlus(num1, num2.Substring(1)); 31 } 32 else if (num2[0] != '-' && num1[0] == '-') 33 { 34 return "-" + DoPlus(num1.Substring(1), num2); 35 } 36 37 return DoMinus(num2.Substring(1), num1.Substring(1)); 38 } 39 // 正則判斷是否為整數 40 private static bool IsNumber(string num1, string num2) 41 { 42 Regex rgx=new Regex(@"^-?\d+$"); 43 return rgx.IsMatch(num1) && rgx.IsMatch(num2); 44 } 45 //執行加法 46 private static string DoPlus(string num1, string num2) 47 { 48 int[] maxNumberArray; //存較大的操作數 49 int[] minNumberArray; //存較小的操作數 50 if (num1.Length > num2.Length) 51 { 52 maxNumberArray = ConvertStringToIntArrayAndReverse(num1); 53 minNumberArray = ConvertStringToIntArrayAndReverse(num2); 54 } 55 else 56 { 57 maxNumberArray = ConvertStringToIntArrayAndReverse(num2); 58 minNumberArray = ConvertStringToIntArrayAndReverse(num1); 59 } 60 int tmp, carry=0, i=0; //存臨時的和、進位、循環變量 61 for (int len=minNumberArray.Length; i < len; i++) 62 { 63 //將兩數對應的位以及前面的進位相加 64 tmp = maxNumberArray[i] + minNumberArray[i] + carry; 65 if (tmp > 9) //和有進位 66 { 67 maxNumberArray[i] = tmp % 10; 68 carry = tmp / 10; 69 } 70 else //和沒有進位 71 { 72 maxNumberArray[i] = tmp; 73 carry = 0; 74 } 75 } 76 if (i < maxNumberArray.Length) //如果較大的數還剩余有位,就將最后一次的進位加入高位 77 { 78 maxNumberArray[i] += carry; 79 return ReverseIntArrayAndToString(maxNumberArray); 80 } 81 else if (carry != 0) //如果兩數長度相等,將最后一次的進位加在最前面 82 { 83 return carry.ToString() + ReverseIntArrayAndToString(maxNumberArray); 84 } 85 else 86 { 87 return ReverseIntArrayAndToString(maxNumberArray); 88 } 89 } 90 //執行減法 91 private static string DoMinus(string num1, string num2) 92 { 93 int[] maxNumberArray=null; 94 int[] minNumberArray=null; 95 bool negative=false; //指示兩數相減結果是否為負 96 if (num1.Length > num2.Length) 97 { 98 maxNumberArray = ConvertStringToIntArrayAndReverse(num1); 99 minNumberArray = ConvertStringToIntArrayAndReverse(num2); 100 } 101 else if (num2.Length > num1.Length) 102 { 103 maxNumberArray = ConvertStringToIntArrayAndReverse(num2); 104 minNumberArray = ConvertStringToIntArrayAndReverse(num1); 105 negative = true; 106 } 107 else //如果兩數長度相等,通過循環判斷其大小 108 { 109 int len=num1.Length; 110 int i=0; 111 for (; i < len; i++) 112 { 113 if (num1[i] > num2[i]) 114 { 115 maxNumberArray = ConvertStringToIntArrayAndReverse(num1); 116 minNumberArray = ConvertStringToIntArrayAndReverse(num2); 117 break; 118 } 119 else if (num1[i] < num2[i]) 120 { 121 maxNumberArray = ConvertStringToIntArrayAndReverse(num2); 122 minNumberArray = ConvertStringToIntArrayAndReverse(num1); 123 negative = true; 124 break; 125 } 126 } 127 if (i == len) //如果兩數相等,返回結果 0 128 return "0"; 129 } 130 131 for (int j=0,len=minNumberArray.Length; j < len; j++) 132 { 133 //將兩數對應位相減 134 maxNumberArray[j] -= minNumberArray[j]; 135 if (maxNumberArray[j] < 0) //如果相減結果為負,用遞歸向高位借位 136 { 137 maxNumberArray[j] += 10; 138 ComputeCarry(maxNumberArray, j + 1); 139 } 140 } 141 142 if (negative) 143 return "-" + ReverseIntArrayAndToString(maxNumberArray); 144 return ReverseIntArrayAndToString(maxNumberArray); 145 } 146 //向高位借位的遞歸算法 147 private static void ComputeCarry(int[] numberArray, int p) 148 { 149 if (numberArray[p] > 0) //如果高位夠借位 150 { 151 numberArray[p]--; 152 } 153 else //如果高位不夠借,繼續遞歸借位 154 { 155 numberArray[p] = 9; 156 ComputeCarry(numberArray, p + 1); 157 } 158 } 159 //將字符形式表示的數按位存入 int 數組,並反轉過來以便於計算 160 private static int[] ConvertStringToIntArrayAndReverse(string str) 161 { 162 int[] result=new int[str.Length]; 163 for (int i=str.Length - 1, j=0; i >= 0; i--, j++) 164 { 165 result[j] = Convert.ToInt32(str[i].ToString()); 166 } 167 return result; 168 } 169 //向高位借位的遞歸算法 170 private static void ComputeCarry(int[] numberArray, int p) 171 { 172 if (numberArray[p] > 0) //如果高位夠借位 173 { 174 numberArray[p]--; 175 } 176 else //如果高位不夠借,繼續遞歸借位 177 { 178 numberArray[p] = 9; 179 ComputeCarry(numberArray, p + 1); 180 } 181 } 182 //將字符形式表示的數按位存入 int 數組,並反轉過來以便於計算 183 private static int[] ConvertStringToIntArrayAndReverse(string str) 184 { 185 int[] result=new int[str.Length]; 186 for (int i=str.Length - 1, j=0; i >= 0; i--, j++) 187 { 188 result[j] = Convert.ToInt32(str[i].ToString()); 189 } 190 return result; 191 } 192 //向高位借位的遞歸算法 193 private static void ComputeCarry(int[] numberArray, int p) 194 { 195 if (numberArray[p] > 0) //如果高位夠借位 196 { 197 numberArray[p]--; 198 } 199 else //如果高位不夠借,繼續遞歸借位 200 { 201 numberArray[p] = 9; 202 ComputeCarry(numberArray, p + 1); 203 } 204 } 205 //將字符形式表示的數按位存入 int 數組,並反轉過來以便於計算 206 private static int[] ConvertStringToIntArrayAndReverse(string str) 207 { 208 int[] result=new int[str.Length]; 209 for (int i=str.Length - 1, j=0; i >= 0; i--, j++) 210 { 211 result[j] = Convert.ToInt32(str[i].ToString()); 212 } 213 return result; 214 } 215 //向高位借位的遞歸算法 216 private static void ComputeCarry(int[] numberArray, int p) 217 { 218 if (numberArray[p] > 0) //如果高位夠借位 219 { 220 numberArray[p]--; 221 } 222 else //如果高位不夠借,繼續遞歸借位 223 { 224 numberArray[p] = 9; 225 ComputeCarry(numberArray, p + 1); 226 } 227 } 228 //將字符形式表示的數按位存入 int 數組,並反轉過來以便於計算 229 private static int[] ConvertStringToIntArrayAndReverse(string str) 230 { 231 int[] result=new int[str.Length]; 232 for (int i=str.Length - 1, j=0; i >= 0; i--, j++) 233 { 234 result[j] = Convert.ToInt32(str[i].ToString()); 235 } 236 return result; 237 } 238 //向高位借位的遞歸算法 239 private static void ComputeCarry(int[] numberArray, int p) 240 { 241 if (numberArray[p] > 0) //如果高位夠借位 242 { 243 numberArray[p]--; 244 } 245 else //如果高位不夠借,繼續遞歸借位 246 { 247 numberArray[p] = 9; 248 ComputeCarry(numberArray, p + 1); 249 } 250 } 251 //將字符形式表示的數按位存入 int 數組,並反轉過來以便於計算 252 private static int[] ConvertStringToIntArrayAndReverse(string str) 253 { 254 int[] result=new int[str.Length]; 255 for (int i=str.Length - 1, j=0; i >= 0; i--, j++) 256 { 257 result[j] = Convert.ToInt32(str[i].ToString()); 258 } 259 return result; 260 } 261 //向高位借位的遞歸算法 262 private static void ComputeCarry(int[] numberArray, int p) 263 { 264 if (numberArray[p] > 0) //如果高位夠借位 265 { 266 numberArray[p]--; 267 } 268 else //如果高位不夠借,繼續遞歸借位 269 { 270 numberArray[p] = 9; 271 ComputeCarry(numberArray, p + 1); 272 } 273 } 274 //將字符形式表示的數按位存入 int 數組,並反轉過來以便於計算 275 private static int[] ConvertStringToIntArrayAndReverse(string str) 276 { 277 int[] result=new int[str.Length]; 278 for (int i=str.Length - 1, j=0; i >= 0; i--, j++) 279 { 280 result[j] = Convert.ToInt32(str[i].ToString()); 281 } 282 return result; 283 }
1 //將最終計算結果反轉回來並拼成字符串 2 private static string ReverseIntArrayAndToString(int[] intArray) 3 { 4 IEnumerable<int> tmp = intArray.Reverse(); 5 StringBuilder strBld=new StringBuilder(); 6 foreach (int i in tmp) 7 strBld.Append(i); 8 return strBld.ToString().TrimStart('0'); 9 } 10 }