1 #pragma mark - 说明
2 #if 0
3 1、传入字符串表示的整数只能是正整数。
4 2、不能带有除了阿拉伯小写数字以外的任何字符。
5 3、目前只完成了大数的加减和乘法。除法有待解决。
6 现在传递进来的参数字符串,不能是带有标点符号或者加减乘除其他符号的字符串。否则计算功能失效。另外减法在leftNum<rightNum的时候,得到返回值结果带有一个‘-’负号,不能将他在读进行本函数中的进一步计算,必须进过处理。
7 对于上面这一点不足,有待改进。算法和代码优化待改进。
8 #endif
9 #pragma mark -
10
11
12 #import <Foundation/Foundation.h>
13
14 @interface BigNumMath : NSObject
15
16 /*两个数相加,返回结果的字符串*/
17 -(NSString *)bnm:(NSString *)leftNum Add:(NSString *)rightNum;
18
19 /*两个数相减,返回结果的字符串*/
20 -(NSString *)bnm:(NSString *)leftNum Minus:(NSString *)rightNum;
21
22 /* 比较两个字符串表示整数的大小,前者大返回:NSOrderedDescending
23 后者大返回:NSOrderedAscending大小相同放回:NSOrderedSame */
24 -(NSComparisonResult)bnm:(NSString *)leftNum LargerThan:(NSString *)rightNum;
25
26 /*两个数相乘,返回结果的字符串*/
27 -(NSString *)bnm:(NSString *)leftNum Multiply:(NSString *)rightNum;
28
29 /*一个整形数据int 与一个大数乘积,放回结果NSString*/
30 -(NSString *)getStringWithInt:(int)num Multiply:(NSString *)rightNum;
31
32 @end
33 //==================方法实现部分:
34 #import "BigNumMath.h"
35
36 #pragma mark - Catogary
37 @interface NSString (NSStringMethod)
38 +(NSArray *)getCharArrayFromNSString:(NSString *)charsString;
39 @end
40 @implementation NSString (NSStringMethod)
41
42 +(NSArray *)getCharArrayFromNSString:(NSString *)charsString
43 {
44 NSMutableArray *charArray = [[NSMutableArray alloc] initWithCapacity:0];
45 int index = 0;
46 while (1) {
47 NSString *charOne = [charsString substringWithRange:NSMakeRange(index, 1)];
48 [charArray addObject:charOne];
49 index++;
50 if (index>=[charsString rangeOfString:charsString].length) {
51 break;
52 }
53 }
54 return charArray;
55 }
56
57 @end
58
59 #pragma mark - BNM_Class
60 @implementation BigNumMath
61 {
62 NSMutableArray *leftArray;
63 NSMutableArray *rightArray;
64 NSMutableArray *destArray;
65
66 char *left;
67 char *right;
68 }
69
70 -(id)init{
71 if (self=[super init]) {
72
73 }
74 return self;
75 }
76
77 #pragma mark - MultiplyWithInt
78 -(NSString *)getStringWithInt:(int)num Multiply:(NSString *)rightNum
79 {
80 NSMutableArray *rArr = [NSMutableArray arrayWithArray:[NSString getCharArrayFromNSString:rightNum]];
81 // printf("\n n = %d, rArr = %s \n",num,[[rArr componentsJoinedByString:@""] UTF8String]);
82
83 NSMutableArray *destArr = [NSMutableArray arrayWithCapacity:0];
84 int car1 = 0;
85 int temp = 0;
86 int location = rArr.count-1;
87 while (1)
88 {
89 temp = [[rArr objectAtIndex:location] intValue]*num+car1;
90 car1 = temp/10;
91 [destArr insertObject:[NSString stringWithFormat:@"%d",temp%10] atIndex:0];
92 if (location==0) {
93 if (car1!=0) {
94 [destArr insertObject:[NSString stringWithFormat:@"%d",car1] atIndex:0];
95 }
96 break;
97 }else{
98 location--;
99 }
100 }
101 NSString *numD = [destArr componentsJoinedByString:@""];
102
103 return numD;
104 }
105
106 #pragma mark - MultiplyMethod
107 -(NSString *)bnm:(NSString *)leftNum Multiply:(NSString *)rightNum
108 {
109 NSArray *lArr = [NSString getCharArrayFromNSString:leftNum];
110 NSArray *rArr = [NSString getCharArrayFromNSString:rightNum];
111
112 /*得到有效数位的数组*/
113 NSArray *elArray = [self getEffectiveArrayFromArray:lArr];
114 NSArray *erArray = [self getEffectiveArrayFromArray:rArr];
115
116 //查找有效位数
117 int LenOfL = elArray.count;
118 int LenOfR = erArray.count;
119
120
121 NSMutableArray *elemArr = [NSMutableArray arrayWithCapacity:0];
122 for (int i=1; i<=LenOfL; i++) {
123 NSMutableString *numLayer = (NSMutableString *)[self getStringWithInt:[[elArray objectAtIndex:LenOfL-i] intValue] Multiply:rightNum];
124 for (int j=1; j<i; j++) {
125 [numLayer appendString:@"0"];
126 }//加法运算对齐处理
127 [elemArr addObject:numLayer];
128 }
129
130 NSMutableString *numD = [NSMutableString stringWithString:@"0"];
131 for (int l=0; l<LenOfL; l++) {
132 numD = (NSMutableString *)[self bnm:numD Add:[elemArr objectAtIndex:l]];
133 }
134
135 return numD;
136 }
137
138 #pragma mark - AddMethod
139 -(NSString *)bnm:(NSString *)leftNum Add:(NSString *)rightNum
140 {
141 // printf("left = %s,%c right = %s\n",[leftNum UTF8String],9,[rightNum UTF8String]);
142
143 leftArray = [NSMutableArray arrayWithArray:[NSString getCharArrayFromNSString:leftNum]];
144
145 rightArray = [NSMutableArray arrayWithArray:[NSString getCharArrayFromNSString:rightNum]];
146
147 destArray = [[NSMutableArray alloc] initWithCapacity:0];
148
149
150 NSMutableArray *shortArray = leftArray.count<rightArray.count ? leftArray:rightArray;
151 NSMutableArray *longArray = leftArray.count<rightArray.count ? rightArray:leftArray;
152
153 int LenOfL = leftArray.count;
154 int LenOfR = rightArray.count;
155 int LenOfMax = MAX(LenOfL, LenOfR);
156 int LenOfMin = MIN(LenOfL, LenOfR);
157 for (int i=0; i<LenOfMax-LenOfMin; i++) {
158 [shortArray insertObject:@"0" atIndex:0];
159 }//这里先使得leftArray为短数组
160
161 int carray = 0;
162 int location = rightArray.count-1;
163 while (1)
164 {
165 int temp = [[shortArray objectAtIndex:location] intValue] + [[longArray objectAtIndex:location] intValue]+carray;
166 [destArray insertObject:[NSString stringWithFormat:@"%d",temp%10] atIndex:0];
167 carray = temp/10;
168
169
170 if (location==0) {
171 if (carray!=0) {
172 [destArray insertObject:[NSString stringWithFormat:@"%d",carray] atIndex:0];
173 }
174 break;
175 }else{
176 location--;
177 }
178 }
179
180 NSString *sumD = [destArray componentsJoinedByString:@""];
181
182 return sumD;
183 }
184
185 #pragma mark - MinusMethod
186 -(NSString *)bnm:(NSString *)leftNum Minus:(NSString *)rightNum
187 {
188 // printf("left = %s,%c right = %s\n",[leftNum UTF8String],9,[rightNum UTF8String]);
189 //
190 //
191 // printf("arrLeft = %s,arrRight = %s\n",[[leftArray componentsJoinedByString:@""] UTF8String],[[rightArray componentsJoinedByString:@""] UTF8String]);
192
193 destArray = [[NSMutableArray alloc] initWithCapacity:0];
194
195 NSComparisonResult result = [self bnm:leftNum LargerThan:rightNum];
196 if (result==NSOrderedSame) {
197 return [NSString stringWithFormat:@"0"];
198 }else if (result==NSOrderedDescending){
199 leftArray = [NSMutableArray arrayWithArray:[NSString getCharArrayFromNSString:leftNum]];
200 rightArray = [NSMutableArray arrayWithArray:[NSString getCharArrayFromNSString:rightNum]];
201 }else if(result ==NSOrderedAscending){
202 leftArray = [NSMutableArray arrayWithArray:[NSString getCharArrayFromNSString:rightNum]];
203 rightArray = [NSMutableArray arrayWithArray:[NSString getCharArrayFromNSString:leftNum]];
204 }//确保leftArray > rightArray
205
206
207 // NSMutableArray *shortArray = leftArray.count<rightArray.count ? leftArray:rightArray;
208 // NSMutableArray *longArray = leftArray.count<rightArray.count ? rightArray:leftArray;
209
210 int LenOfL = leftArray.count;
211 int LenOfR = rightArray.count;
212 int LenOfMax = MAX(LenOfL, LenOfR);
213 int LenOfMin = MIN(LenOfL, LenOfR);
214 for (int i=0; i<LenOfMax-LenOfMin; i++) {
215 [rightArray insertObject:@"0" atIndex:0];
216 }//这里先使得leftArray为短数组
217
218 // printf("shortArray = %s,longArray = %s\n",[[shortArray componentsJoinedByString:@""] UTF8String],[[longArray componentsJoinedByString:@""] UTF8String]);
219 //
220 //
221 // printf("lenOFL = %d, LenOfR = %d, LenOfMax = %d\n",LenOfL,LenOfR,LenOfMax);
222
223 int carray = 0;
224 int lend = 0;
225 int location = rightArray.count-1;
226 while (1)
227 {
228 if ([[leftArray objectAtIndex:location] intValue]<[[rightArray objectAtIndex:location] intValue]) {
229 lend = 10;
230 carray = 1;
231 [leftArray replaceObjectAtIndex:location-1 withObject:[NSString stringWithFormat:@"%d",[[leftArray objectAtIndex:location-1] intValue]-carray]];
232 }
233 int temp = [[leftArray objectAtIndex:location] intValue] +lend - [[rightArray objectAtIndex:location] intValue];
234 [destArray insertObject:[NSString stringWithFormat:@"%d",temp] atIndex:0];
235
236 if (location==0) {
237 break;
238 }else{
239 lend = 0;
240 carray = 0;
241 location --;
242 }
243
244 }
245 if (result==NSOrderedDescending) {
246 NSString *sumD = [destArray componentsJoinedByString:@""];
247 return sumD;
248 }
249
250 NSMutableString *sumD = [NSMutableString stringWithFormat:@"-%@",[destArray componentsJoinedByString:@""]];
251
252 return sumD;
253 }
254 #pragma mark - NSCompareResult
255 -(NSComparisonResult)bnm:(NSString *)leftNum LargerThan:(NSString *)rightNum
256 {
257 printf("left = %s,%c right = %s\n",[leftNum UTF8String],9,[rightNum UTF8String]);
258
259 leftArray = [NSMutableArray arrayWithArray:[NSString getCharArrayFromNSString:leftNum]];
260
261 rightArray = [NSMutableArray arrayWithArray:[NSString getCharArrayFromNSString:rightNum]];
262
263 //查找有效位数
264 int LenOfL = [self getEffectiveNumFromArray:leftArray];
265 int LenOfR = [self getEffectiveNumFromArray:rightArray];
266 int rddL = leftArray.count - LenOfL;
267 int rddR = rightArray.count - LenOfR;
268
269
270 if (LenOfL > LenOfR) {
271 return NSOrderedDescending;
272 }else if (LenOfL < LenOfR){
273 return NSOrderedAscending;
274 }
275
276 /*去除无效数位,保留有效数位*/
277 for (int i=0; i<rddL; i++){
278 [leftArray removeObjectAtIndex:0];
279 }
280 for (int j=0; j<rddR; j++){
281 [rightArray removeObjectAtIndex:0];
282 }
283
284 for (int i=0; i<LenOfR; i++) {
285 int nsl = [[leftArray objectAtIndex:i] intValue];
286 int nsr = [[rightArray objectAtIndex:i] intValue];
287 if (nsl > nsr ) {
288 return NSOrderedDescending;
289 }else if (nsl < nsr ){
290 return NSOrderedAscending;
291 }else{
292 continue;
293 }
294 }
295 return NSOrderedSame;
296 }
297 #pragma mark - 查找有效数位数(0000123,有效位为3;010023有效位数为5)
298 -(int)getEffectiveNumFromArray:(NSArray *)sArray
299 {
300 int mark = 0;
301 int ecount = 0;
302 for (NSString *ns in sArray) {
303 if ([ns intValue]==0) {
304 mark++;
305 }else
306 break;
307 }
308 ecount = sArray.count-mark;
309 return ecount;
310 }
311
312 #pragma mark - 将数组保留有效位数(00012030,-->12030)
313 -(NSArray *)getEffectiveArrayFromArray:(NSArray *)sArray
314 {
315 NSMutableArray *mArray = [NSMutableArray arrayWithArray:sArray];
316 int mark = 0;
317 int ecount = 0;
318 for (NSString *ns in sArray) {
319 if ([ns intValue]==0) {
320 mark++;
321 [mArray removeObjectAtIndex:0];
322 }else
323 break;
324 }
325 ecount = sArray.count-mark;
326 return mArray;
327 }
328
329 #pragma mark - 数组倒置
330 -(NSArray *)getReverseArrayFromArray:(NSArray *)sArray
331 {
332 NSMutableArray *dArray = [NSMutableArray arrayWithArray:sArray];
333 int count = dArray.count;
334 for (int i=0; i<sArray.count/2; i++) {
335 [dArray exchangeObjectAtIndex:i withObjectAtIndex:(count-1-i)];
336 }
337 return dArray;
338 }
339
340 @end