iOS——仿写计算器

四则运算:中缀表达式转后缀表达式+后缀表达式求值

实现四则运算的算法思路是:首先输入的是中缀表达式的字符串,然后将其转为计算机可以理解的后缀表达式,然后将后缀表达式求值:

中缀转后缀表达式思路参考:《数据结构》:中缀表达式转后缀表达式 + 后缀表达式的计算

在该思路的基础上,会遇见以下几个问题:

  1. 输入多位数时无法识别出该多位数,可能求值时计算成好几位一位数。我的解决方法是将输入的数字使用","分隔开,因为每两个相邻的运算符之间只会有一个数,所以在转为后缀表达式时,每当遍历到的字符是一个运算符,就再为存储我们得到的后缀表达式的那个数组中添加一个","将数字分隔开,然后在后缀求值的部分,每当读取到一个",",就continue掉,然后在读到数字的时候,就先定义一个动态数组,然后使用一个while循环一直循环将当前数字存入数组中,直到遍历到的元素是下一个",",此时就跳出循环,然后将该动态数组存入栈中,实现多位数的计算。
  2. 小数点的判断:小数点的判断和多位数一样,将小数点的判定条件和数字一样,存入动态数组时也是一样。存入数组后,我们使用c语言中的strtod函数可以将一个字符串识别为浮点数,便可以很简单的完成小数点的读取。
  3. 括号的判断:括号的判断在这里是一个非常复杂的点:首先在转化为后缀表达式的部分,如果遇到的是左括号,就直接入栈(注:左括号入栈后优先级降至最低)。如果遇到的字符为右括号,就直接出栈,并将出栈字符依次送入后缀表达式,直到栈顶字符为左括号(左括号也要出栈,但不送入后缀表达式)。总结就是:只要满足栈顶为左括号即可进行最后一次出栈。
  4. 负数的判断:对于负数的判断,我的思路是将原本的中缀表达式理解为:-x = (0-x)来进行转化后缀表达式的操作。即在将当前字符串元素传入中缀转后缀表达式的函数中时,判断当前元素是否是"-",然后判断该元素的上一个元素是否为运算符/括号或者该元素是否是字符串的第一个元素,如果是,就可以将该字符串的这一部分理解为负数。找到为负数的"-"后,首先不将该"-"传入转后缀的函数,而是先依次将"(","0"传入,然后再传入当前的"-",然后再使用一个while循环依次将负数的数字部分的元素传入(记得此时也要一直更改着遍历字符串的下标位置),直到读到的元素为运算符/括号时跳出循环,然后再传入一个")"到转后缀的函数中,至此,我们得到的后缀表达式就是可以正确计算负数的后缀表达式了。然后再计算后缀表达式的部分不用修改,因为负数部分会计算为(0-x)的。
    以下是我四则运算部分的代码实现:
objectivec 复制代码
//定义一个全局变量n,用于记录后缀表达式数组的下标
static int n = 0;

//栈的定义和初始化以及入栈出栈等操作
typedef struct result {
    char stack[10000];
    int top;
    char nBoLan[10000];
}Result;

Result* CreatStack(void) {
    Result *stack = (Result*)malloc(sizeof(Result));
    stack->top = -1;
    return stack;
}

void PushStack(Result *obj, char val) {
    obj->stack[++obj->top] = val;
}

void PopStack(Result *obj) {
    if (obj->top >= 0) {
        obj->top--;
    }
}

char GetTopStack(Result *obj) {
    if (obj->top >= 0) {
        return obj->stack[obj->top];
    }
    return 0;
}

