Algorithm Design——高精度整数四则运算

要注意两种不同的初始化方法以及算法复杂度问题。

  1 /**
  2     高精度整数的四则运算—— + - * / %
  3     以进制转换为例,输出X的N进制表示的数
  4 
  5     题目描述 : 
  6     将M进制的数X转换为N进制的数输出。
  7 
  8     输入:
  9     输入的第一行包括两个整数:M和N(2<=M,N<=36)。 下面的一行输入一个数X,
 10     X是M进制的数,现在要求你将M进制的数X转换成N进制的数输出。 
 11     输出:
 12     输出X的N进制表示的数。
 13 
 14     样例输入:
 15     16 10 F
 16     样例输出: 
 17     15
 18 */
 19 
 20 #include<cstdio>
 21 #include<cstring>
 22 #include<cstdlib>
 23 using namespace std;
 24 
 25 #define maxDigits 100
 26 
 27 ////高精度整数类
 28 class bigInteger
 29 {
 30 public:
 31     int digit[maxDigits];
 32     int size;
 33 
 34 public:
 35     void init()//初始化
 36     {
 37         for(int i = 0 ; i < maxDigits ; i ++)
 38             digit[i] = 0;
 39 
 40         size = 0;
 41     }
 42 
 43     void set(int x)//用一个普通整数初始化高精度整数
 44     {
 45         init();
 46 
 47         do
 48         {
 49             digit[size ++] = x % 10000;
 50             x /= 10000;
 51         }while(x != 0);
 52     }
 53 
 54     void output()//输出
 55     {
 56         for(int i = size - 1 ; i >= 0 ; i --)
 57         {
 58             if(i != size - 1)
 59                 printf_s("%04d", digit[i]);//先输出数字,然后高位补0
 60             else
 61                 printf_s("%d", digit[i]);
 62         }
 63         printf_s("\n");
 64     }
 65 
 66     bigInteger operator * (int x) const//高精度整数与普通整数的乘积
 67     {
 68         bigInteger ret;
 69         ret.init();
 70         int carry = 0;
 71         for(int i = 0 ; i < size ; i ++)
 72         {
 73             int tmp = x * digit[i] + carry;
 74             carry = tmp / 10000;
 75             tmp %= 10000;
 76             ret.digit[ret.size ++] = tmp;
 77         }
 78         if(carry != 0)
 79         {
 80             ret.digit[ret.size ++] = carry;
 81         }
 82 
 83         return ret;
 84     }
 85 
 86     bigInteger operator + (const bigInteger &A) const//高精度整数之间的加法运算
 87     {
 88         bigInteger ret;
 89         ret.init();
 90         int carry = 0;
 91         for(int i = 0 ; i < A.size || i < size; i ++)
 92         {
 93             int tmp = A.digit[i] + digit[i] + carry;
 94             carry = tmp / 10000;
 95             tmp %= 10000;
 96             ret.digit[ret.size ++] = tmp;
 97         }
 98         if(carry != 0)
 99         {
100             ret.digit[ret.size ++] = carry;
101         }
102 
103         return ret;
104     }
105 
106     bigInteger operator / (int x) const//高精度整数除以普通整数
107     {
108         bigInteger ret;
109         ret.init();
110         int remainder = 0;//余数
111 
112         for(int i = size - 1 ; i >= 0 ; i --)//从最高位到最低位依次完成计算
113         {
114             int t = (remainder * 10000 + digit[i]) / x;//计算当前位数值加上高位剩余的余数的和对x求得的商
115             int r = (remainder * 10000 + digit[i]) % x;//计算当前位数值加上高位剩余的余数的和对x求得的余数
116             ret.digit[i] = t;//保存本位的值
117             remainder = r;//保存至本位为止的余数
118         }
119 
120         /////返回高精度整数的size初始值为0,即当前所有位数字都是0时,digit[0]代表数字0,最为最高有效位,高精度整数即是数字0=
121         ret.size = 0;
122 
123         for(int i = 0 ; i < maxDigits ; i ++)//若存在非0位,确定最高的非0位,作为最高有效位
124         {
125             if(digit[i] != 0)
126                 ret.size = i;
127         }
128         ret.size ++;//最高有效位的下一位即为下一个我们不曾使用的digit数组单元,确定size的值
129         return ret;
130     }
131 
132     int operator % (int x) const//高精度整数对普通整数求余数
133     {
134         int remainder = 0;
135         for(int i = size - 1 ; i >= 0 ; i --)
136         {
137             int t = (remainder * 10000 + digit[i]) / x;
138             int r = (remainder * 10000 + digit[i]) % x;
139             remainder = r;
140         }
141         return remainder;
142     }
143 }a, b, c;
144 
145 char str[10000];
146 char ans[10000];
147 
148 int main()
149 {
150     int n, m;
151     while(scanf_s("%d%d", &m, &n) != EOF)
152     {
153         scanf_s("%s", str, _countof(str));//输入m进制数
154         int L = strlen(str);
155         a.set(0);//a的初始值是0,用来保存转换成10进制的m进制数
156         b.set(1);//b的初始值是1,在m进制向10进制转换过程中,一次代表每一位的权重
157 
158         for(int i = L - 1 ; i >= 0 ; i --)//从低位到高位转换m进制到相应的10进制数
159         {
160             int t;
161             if(str[i] >= '0' && str[i] <= '9')
162             {
163                 t = str[i] - '0';
164             }
165             else
166                 t = str[i] - 'A' + 10;//确定当前位字符代表的数字
167 
168             a = a + b * t;//累加当前数字乘以当前权重的乘积
169             b = b * m;//计算下一位权重
170         }
171 
172         int size = 0;//代表转换为n进制后的字符个数
173         do{//对转换成的10进制数求其n进制值
174             int t = a % n;//求余数
175 
176             //确定当前位字符
177             if(t >= 10)
178                 ans[size ++] = t - 10 + 'a';
179             else
180                 ans[size ++] = t + '0';
181 
182             a = a / n;//求商
183         }while(a.digit[0] != 0 || a.size != 1);//当a不为0时,重复该过程
184 
185         for(int i = size - 1 ; i >= 0 ; i --)
186             printf_s("%c", ans[i]);
187         printf("\n");
188     }
189 
190     return 0;
191 }
192 
193 /**
194 大整数求和
195 
196 题目描述: 实现一个加法器,使其能够输出a+b的值。
197 
198 输入:输入包括两个数a和b,其中a和b的位数不超过1000位。 
199 
200 输出 :可能有多组测试数据,对于每组数据,输出a+b的值。
201 
202 样例输入: 
203 2 6
204 10000000000000000000 10000000000000000000000000000000 
205 
206 样例输出:
207 8
208 10000000000010000000000000000000
209 */
210 
211 #include<cstdio>
212 #include<cstring>
213 #include<cstdlib>
214 using namespace std;
215 
216 class bigInteger
217 {
218 public:
219     int digit[1000];
220     int size;
221 
222 public:
223     void init()
224     {
225         for(int i = 0 ; i < 1000 ; i ++)
226             digit[i] = 0;
227         size = 0;
228     }
229 
230     ////将一个数字字符串转换成一个大数
231     void set(char str[])
232     {
233         init();
234         int L = strlen(str);
235 
236         for(int i = L - 1, j = 0 , t = 0 , c = 1 ; i >= 0 ; i --)
237         {
238             t += (str[i] - '0') * c;
239             j ++;
240             c *= 10;
241 
242             if(j == 4 || i == 0)
243             {
244                 digit[size ++] = t;
245 
246                 j = 0 ;
247                 t = 0;
248                 c = 1;
249             }
250         }
251     }
252 
253     void output()
254     {
255         for(int i = size - 1 ; i >= 0 ; i --)
256         {
257             if(i != size - 1)
258                 printf_s("%04d", digit[i]);
259             else
260                 printf_s("%d", digit[i]);
261         }
262         printf_s("\n");
263     }
264 
265     bigInteger operator + (const bigInteger &A) const
266     {
267         bigInteger ret;
268         ret.init();
269 
270         int carry = 0;
271         for(int i = 0 ; i < A.size || i < size ; i ++)
272         {
273             int tmp = A.digit[i] + digit[i] + carry;
274             carry = tmp / 10000;
275             tmp %= 10000;
276             ret.digit[ret.size ++] = tmp;
277         }
278 
279         if(carry != 0)
280         {
281             ret.digit[ret.size ++] = carry;
282         }
283 
284         return ret;
285     }
286 }a, b, c;
287 
288 char str1[1002], str2[1002];
289 
290 int main()
291 {
292     while(scanf_s("%s%s", str1, _countof(str1), str2, _countof(str2)) != EOF)
293     {
294         a.set(str1);
295         b.set(str2);
296         c = a + b;
297         c.output();
298     }
299 
300     return 0;
301 }

 

posted @ 2013-12-01 10:58  yiyi_xuechen  Views(394)  Comments(0)    收藏  举报