C#实现突破位数限制,用字符串对较大的数进行运算

有时会碰到数字太大无法用int运算的情况,比如1000的阶乘。

解决方法是用char、string代替int进行竖式计算,可进行加、减、乘、除、阶乘、组合、比较大小,下面的方法都测试过


  1         #region 运算方法
2 // 计算组合数
3 public string GetCombination(int total, int num)
4 {
5 string result = "";
6 string dividend = GetStringMultiply(GetFactorial(num), GetFactorial(total - num));
7 string divisor = GetFactorial(total);
8 result = GetStringDivide(divisor, dividend);
9 return result;
10 }
11 // 计算num的阶乘
12 public string GetFactorial(int num)
13 {
14 string result = "";
15 result = num > 0 ? GetStringMultiply(num.ToString(), GetFactorial(num - 1)) : "1";
16 return result;
17 }
18 // 两个string数字相除
19 public string GetStringDivide(string divisor, string dividend)
20 {
21 string result = "";
22 List<char> cDivisor= divisor.ToCharArray().ToList<char>();
23 List<char> cDividend = dividend.ToCharArray().ToList<char>();
24 List<char> temp = new List<char>();
25 List<char> cResult = new List<char>();
26 int indexResult = -1;
27 int indexDivisor = 0;
28
29 // 除法的竖式计算
30 while (indexDivisor != cDivisor.Count)
31 {
32 // 从前往后分离除数大于被除数的部分,结果存入temp
33 try
34 {
35 for (; CompareTwoStringNum(GetListToString(temp), GetListToString(cDividend)) < 0; indexDivisor++)
36 {
37 temp.Add(cDivisor[indexDivisor]);
38 cResult.Add(‘0‘);
39 indexResult++;
40 }
41 }
42 catch
43 {
44 ;
45 }
46 // 得到一位结果,存入cResult
47 for (int i = 1; CompareTwoStringNum(GetListToString(temp), GetStringMultiply(dividend, i.ToString())) >= 0; i++)
48 {
49 cResult[indexResult] = Convert.ToChar(i.ToString());
50 }
51
52 temp = GetStringSub(GetListToString(temp), GetStringMultiply(GetListToString(cDividend), cResult[indexResult].ToString())).ToList<char>();
53 }
54
55 // 去除多余的0
56 while (cResult[0] == ‘0‘ && cResult.Count > 1)
57 cResult.RemoveAt(0);
58
59 result = string.Join("", cResult);
60 return result;
61 }
62 // 转换成string
63 public string GetListToString(List<char> cNum)
64 {
65 if (cNum.Count == 0)
66 return "0";
67
68 while (cNum[0] == ‘0‘ && cNum.Count > 1)
69 cNum.RemoveAt(0);
70 return string.Join("", cNum);
71 }
72 // 多个string数字相乘
73 public string GetStringMultiply(List<string> nums, bool isRecursion = false)
74 {
75 string result = "";
76 if (isRecursion)
77 nums.RemoveAt(0);
78
79 if (nums.Count > 0)
80 result = GetStringMultiply(nums[0], GetStringMultiply(nums, true));
81 else
82 return "1";
83 return result;
84 }
85 // 两个string数字相乘
86 public string GetStringMultiply(string num1, string num2)
87 {
88 string result = "";
89 List<string> temp = new List<string>();
90 char[] Char1 = num1.ToCharArray();
91 char[] Char2 = num2.ToCharArray();
92 int index1 = Char1.Length - 1, index2 = Char2.Length-1;
93 int flag = 0;
94
95 // 得到第一级相乘后的字符串数组
96 for (int i = index2; i >= 0; i--)
97 {
98 List<char> c = new List<char>();
99 for (int z = i; z < Char2.Length-1; z++)
100 {
101 c.Add(‘0‘);
102 }
103 // 进行第一级相乘(倒序存放)
104 for (int j = index1; j >= 0; j--)
105 {
106 int n = Convert.ToInt32(Char1[j].ToString()) * Convert.ToInt32(Char2[i].ToString()) + flag;
107 flag = n > 9 ? n / 10 : 0;
108 c.Add(n > 9 ? Convert.ToChar((n % 10).ToString()) : Convert.ToChar(n.ToString()));
109 }
110 // 组合成第一级相乘的字符串
111 StringBuilder sb = new StringBuilder();
112 if (flag > 0)
113 sb.Append(flag.ToString()); // 最高位进位
114 for (int k = c.Count - 1; k >= 0; k--)
115 {
116 sb.Append(c[k]);
117 }
118 temp.Add(sb.ToString());
119 flag = 0;
120 }
121
122 // 字符串相加
123 result = GetStringAdd(temp);
124
125 return result;
126 }
127 // 多个string数字相加
128 public string GetStringAdd(List<string> num)
129 {
130 string result = "";
131 List<char[]> nChar = new List<char[]>();
132
133 foreach (string s in num)
134 {
135 nChar.Add(s.ToCharArray());
136 }
137
138 int flag = 0; // 进位
139 int index = 1; // 从后向前的索引
140 bool continus;
141 List<string> addResult = new List<string>();
142 StringBuilder sb = new StringBuilder();
143 do
144 {
145 int addNum = 0;
146 continus = false;
147
148 // 从后向前单列相加
149 for (int i = 0; i < num.Count; i++)
150 {
151 int lastIndex = nChar[i].Length - index;
152 addNum += lastIndex < 0 ? 0 : Convert.ToInt32(nChar[i][lastIndex].ToString());
153 continus |= (lastIndex > 0);
154 }
155 index++;
156
157 addResult.Add(((addNum + flag) % 10).ToString());
158 flag = (addNum + flag) / 10;
159 if (flag > 0 && !continus)
160 addResult.Add(flag.ToString());
161 } while (continus);
162 for (int i = addResult.Count - 1; i >= 0; i--)
163 {
164 sb.Append(addResult[i]);
165 }
166 result = sb.ToString();
167
168 List<char> cResult = result.ToCharArray().ToList<char>();
169 // 去除多余的0
170 while (cResult[0] == ‘0‘ && cResult.Count > 1)
171 cResult.RemoveAt(0);
172 result = string.Join("", cResult);
173
174 return result;
175 }
176 // 两个string数字相减
177 public string GetStringSub(string num1, string num2)
178 {
179 string result = "";
180 int flag = 0;
181 if (num1.Length < num2.Length)
182 return null;
183 num2 = num2.PadLeft(num1.Length, ‘0‘);
184 char[] cNum1 = num1.ToCharArray();
185 char[] cNum2 = num2.ToCharArray();
186 if (Convert.ToInt32(cNum1[0].ToString()) < Convert.ToInt32(cNum2[0].ToString()))
187 return null;
188
189 List<char> temp = new List<char>();
190 for (int i = cNum1.Length - 1; i >= 0; i--)
191 {
192 if ((Convert.ToInt32(cNum1[i].ToString()) - flag) >= Convert.ToInt32(cNum2[i].ToString()))
193 {
194 temp.Add(Convert.ToChar((Convert.ToInt32(cNum1[i].ToString()) - flag - Convert.ToInt32(cNum2[i].ToString())).ToString()));
195 flag = 0;
196 }
197 else
198 {
199 temp.Add(Convert.ToChar((Convert.ToInt32(cNum1[i].ToString()) - flag + 10 - Convert.ToInt32(cNum2[i].ToString())).ToString()));
200 flag = 1;
201 }
202 }
203 // 去除多余的0
204 while (temp[temp.Count - 1] == ‘0‘ && temp.Count > 1)
205 temp.RemoveAt(temp.Count - 1);
206
207 StringBuilder sb = new StringBuilder();
208 for (int i = temp.Count - 1; i >= 0; i--)
209 {
210 sb.Append(temp[i]);
211 }
212 result = sb.ToString();
213 return result;
214 }
215 // 两个string数字比较大小,前面的大返回1
216 public int CompareTwoStringNum(string num1, string num2)
217 {
218 int result = 0;
219 List<char> cNum1 = num1.ToCharArray().ToList<char>();
220 List<char> cNum2 = num2.ToCharArray().ToList<char>();
221 // 去除多余的0
222 while (cNum1[0] == ‘0‘ && cNum1.Count > 1)
223 cNum1.RemoveAt(0);
224 while (cNum2[0] == ‘0‘ && cNum2.Count > 1)
225 cNum2.RemoveAt(0);
226
227 if (cNum1.Count > cNum2.Count)
228 result = 1;
229 else if (cNum1.Count < cNum2.Count)
230 result = -1;
231 else
232 {
233 for (int i = 0; i < cNum2.Count; i++)
234 {
235 if (cNum1[i] != cNum2[i])
236 {
237 result = cNum1[i] > cNum2[i] ? 1 : -1;
238 break;
239 }
240 }
241 }
242
243 return result;
244 }
245 #endregion