//将中缀表达式转为后缀表达式
void caoZuoStack(char a, Result *obj) {
    if (a == '+' || a == '-') {
        if (obj->stack[obj->top] == '-') {
            while(obj->stack[obj->top] != '(' && obj->top >= 0) {
                obj->nBoLan[n++] = GetTopStack(obj);
                PopStack(obj);
            }
            PushStack(obj, a);
            obj->nBoLan[n++] = ',';
        } else if (obj->stack[obj->top] == '(') {
            PushStack(obj, a);
            obj->nBoLan[n++] = ',';
        } else if (obj->stack[obj->top] == '*' || obj->stack[obj->top] == '/') {
            while (obj->stack[obj->top] != '(' && obj->top >= 0) {
                obj->nBoLan[n++] = GetTopStack(obj);
                PopStack(obj);
            }
            PushStack(obj, a);
            obj->nBoLan[n++] = ',';
        } else {
            PushStack(obj, a);
            obj->nBoLan[n++] = ',';
        }
    } else if (a == '*' || a == '/'){
        if (obj->stack[obj->top] == '/') {
            obj->nBoLan[n++] = GetTopStack(obj);
            PopStack(obj);
            PushStack(obj, a);
            obj->nBoLan[n++] = ',';
        } else if (obj->stack[obj->top] == '(') {
            PushStack(obj, a);
            obj->nBoLan[n++] = ',';
        } else {
            PushStack(obj, a);
            obj->nBoLan[n++] = ',';
        }
    } else if (a == ')') {
        while(obj->stack[obj->top] != '(') {
            obj->nBoLan[n++] = GetTopStack(obj);
            PopStack(obj);
        }
        PopStack(obj);
    } else if (a == '(') {
        PushStack(obj, a);
    } else if (a != '=' && a != ')' && a != '(') {
        obj->nBoLan[n++] = a;
    }
    if (a == '=') {
        while(obj->top >= 0) {
            obj->nBoLan[n++] = GetTopStack(obj);
            PopStack(obj);
        }
    }
    printf("%s\n", obj->nBoLan);
}

//后缀表达式求值
double evalRPN(char *tokens, int tokensSize){
    int top = -1;
    double stack[100];
    for (int i = 0; i < tokensSize; i++) {
        if (tokens[i] == ',' || tokens[i] == '(' || tokens[i] == ')') {
            continue;
        }
        if (tokens[i] == '+') {
            stack[top - 1] = stack[top] + stack[top - 1];
            top--;
            continue;
        }
        if (tokens[i] == '-') {
            stack[top - 1] = stack[top - 1] - stack[top];
            top--;
            continue;
        }
        if (tokens[i] == '*') {
            stack[top - 1] = stack[top] * stack[top - 1];
            top--;
            continue;
        }
        if (tokens[i] == '/') {
            stack[top - 1] = stack[top - 1] / stack[top];
            top--;
            continue;
        } else {
            int sum = 0;
            char *s = (char*)malloc(sizeof(char) * 2 * (sum+1));
            while (tokens[i] != ',' && tokens[i] != '+' && tokens[i] != '-' && tokens[i] != '*' && tokens[i] != '/' && tokens[i] != '(' && tokens[i] != ')') {
                s[sum++] = tokens[i];
                i++;
            }
            if (tokens[i] == '+' || tokens[i] == '-' || tokens[i] == '*' || tokens[i] == '/' || tokens[i] == '(' || tokens[i] == ')') {
                i--;
            }
            char *t;
            double theNum = strtod(s, &t);
            stack[++top] = theNum;
        }
        continue;
    }
    return stack[top];
}

//将计算器输入的字符串传给上面两个函数
- (double)jiSuan: (NSString*)putInStr {
    NSLog(@"%@", putInStr);
    n = 0;
    Result *obj = CreatStack();
    //对负数进行判断
    for (int i = 0; i < [putInStr length]; i++) {
        if ((i == 0 && [putInStr characterAtIndex:0] == '-') || ([putInStr characterAtIndex:i] == '-' && ([putInStr characterAtIndex:i-1] == '+' || [putInStr characterAtIndex:i-1] == '-' || [putInStr characterAtIndex:i-1] == '*' || [putInStr characterAtIndex:i-1] == '/' || [putInStr characterAtIndex:i-1] == '('))) {
            caoZuoStack('(', obj);
            caoZuoStack('0', obj);
            caoZuoStack('-', obj);
            i++;
            while (([putInStr characterAtIndex:i] >= 48 && [putInStr characterAtIndex:i] <= 57) || [putInStr characterAtIndex:i] == '.') {
                caoZuoStack([putInStr characterAtIndex:i], obj);
                i++;
            }
            caoZuoStack(')', obj);
            i--;
            continue;
        }
        caoZuoStack([putInStr characterAtIndex:i], obj);
    }
    int tokensSize = (int)strlen(obj->nBoLan);
    printf("%lf", evalRPN(obj->nBoLan, tokensSize));
    //返回结果
    return evalRPN(obj->nBoLan, tokensSize);
}

