巨型整数相加减
最近喜欢上上百度知道,回答了些问题,等级不知不觉到了六级。其中一些问题还有些意思,现在搬到这里来,也好让有兴趣的人参考参考,或者讨论,希望能起到抛砖引玉的效果(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 }
正在看本人博客的这位童鞋,我看你气度不凡,谈吐间隐隐有王者之气,日后必有一番作为!旁边有“推荐”二字,你就顺手把它点了吧,相得准,我分文不收;相不准,你也好回来找我!
希望能和在读此文的朋友们碰撞一些激情的火花,此公众号会不定时推送一些属于我们程序员的有用信息与优质内容,欢迎关注交流!
作者:施瓦小辛格
出处:http://www.cnblogs.com/wenyang-rio/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。
出处:http://www.cnblogs.com/wenyang-rio/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .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语句:使用策略模式优化代码结构