C#实现突破位数限制,用字符串对较大的数进行运算

时间: 2024-10-11 11:49:08

C#实现突破位数限制,用字符串对较大的数进行运算的相关文章

输入任意一个5位数,判断其是否是回文数

输入任意一个5位数,判断其是否是回文数.所谓的回文数是指其个位与万位相同,并且十位与千位相同,比如:12321或者54645: #include <stdio.h>void main(){   int n=0;    printf("请输入任意一个5位数\n");    scanf("%d",&n);   n%10==n/10000&&(n/10)%10==(n/1000)%10 ? printf("%n是一个回文数&q

打印出所有的&quot;水仙花数&quot;,所谓&quot;水仙花数&quot;是指一个三位数,其各位数字立方和等于该数本身。

package com.mumu.ready; public class Daffodils { // 题目:打印出所有的"水仙花数",所谓"水仙花数"是指一个三位数,其各位数字立方和等于该数本身. // 例如:153是一个"水仙花数",因为153=1的三次方+5的三次方+3的三次方. public static void main(String[] args) { for (int i = 100; i < 1000; i++) { in

输入任意一个5位数,判断其是否是回文数。

#include <stdio.h>void main(){ int a; printf("请输入一个5位数"); scanf("%d",&a); (a/10000==a%10&&(a/1000)%10==(a/10)%10)?printf("是回文数\n"):printf("不是回文数\n");} 输入任意一个5位数,判断其是否是回文数.,布布扣,bubuko.com

jquery获取字符串中出现最多的数

//获取字符串中出现最多的数和它一共出现多少次 var str = 'asdfssaaasasasasaa'; //定义字符串 var json = {}; //定义数组用来存储每个字符元素所对应的个数 for (var i = 0; i < str.length; i++) { //遍历字符串中所有的元素 if (!json[str.charAt(i)]) { //判断当前元素是否已经在数组中存在 str.charAt(i)//当前元素 json[str.charAt(i)] = 1; //给

C实例--判断一个字符串是否是回文数

回文是指顺读和反读内容均相同的字符串,例如"121","ABBA","X"等.本实例将编写函数判断字符串是否是回文. 引入两个指针变量,开始时,两个指针分别指向字符串的首末字符,当两个指针所指字符相等时,两个指针分别向后和向前移动一个字符位置,并继续比较,直到两个指针相遇,说明该字符串是回文,如果比较过程中发现两个指针指向的字符不相等,则判断该字符串不是回文. 下面是代码的实现部分: #include <stdio.h> #inclu

ligh1060(求字符串第k大排列)组合数学

题意:求给定字符串(有重复字符)第k大排列. 解法:先判断字符串的所有排列是否够k个.然后从左向右每一位每一位确定.简单的组合数学. 代码: /**************************************************** * author:xiefubao *******************************************************/ #pragma comment(linker, "/STACK:102400000,10240000

c++实验5--统计输出字符串中(大/小写)字母个数,数字个数及其它字符个数。

一.问题及代码 /* * 文件名称: * 作 者: 杨楚莛 * 完成日期: 2016 年 5 月 3 日 * 版 本 号:v1.0 * 对任务及求解方法的描述部分:统计输出字符串中(大/小写)字母个数,数字个数及其它字符个数. * 输入描述: * 问题描述: * 程序输出: * 问题分析: * 算法设计: */ #include<iostream> #include<cstdio> using namespace std; int main() { char str[50]; in

中矿大新生赛 A 求解位数和【字符串】

时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 32768K,其他语言65536K64bit IO Format: %lld 题目描述 给出一个数x,求x的所有位数的和. 输入描述: 第1行输入组数T,代表有T组数据. 第2-T+1行,每行输入一个数x. 输入数据保证:0≤x≤10200 输出描述: 每行输出对应行的数的位数和. 示例1 输入 2 10 101 输出 1 2 示例2 输入 2 111111111111111111111111111111111111 22222222

Java字符串的10大热点问题,你都懂吗?

转自 威哥干JAVA http://www.codingke.com 下面我为大家总结了10条Java开发者经常会提的关于Java字符串的问题,如果你也是Java初学者,仔细看看吧: 1.如何比较字符串,应该用”==”还是equals()? 总的来说,”==”是用来比较字符串的引用地址,而equals()才是比较字符串的值.两个值相同的字符串用”==”比较结果有可能是false,而用equals()则一定为true.除非两个字符串是同一个new出来的对象,不然比较字符串值是否相同应该要用equa