计算器的布局及限制

本次计算机的仿写我使用的是mvc模式,并且布局使用了Masonry框架。

  • 在model层:我使用了一个可变数组来存储表达式以及结果,当在计算器上点击输入表达式时,点击的合法的按钮的会传相应的值到该字符串中,点击AC按钮时将会清空该字符串,点击"="按钮后将会先计算表达式的结果,然后清空该字符串,然后再将得到的结果传入该字符串。model层和controller层使用KVO传值,但是该KVO传值的监听对象并不是该可变数组对象,因为前面学过KVO只是监听setter方法,但是向可变数组添加元素的方法它不属于setter方法,所以即使你向数组中add多少个元素也不会有监听反应。所以这里我的操作是再model层再声明一个int类型的a属性,并在初始化的时候给其赋值为0,然后使用KVO监听该a属性,在controller层中,每当点击了按钮,就将该a属性自增使得其值改变,由此就可以触发监听事件。在监听事件中,将view层声明的label属性的text属性赋值为该可变字符串,这样就可以实现每当点击按钮,上面的表达式可以随时改变。
    代码实现:
objectivec 复制代码
#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface Model : NSObject

@property (nonatomic, strong) NSMutableString *StrNum;
@property (nonatomic, assign) int a;

@end

NS_ASSUME_NONNULL_END
objectivec 复制代码
#import "Model.h"

@implementation Model

- (Model*)init {
    self.a = 0;
    if (self = [super init]) {
        self.StrNum = [[NSMutableString alloc] init];
    }
    return self;
}

@end
  • 在view层:我使用了一个for循环循环创建button,并为每个button的tag赋值,并使用Masonry框架等对其布局。布局这块直接看代码就行了不多赘述。在view层和controller层之间的交互我是使用了通知传值,在view层将button存入一个字典然后用通知传值传给controller层,在controller中对传来的button的tag值进行判断。
    代码实现:
objectivec 复制代码
#import <UIKit/UIKit.h>
#import "Masonry.h"

NS_ASSUME_NONNULL_BEGIN

@interface View : UIView

@property (nonatomic, strong) UILabel *label;
@property (nonatomic, strong) UIButton *Button;


@end

NS_ASSUME_NONNULL_END
objectivec 复制代码
#import "View.h"

#import "Masonry.h"

#define MAS_SHORTHAND
#define MAS_SHORTHAND_GLOBALS

