四川航霖管理咨詢有限公司seo站長(zhǎng)常用工具
文章目錄
- 一、實(shí)現(xiàn)思路
- 二、實(shí)現(xiàn)方法
- 三、判錯(cuò)處理
一、實(shí)現(xiàn)思路
先搭建好MVC框架,接著在各個(gè)模塊中實(shí)現(xiàn)各自的任務(wù)。首先要?jiǎng)?chuàng)建好UI界面,接著根據(jù)UI界面的元素來與數(shù)據(jù)進(jìn)行互動(dòng),其中創(chuàng)建UI界面需要用到Masonry布局。
二、實(shí)現(xiàn)方法
在calculationView文件中只涉及到UI界面。
首先創(chuàng)建兩個(gè)UITextField對(duì)象,一個(gè)用來顯示輸入到表達(dá)式,一個(gè)用來輸出運(yùn)算結(jié)果,接著創(chuàng)建一個(gè)數(shù)組用來存放button的名稱,接著循環(huán)創(chuàng)建button對(duì)象即可。
創(chuàng)建button時(shí)需要設(shè)置button的tag屬性,因?yàn)楹竺嫘枰ㄟ^button的tag屬性來進(jìn)行邏輯判斷。
self.textField01 = [[UITextField alloc] init];
self.textField01.backgroundColor = [UIColor blackColor];
self.textField02 = [[UITextField alloc] init];
self.textField02.backgroundColor = [UIColor blackColor];
self.buttonArray = [NSMutableArray arrayWithObjects:@"AC", @"(", @")", @"/", @"1", @"2", @"3", @"+", @"4", @"5", @"6", @"-", @"7", @"8", @"9", @"*", @"0", @".", @"=", nil];for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {self.calculatorButton = [UIButton buttonWithType:UIButtonTypeCustom];NSString* buttonString = self.buttonArray[i * 4 + j];[self.calculatorButton setTitle:buttonString forState:UIControlStateNormal];self.calculatorButton.titleLabel.font = [UIFont systemFontOfSize:43];self.calculatorButton.titleLabel.textColor = [UIColor whiteColor];self.calculatorButton.backgroundColor = [UIColor grayColor];[self.calculatorButton addTarget:self action:@selector(pressButton:) forControlEvents:UIControlEventTouchUpInside];self.calculatorButton.layer.borderWidth = 2.0;self.calculatorButton.layer.cornerRadius = ButtonSize / 2;self.calculatorButton.layer.masksToBounds = YES;self.calculatorButton.tag = 100 + j + i*4;if (i == 0 && j < 3) {self.calculatorButton.backgroundColor = [UIColor colorWithWhite:0.6 alpha:0.9];self.calculatorButton.titleLabel.textColor = [UIColor blackColor];}if (j == 3) {self.calculatorButton.backgroundColor = [UIColor orangeColor];}[self addSubview:self.calculatorButton];[self.calculatorButton mas_makeConstraints:^(MASConstraintMaker *make) {make.top.equalTo(self).offset(90 + HEIGHT / 6 + HEIGHT / 8 + (ButtonSize + SideSize) * i);make.left.equalTo(self).offset(SideSize + (ButtonSize + SideSize) * j);make.width.equalTo(@ButtonSize);make.height.equalTo(@ButtonSize);}];}}
還需要在當(dāng)前文件觸發(fā)button的事件函數(shù),因?yàn)橐ㄟ^button的事件函數(shù)將當(dāng)前button傳值到CalculationViewController文件中。
我使用的協(xié)議傳值進(jìn)行
定義協(xié)議及協(xié)議方法
@protocol ButttonDelegate <NSObject>- (void)returnButton:(UIButton*)button;@end
定義代理對(duì)象
@property (nonatomic, weak)id<ButttonDelegate>delegate;
button事件函數(shù)觸發(fā)代理方法
- (void)pressButton:(UIButton*)button {[self.delegate returnButton:button];
}
在CalculationViewController中定義協(xié)議方法
- (void)returnButton:(UIButton*)button;
在CalculationViewController中設(shè)置代理對(duì)象
self.calculationView.delegate = self;
在CalculationViewController中實(shí)現(xiàn)協(xié)議方法
- (void)returnButton:(UIButton*)button {
- NSString* buttonStr = button.titleLabel.text;NSInteger buttonTag = button.tag;if (buttonTag == 100) {self.calculationView.textField01.text = @"";self.calculationView.textField02.text = @"";self.yunsuanStr = [[NSMutableString alloc] init];self.jieguoStr = [[NSString alloc] init];} else if (buttonTag == 118) {//四則運(yùn)算}//
}
對(duì)于四則運(yùn)算,我使用中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式,再利用后綴表達(dá)式進(jìn)行計(jì)算。中綴轉(zhuǎn)后綴定義一個(gè)符號(hào)棧,一個(gè)結(jié)果棧。
char resultStack[100];int resultTop = -1;char operationStack[100];int operationTop = -1;NSString* ocStr = self.yunsuanStr;const char* strs = [ocStr UTF8String];char str[1000] ;strcpy(str, strs) ;int length = (int)strlen(str);
后綴進(jìn)行四則運(yùn)算時(shí)定義一個(gè)新棧。
double Stack[100];int StackTop = -1;char* token = strtok(resultStack, " ");while (token != NULL) {if (strcmp(token, "+") == 0) {double a = Stack[StackTop--];double b = Stack[StackTop--];double c = b + a;Stack[++StackTop] = c;}else if (strcmp(token, "-") == 0) {double a = Stack[StackTop--];double b = Stack[StackTop--];double c = b - a;Stack[++StackTop] = c;}else if (strcmp(token, "*") == 0) {double a = Stack[StackTop--];double b = Stack[StackTop--];double c = b * a;Stack[++StackTop] = c;}else if (strcmp(token, "/") == 0) {double a = Stack[StackTop--];double b = Stack[StackTop--];double c = b / a;Stack[++StackTop] = c;}else if (strcmp(token, "!") == 0) {double c = Stack[StackTop--];c = -c;Stack[++StackTop] = c;}else {double num = atof(token);Stack[++StackTop] = num;}token = strtok(NULL, " ");}double result = Stack[StackTop--];
這里使用了atof()函數(shù)可以將字符串中的數(shù)字識(shí)別為double類型的浮點(diǎn)數(shù)。使用strtok()函數(shù)將結(jié)果棧的元素通過空格分割方便進(jìn)行識(shí)別和運(yùn)算。
對(duì)于負(fù)數(shù)的運(yùn)算,我是將與“(”相鄰的“-”轉(zhuǎn)換為“!”,并用“!”進(jìn)行負(fù)數(shù)轉(zhuǎn)變,其中需要將“!“的優(yōu)先級(jí)設(shè)置為最高
int Compare(char str) {if (str == '(' || str == ')') {return 0;}else if (str == '+' || str == '-') {return 1;}else if (str == '*' || str == '/') {return 2;} else if (str == '!') {return 3;} else {return -1;}
}
接著在輸入字符串時(shí)進(jìn)行識(shí)別
for (int i = 0; i < length; ++i) {if (str[i] == '(' && str[i + 1] == '-') {str[i + 1] = '!';}}
三、判錯(cuò)處理
對(duì)于括號(hào)匹配問題,我使用棧來處理,當(dāng)讀到“(”則入棧,讀到“)”則棧頂元素出棧,最后判斷棧是否為空即可。
- (int)kuoHaoMatch:(NSMutableString*)mutableString {const char* cstr = [mutableString UTF8String];int length = (int)strlen(cstr);char stack[100];int stackTop = -1;for (int i = 0; i < length; i++) {if (cstr[i] == '(') {stack[++stackTop] = cstr[i];}if (cstr[i] == ')') {stack[stackTop--];}}if (stackTop == -1) {return 1;}return 0;
}
對(duì)于符號(hào)匹配問題,兩個(gè)運(yùn)算符不能相鄰,第一個(gè)位置不能為運(yùn)算符(-除外),最后一個(gè)位置不能為運(yùn)算符
- (int)fuHaoMatch:(NSMutableString*)mutableString {const char* cstr = [mutableString UTF8String];int length = (int)strlen(cstr);if (cstr[0] == '*' || cstr[0] == '/' || cstr[0] == '+') {return 0;}for (int i = 0; i < length; i++) {if ((cstr[i] == '*' && cstr[i+1] == '/') || (cstr[i] == '/' && cstr[i+1] == '*')) {return 0;}if ((cstr[i] == '*' && cstr[i+1] == '-') || (cstr[i] == '*' && cstr[i+1] == '+')) {return 0;}if ((cstr[i] == '/' && cstr[i+1] == '-') || (cstr[i] == '/' && cstr[i+1] == '+')) {return 0;}if ((cstr[i] == '+' && cstr[i+1] == '/') || (cstr[i] == '+' && cstr[i+1] == '*')) {return 0;}if ((cstr[i] == '-' && cstr[i+1] == '/') || (cstr[i] == '-' && cstr[i+1] == '*')) {return 0;}if ((cstr[i] == '-' && cstr[i+1] == '-') || (cstr[i] == '-' && cstr[i+1] == '+')) {return 0;}if ((cstr[i] == '+' && cstr[i+1] == '+') || (cstr[i] == '+' && cstr[i+1] == '-')) {return 0;}}if (cstr[length - 1] == '+' || cstr[length - 1] == '-' ||cstr[length - 1] == '*' || cstr[length - 1] == '/') {return 0;}return 1;
}
對(duì)于數(shù)字和括號(hào)的相鄰問題,數(shù)字后不能直接跟左括號(hào),右括號(hào)不能直接跟數(shù)字
- (int)numberAndkuoHao:(NSMutableString*)mutableString {const char* cstr = [mutableString UTF8String];int length = (int)strlen(cstr);int flag = 0;for (int i = 0; i < length; i++) {if ((cstr[i]>= '0' && cstr[i] <= '9') &&cstr[i+1] == '(') {flag++;}if (cstr[i] == ')' && (cstr[i + 1]>= '0' && cstr[i + 1] <= '9')) {flag++;}}if (flag == 0) {return 1;}return 0;
}
對(duì)于只有括號(hào)沒有數(shù)字的問題,直接遍歷整個(gè)字符串如果有數(shù)字則標(biāo)志變量加一,最后判斷標(biāo)志變量
- (int)numberJudge:(NSMutableString*)mutableString {const char* cstr = [mutableString UTF8String];int length = (int)strlen(cstr);int flag = 0;for (int i = 0; i < length; i++) {if (cstr[i]>= '0' && cstr[i] <= '9') {flag++;}}if (flag != 0) {return 1;}return 0;;
}
對(duì)于除零問題
if ([self.jieguoStr isEqualToString:@"nan"]) {self.jieguoStr = @"錯(cuò)誤";}if ([self.jieguoStr isEqualToString:@"inf"]) {self.jieguoStr = @"錯(cuò)誤";}
對(duì)于小數(shù)點(diǎn)異常處理
int pointFlag = 0;
for (int i = 0; i < resultTop; i++) {if (resultStack[i] == '.') {for (int j = i + 1; resultStack[j] != ' '; j++) {if (resultStack[j] == '.') {pointFlag++;}}}}if (pointFlag != 0) {self.jieguoStr = @"錯(cuò)誤";pointFlag = 0;}
對(duì)于如何刪除多余的零
NSDecimalNumber *number = [NSDecimalNumber decimalNumberWithString: self.jieguoStr];NSDecimalNumberHandler *roundHandler = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundUp scale:8 raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:NO];NSDecimalNumber *roundedNumber = [number decimalNumberByRoundingAccordingToBehavior:roundHandler];self.jieguoStr = [roundedNumber stringValue];