大数模板
1 大数: 2 #include <stdio.h> 3 #include <string.h> 4 #include <stdlib.h> 5 #include <math.h> 6 #include <assert.h> 7 #include <ctype.h> 8 #include <map> 9 #include <string> 10 #include <set> 11 #include <bitset> 12 #include <utility> 13 #include <algorithm> 14 #include <vector> 15 #include <stack> 16 #include <queue> 17 #include <iostream> 18 #include <fstream> 19 #include <list> 20 using namespace std; 21 22 const int MAXL = 500; 23 struct BigNum 24 { 25 int num[MAXL]; 26 int len; 27 }; 28 29 //高精度比较 a > b return 1, a == b return 0; a < b return -1; 30 int Comp(BigNum &a, BigNum &b) 31 { 32 int i; 33 if(a.len != b.len) return (a.len > b.len) ? 1 : -1; 34 for(i = a.len-1; i >= 0; i--) 35 if(a.num[i] != b.num[i]) return (a.num[i] > b.num[i]) ? 1 : -1; 36 return 0; 37 } 38 39 //高精度加法 40 BigNum Add(BigNum &a, BigNum &b) 41 { 42 BigNum c; 43 int i, len; 44 len = (a.len > b.len) ? a.len : b.len; 45 memset(c.num, 0, sizeof(c.num)); 46 for(i = 0; i < len; i++) 47 { 48 c.num[i] += (a.num[i]+b.num[i]); 49 if(c.num[i] >= 10) 50 { 51 c.num[i+1]++; 52 c.num[i] -= 10; 53 } 54 } 55 if(c.num[len]) 56 len++; 57 c.len = len; 58 return c; 59 } 60 //高精度减法,保证a >= b 61 BigNum Sub(BigNum &a, BigNum &b) 62 { 63 BigNum c; 64 int i, len; 65 len = (a.len > b.len) ? a.len : b.len; 66 memset(c.num, 0, sizeof(c.num)); 67 for(i = 0; i < len; i++) 68 { 69 If(i>=b.len) 70 c.num[i]+=a.num[i]; 71 else 72 c.num[i] += (a.num[i]-b.num[i]); 73 if(c.num[i] < 0) 74 { 75 c.num[i] += 10; 76 c.num[i+1]--; 77 } 78 } 79 while(c.num[len] == 0 && len > 1) 80 len--; 81 c.len = len; 82 return c; 83 } 84 //高精度乘以低精度,当b很大时可能会发生溢出int范围,具体情况具体分析 85 //如果b很大可以考虑把b看成高精度 86 BigNum Mul1(BigNum &a, int &b) 87 { 88 BigNum c; 89 int i, len; 90 len = a.len; 91 memset(c.num, 0, sizeof(c.num)); 92 //乘以0,直接返回0 93 if(b == 0) 94 { 95 c.len = 1; 96 return c; 97 } 98 for(i = 0; i < len; i++) 99 { 100 c.num[i] += (a.num[i]*b); 101 if(c.num[i] >= 10) 102 { 103 c.num[i+1] = c.num[i]/10; 104 c.num[i] %= 10; 105 } 106 } 107 while(c.num[len] > 0) 108 { 109 c.num[len+1] = c.num[len]/10; 110 c.num[len++] %= 10; 111 } 112 c.len = len; 113 return c; 114 } 115 116 //高精度乘以高精度,注意要及时进位,否则肯能会引起溢出,但这样会增加算法的复杂度, 117 //如果确定不会发生溢出, 可以将里面的while改成if 118 BigNum Mul2(BigNum &a, BigNum &b) 119 { 120 int i, j, len = 0; 121 BigNum c; 122 memset(c.num, 0, sizeof(c.num)); 123 for(i = 0; i < a.len; i++) 124 { 125 for(j = 0; j < b.len; j++) 126 { 127 c.num[i+j] += (a.num[i]*b.num[j]); 128 if(c.num[i+j] >= 10) 129 { 130 c.num[i+j+1] += c.num[i+j]/10; 131 c.num[i+j] %= 10; 132 } 133 } 134 } 135 len = a.len+b.len-1; 136 if(c.num[len]) 137 len++; 138 while(c.num[len-1] == 0 && len > 1) 139 len--; 140 c.len = len; 141 return c; 142 } 143 144 //高精度除以低精度,除的结果为c, 余数为f 145 void Div1(BigNum &a, int &b, BigNum &c, int &f) 146 { 147 int i, len = a.len; 148 memset(c.num, 0, sizeof(c.num)); 149 f = 0; 150 for(i = a.len-1; i >= 0; i--) 151 { 152 f = f*10+a.num[i]; 153 c.num[i] = f/b; 154 f %= b; 155 } 156 while(len > 1 && c.num[len-1] == 0) 157 len--; 158 c.len = len; 159 } 160 //高精度*10 161 void Mul10(BigNum &a) 162 { 163 int i, len = a.len; 164 for(i = len; i >= 1; i--) 165 a.num[i] = a.num[i-1]; 166 a.num[i] = 0; 167 len++; 168 //if a == 0 169 while(len > 1 && a.num[len-1] == 0) 170 len--; 171 a.len=len; 172 } 173 174 //高精度除以高精度,除的结果为c,余数为f 175 void Div2(BigNum &a, BigNum &b, BigNum &c, BigNum &f) 176 { 177 int i, len = a.len; 178 memset(c.num, 0, sizeof(c.num)); 179 memset(f.num, 0, sizeof(f.num)); 180 f.len = 1; 181 for(i = len-1;i >= 0;i--) 182 { 183 Mul10(f); 184 //余数每次乘10 185 f.num[0] = a.num[i]; 186 //然后余数加上下一位 187 ///利用减法替换除法 188 while(Comp(f, b) >= 0) 189 { 190 f = Sub(f, b); 191 c.num[i]++; 192 } 193 } 194 while(len > 1 && c.num[len-1] == 0) 195 len--; 196 c.len = len; 197 } 198 void print(BigNum &a) //输出大数 199 { 200 int i; 201 for(i = a.len-1; i >= 0; i--) 202 printf("%d", a.num[i]); 203 puts(""); 204 } 205 //将字符串转为大数存在BigNum结构体里面 206 BigNum ToNum(char *s) 207 { 208 int i, j; 209 BigNum a; 210 a.len = strlen(s); 211 for(i = 0, j = a.len-1; s[i] != '\0'; i++, j--) 212 a.num[i] = s[j]-'0'; 213 return a; 214 } 215 216 void Init(BigNum &a, char *s, int &tag) //将字符串转化为大数 217 { 218 int i = 0, j = strlen(s); 219 if(s[0] == '-') 220 { 221 j--; 222 i++; 223 tag *= -1; 224 } 225 a.len = j; 226 for(; s[i] != '\0'; i++, j--) 227 a.num[j-1] = s[i]-'0'; 228 } 229 230 int main(void) 231 { 232 BigNum a, b; 233 char s1[100], s2[100]; 234 while(scanf("%s %s", s1, s2) != EOF) 235 { 236 int tag = 1; 237 Init(a, s1, tag); //将字符串转化为大数 238 Init(b, s2, tag); 239 a = Mul2(a, b); 240 if(a.len == 1 && a.num[0] == 0) 241 { 242 puts("0"); 243 } 244 else 245 { 246 if(tag < 0) putchar('-'); 247 print(a); 248 } 249 } 250 return 0; 251 }
posted on 2013-09-17 14:54 jumpingfrog0 阅读(358) 评论(0) 编辑 收藏 举报