@implementation View

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    self.backgroundColor = [UIColor blackColor];
    
    //显示在计算器上方的label,用于显示表达式及结果
    self.label = [[UILabel alloc] init];
    [self addSubview:self.label];
    self.label.textColor = [UIColor whiteColor];
    self.label.textAlignment = NSTextAlignmentRight;
    [self.label mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.mas_equalTo(25);
        make.top.mas_equalTo(270);
        make.height.mas_equalTo(@100);
        make.width.mas_equalTo(360);
    }];
    self.label.font = [UIFont systemFontOfSize:50];
    
    //for循环创建button,button的点击事件用来触发通知传值
    for (int i = 0; i < 5; i++) {
        for (int j = 0; j < 4; j++) {
            self.Button = [UIButton buttonWithType:UIButtonTypeCustom];
            [self addSubview:self.Button];
            [self.Button mas_makeConstraints:^(MASConstraintMaker *make) {
                make.left.mas_equalTo(102 * j + 15);
                make.top.mas_equalTo(102 * i + 375);
                make.width.and.height.mas_equalTo(@90);
            }];
            [self.Button addTarget:self action:@selector(pressPutin:) forControlEvents:UIControlEventTouchUpInside];
            self.Button.layer.cornerRadius = 45;
            self.Button.layer.masksToBounds = YES;
            self.Button.titleLabel.font = [UIFont systemFontOfSize:40];

            self.Button.tag = i * 4 + j;
            if (self.Button.tag == 0) {
                [self.Button setTitle:@"AC" forState:UIControlStateNormal];
                [self.Button setBackgroundColor:[UIColor grayColor]];
            }
            if (self.Button.tag == 1) {
                [self.Button setTitle:@"(" forState:UIControlStateNormal];
                [self.Button setBackgroundColor:[UIColor grayColor]];
            }
            if (self.Button.tag == 2) {
                [self.Button setTitle:@")" forState:UIControlStateNormal];
                [self.Button setBackgroundColor:[UIColor grayColor]];
            }
            if (self.Button.tag == 3) {
                [self.Button setTitle:@"/" forState:UIControlStateNormal];
                [self.Button setBackgroundColor:[UIColor orangeColor]];
            }
            if (self.Button.tag == 4) {
                [self.Button setTitle:@"7" forState:UIControlStateNormal];
                [self.Button setBackgroundColor:[UIColor darkGrayColor]];
            }
            if (self.Button.tag == 5) {
                [self.Button setTitle:@"8" forState:UIControlStateNormal];
                [self.Button setBackgroundColor:[UIColor darkGrayColor]];
            }
            if (self.Button.tag == 6) {
                [self.Button setTitle:@"9" forState:UIControlStateNormal];
                [self.Button setBackgroundColor:[UIColor darkGrayColor]];
            }
            if (self.Button.tag == 7) {
                [self.Button setTitle:@"*" forState:UIControlStateNormal];
                [self.Button setBackgroundColor:[UIColor orangeColor]];
            }
            if (self.Button.tag == 8) {
                [self.Button setTitle:@"4" forState:UIControlStateNormal];
                [self.Button setBackgroundColor:[UIColor darkGrayColor]];
            }
            if (self.Button.tag == 9) {
                [self.Button setTitle:@"5" forState:UIControlStateNormal];
                [self.Button setBackgroundColor:[UIColor darkGrayColor]];
            }
            if (self.Button.tag == 10) {
                [self.Button setTitle:@"6" forState:UIControlStateNormal];
                [self.Button setBackgroundColor:[UIColor darkGrayColor]];
            }
            if (self.Button.tag == 11) {
                [self.Button setTitle:@"-" forState:UIControlStateNormal];
                [self.Button setBackgroundColor:[UIColor orangeColor]];
            }
            if (self.Button.tag == 12) {
                [self.Button setTitle:@"1" forState:UIControlStateNormal];
                [self.Button setBackgroundColor:[UIColor darkGrayColor]];
            }
            if (self.Button.tag == 13) {
                [self.Button setTitle:@"2" forState:UIControlStateNormal];
                [self.Button setBackgroundColor:[UIColor darkGrayColor]];
            }
            if (self.Button.tag == 14) {
                [self.Button setTitle:@"3" forState:UIControlStateNormal];
                [self.Button setBackgroundColor:[UIColor darkGrayColor]];
            }
            if (self.Button.tag == 15) {
                [self.Button setTitle:@"+" forState:UIControlStateNormal];
                [self.Button setBackgroundColor:[UIColor orangeColor]];
            }
            if (self.Button.tag == 16) {
                [self.Button setTitle:@"0" forState:UIControlStateNormal];
                [self.Button setBackgroundColor:[UIColor darkGrayColor]];
                [self.Button mas_updateConstraints: ^(MASConstraintMaker *make) {
                    make.left.mas_equalTo(102 * j + 15);
                    make.top.mas_equalTo(102 * i + 375);
                    make.width.mas_equalTo(@192);
                    make.height.mas_equalTo(@90);
                }];
            }
            if (self.Button.tag == 17) {
                [self.Button setTitle:@"." forState:UIControlStateNormal];
                [self.Button setBackgroundColor:[UIColor darkGrayColor]];
                [self.Button mas_updateConstraints: ^(MASConstraintMaker *make) {
                    make.left.mas_equalTo(102 * (j+1) + 15);
                    make.top.mas_equalTo(102 * i + 375);
                    make.width.and.height.mas_equalTo(@90);
                }];
            }
            if (self.Button.tag == 18) {
                [self.Button setTitle:@"=" forState:UIControlStateNormal];
                [self.Button setBackgroundColor:[UIColor orangeColor]];
                [self.Button mas_updateConstraints: ^(MASConstraintMaker *make) {
                    make.left.mas_equalTo(102 * (j+1) + 15);
                    make.top.mas_equalTo(102 * i + 375);
                    make.width.and.height.mas_equalTo(@90);
                }];
            }
        }
        
    }
    return self;
}

