巨型整数相加减

最近喜欢上上百度知道,回答了些问题,等级不知不觉到了六级。其中一些问题还有些意思,现在搬到这里来,也好让有兴趣的人参考参考,或者讨论,希望能起到抛砖引玉的效果(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 } 
复制代码

 

 
posted @   施瓦小辛格  阅读(2193)  评论(17编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示