//通知传值
- (void)pressPutin: (UIButton*)Button {
    //NSLog(@"OK");
    NSDictionary *dict =[NSDictionary dictionaryWithObject:Button forKey:@"btn"];
    [[NSNotificationCenter defaultCenter] postNotificationName:@"NumGo" object:nil userInfo:dict];
}
@end
  • controller层:在controller层中我要对传来的button的tag进行判断并改变可变数组,并且要对按钮的点击进行限制,而且要将前面我们写过的四则运算式子写在这里。对按钮输入限制的判断:我定义了很多个全局变量,例如fuHaoNum,如果点击了ac按钮,就将其赋为初值0,因为字符串中没有元素时不能输入运算符(负号除外)。如果点击了运算符和括号,就将该值赋为0,因为除了负号外,其他运算符和括号不能连续两个相邻。如果点击了数字,就将该值赋为1,因为数字后面可以跟运算符,如果点击了小数点,就将该值赋为0...由此实现限制。
    代码实现:
objectivec 复制代码
#import "ViewController.h"

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>
#include<math.h>

@interface ViewController ()

@property (nonatomic, strong) View *aView;
@property (nonatomic, strong) Model *model;

@end

static int pointNum = 0;
static int kuoHaoNum = 0;
static int fuHaoNum = 0;
static int jianHao = 0;
static int numAKuoHao = 1;
static int inKuoHao = 0;
static int dengYu = 0;
static int point = 1;
static int dengYuNum = 0;

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.aView = [[View alloc] initWithFrame:self.view.bounds];
    [self.view addSubview:self.aView];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pressNum:) name:@"NumGo" object:nil];

    self.model = [[Model alloc] init];
    [self.model addObserver:self forKeyPath:@"a" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
    self.aView.label.text = [NSString stringWithFormat:@"%@",self.model.StrNum];
    self.aView.label.adjustsFontSizeToFitWidth = YES;
}

- (void)pressWanCheng {
    [self dismissViewControllerAnimated:YES completion:nil];
}

- (void)pressNum: (NSNotification*)sender{
    UIButton *Button = sender.userInfo[@"btn"];
    if(Button.tag == 0) {
        pointNum = 0;
        kuoHaoNum = 0;
        fuHaoNum = 0;
        jianHao = 0;
        numAKuoHao = 1;
        inKuoHao = 0;
        dengYu = 0;
        point = 1;
        dengYuNum = 0;
        
        NSUInteger a = [self.model.StrNum length];
        [self.model.StrNum deleteCharactersInRange:NSMakeRange(0, a)];
    }
    if (Button.tag == 1) {
        if(numAKuoHao) {
            [self.model.StrNum appendFormat:@"("];
            pointNum = 0;
            kuoHaoNum++;
            fuHaoNum = 0;
            jianHao = 1;
            numAKuoHao = 1;
            inKuoHao = 0;
            dengYu = 0;
            point = 1;
            dengYuNum++;
        } else {
            UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:@"输入格式错误" preferredStyle:UIAlertControllerStyleAlert];
            [self presentViewController:alert animated:YES completion:nil];
            [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(pressWanCheng) userInfo:nil repeats:NO];
        }
    }
    if (Button.tag == 2) {
        if(fuHaoNum && inKuoHao && kuoHaoNum != 0) {
            [self.model.StrNum appendFormat:@")"];
            pointNum = 0;
            kuoHaoNum--;
            fuHaoNum = 1;
            jianHao = 1;
            numAKuoHao = 0;
            dengYu = 1;
            point = 1;
            dengYuNum++;
        } else {
            UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:@"输入格式错误" preferredStyle:UIAlertControllerStyleAlert];
            [self presentViewController:alert animated:YES completion:nil];
            [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(pressWanCheng) userInfo:nil repeats:NO];
        }
    }
    if (Button.tag == 3) {
        if(fuHaoNum) {
            [self.model.StrNum appendFormat:@"/"];
            pointNum = 0;
            fuHaoNum = 0;
            jianHao = 1;
            numAKuoHao = 1;
            inKuoHao = 1;
            dengYu = 0;
            point = 1;
            dengYuNum++;
        } else {
            UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:@"输入格式错误" preferredStyle:UIAlertControllerStyleAlert];
            [self presentViewController:alert animated:YES completion:nil];
            [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(pressWanCheng) userInfo:nil repeats:NO];
        }
    }
    if(Button.tag == 4) {
        [self.model.StrNum appendFormat:@"7"];
        pointNum = 1;
        fuHaoNum = 1;
        jianHao = 2;
        numAKuoHao = 0;
        dengYu = 1;
    }
    if(Button.tag == 5) {
        [self.model.StrNum appendFormat:@"8"];
        pointNum = 1;
        fuHaoNum = 1;
        jianHao = 2;
        numAKuoHao = 0;
        dengYu = 1;
    }
    if(Button.tag == 6) {
        [self.model.StrNum appendFormat:@"9"];
        pointNum = 1;
        fuHaoNum = 1;
        jianHao = 2;
        numAKuoHao = 0;
        dengYu = 1;
    }
    if (Button.tag ==7) {
        if(fuHaoNum) {
            [self.model.StrNum appendFormat:@"*"];
            pointNum = 0;
            fuHaoNum = 0;
            jianHao = 1;
            numAKuoHao = 1;
            inKuoHao = 1;
            dengYu = 0;
            point = 1;
            dengYuNum++;
        } else {
            UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:@"输入格式错误" preferredStyle:UIAlertControllerStyleAlert];
            [self presentViewController:alert animated:YES completion:nil];
            [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(pressWanCheng) userInfo:nil repeats:NO];
        }
    }
    if(Button.tag == 8) {
        [self.model.StrNum appendFormat:@"4"];
        pointNum = 1;
        fuHaoNum = 1;
        jianHao = 2;
        numAKuoHao = 0;
        dengYu = 1;
    }
    if(Button.tag == 9) {
        [self.model.StrNum appendFormat:@"5"];
        pointNum = 1;
        fuHaoNum = 1;
        jianHao = 2;
        numAKuoHao = 0;
        dengYu = 1;
    }
    if(Button.tag == 10) {
        [self.model.StrNum appendFormat:@"6"];
        pointNum = 1;
        fuHaoNum = 1;
        jianHao = 2;
        numAKuoHao = 0;
        dengYu = 1;
    }
    if (Button.tag == 11) {
        if ([self.model.StrNum length] == 0) {
            [self.model.StrNum appendFormat:@"-"];
            pointNum = 0;
            fuHaoNum = 0;
            jianHao = 0;
            numAKuoHao = 1;
            dengYu = 0;
            point = 1;
        } else if(jianHao) {
            [self.model.StrNum appendFormat:@"-"];
            pointNum = 0;
            fuHaoNum = 0;
            jianHao--;
            numAKuoHao = 1;
            inKuoHao = 1;
            dengYu = 0;
            point = 1;
            dengYuNum++;
        } else {
            UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:@"输入格式错误" preferredStyle:UIAlertControllerStyleAlert];
            [self presentViewController:alert animated:YES completion:nil];
            [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(pressWanCheng) userInfo:nil repeats:NO];
        }
    }
    if(Button.tag == 12) {
        [self.model.StrNum appendFormat:@"1"];
        pointNum = 1;
        fuHaoNum = 1;
        jianHao = 2;
        numAKuoHao = 0;
        dengYu = 1;
    }
    if(Button.tag == 13) {
        [self.model.StrNum appendFormat:@"2"];
        pointNum = 1;
        fuHaoNum = 1;
        jianHao = 2;
        numAKuoHao = 0;
        dengYu = 1;
    }
    if(Button.tag == 14) {
        [self.model.StrNum appendFormat:@"3"];
        pointNum = 1;
        fuHaoNum = 1;
        jianHao = 2;
        numAKuoHao = 0;
        dengYu = 1;
    }
    if (Button.tag == 15) {
        if(fuHaoNum) {
            [self.model.StrNum appendFormat:@"+"];
            pointNum = 0;
            fuHaoNum = 0;
            jianHao = 1;
            numAKuoHao = 1;
            inKuoHao = 1;
            dengYu = 0;
            point = 1;
            dengYuNum++;
        } else {
            UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:@"输入格式错误" preferredStyle:UIAlertControllerStyleAlert];
            [self presentViewController:alert animated:YES completion:nil];
            [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(pressWanCheng) userInfo:nil repeats:NO];
        }
    }
    if(Button.tag == 16) {
        [self.model.StrNum appendFormat:@"0"];
        pointNum = 1;
        fuHaoNum = 1;
        jianHao = 2;
        numAKuoHao = 0;
        dengYu = 1;
    }
    if (Button.tag == 17) {
        if(point && fuHaoNum && pointNum) {
            [self.model.StrNum appendFormat:@"."];
            pointNum = 0;
            fuHaoNum = 0;
            jianHao = 0;
            numAKuoHao = 0;
            dengYu = 0;
            point = 0;
        } else {
            UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:@"输入格式错误" preferredStyle:UIAlertControllerStyleAlert];
            [self presentViewController:alert animated:YES completion:nil];
            [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(pressWanCheng) userInfo:nil repeats:NO];
        }
    }
    if (Button.tag == 19) {
        if(dengYuNum && kuoHaoNum == 0 && dengYu) {
            [self.model.StrNum appendFormat:@"="];
            NSLog(@"%@", self.model.StrNum);
            double b = [self jiSuan:self.model.StrNum];
            NSUInteger a = [self.model.StrNum length];
            [self.model.StrNum deleteCharactersInRange:NSMakeRange(0, a)];
            [self.model.StrNum appendFormat:@"%.9g", b];
            if ([self.model.StrNum isEqual: @"inf"]) {
                NSUInteger a = [self.model.StrNum length];
                [self.model.StrNum deleteCharactersInRange:NSMakeRange(0, a)];
                [self.model.StrNum appendFormat:@"不能除以0"];
            }
        } else {
            UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:@"输入格式错误" preferredStyle:UIAlertControllerStyleAlert];
            [self presentViewController:alert animated:YES completion:nil];
            [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(pressWanCheng) userInfo:nil repeats:NO];
        }
    }
    self.model.a++;
}

/*此处插入上面四则运算的代码*/
    
@end

结果:

相关推荐
百锦再2 小时前
Android Studio 项目文件夹结构详解
android·java·ide·ios·app·android studio·idea
season_zhu3 小时前
iOS开发:关于URL解析
ios·json·swift
iOS大前端海猫4 小时前
深入解析 Swift 中的并发属性包装器:@Actor、@MainActor 和 @GlobalActor
ios·app
溪饱鱼5 小时前
DHgate爆火背后的技术原因
android·前端·ios
增强6 小时前
腾讯云 人脸核身 Flutter 插件功能开发(一 IOS 端实现)
ios
鸿蒙布道师9 小时前
鸿蒙NEXT开发图片相关工具类(ArkTs)
android·ios·华为·harmonyos·arkts·鸿蒙系统·huawei
东东爱编码9 小时前
一路磕磕绊绊解决flutter doctor 报错CocoaPods not installed
flutter·xcode·cocoapods
yzwdzkn1 天前
解决Flutter 2.10.5在升级Xcode 16后的各种报错
flutter·macos·xcode
Unlimitedz1 天前
iOS内存管理中的强引用问题
macos·ios·cocoa
雨夜赶路人1 天前
iOS开发--接入ADMob广告失败
ios