iOS——仿写计算器

news2025/1/11 20:51:11

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

实现四则运算的算法思路是:首先输入的是中缀表达式的字符串,然后将其转为计算机可以理解的后缀表达式,然后将后缀表达式求值:
中缀转后缀表达式思路参考:《数据结构》:中缀表达式转后缀表达式 + 后缀表达式的计算
在该思路的基础上,会遇见以下几个问题:

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

结果:
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1067829.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

竹云筑基,量子加密| 竹云携手国盾量子构建量子身份安全防护体系

9月23日-24日&#xff0c;2023量子产业大会在安徽合肥举行。作为量子科技领域行业盛会&#xff0c;2023年量子产业大会以“协同创新 量点未来”为主题&#xff0c;展示了前沿的量子信息技术、产业创新成果&#xff0c;并举办主旨论坛、量子科普讲座等系列专项活动。量子信息作为…

多种方案教你彻底解决mac npm install -g后仍然不行怎么办sudo: xxx: command not found

问题概述 某些时候我们成功执行了npm install -g xxx&#xff0c;但是执行完成以后&#xff0c;使用我们全局新安装的包依然不行&#xff0c;如何解决呢&#xff1f; 解决方案1&#xff1a; step1: 查看npm 全局文件安装地址 XXXCN_CXXXMD6M ~ % npm list -g …

45 二叉树的右视图

二叉树的右视图 题解1 层序遍历——BFS题解2 递归——DFS 给定一个二叉树的根节点 root&#xff0c;想象自己站在它的右侧&#xff0c;按照从顶部到底部的顺序&#xff0c;返回从右侧所能看到的节点值。 提示: 二叉树的节点个数的范围是 [0,100]-100 < Node.val < 100 …

使用Docker安装Redis

一、如果虚拟机有redis运行则&#xff0c;关闭本地redis 1、查看redis是否运行 ps -ef | grep redis 2、 关闭本地redis redis-cli -a 123456 shutdown 3、如果需要启动本地redis #切换到redis目录 cd /opt/redis/bin redis-server redis.conf #关闭进程 kill [进程号] 二、…

element-plus自动引入组件报错,例如collapse、loading

element-plus自动引入组件&#xff0c;例如collapse、loading&#xff0c;使用时报错&#xff0c;报错信息如下图所示&#xff1a; 解决办法&#xff1a;vite-config.ts改变vue的引入顺序&#xff0c;将vue放在第一个

从0开始python学习-30.selenium frame子页面切换

目录 1. frame切换逻辑 2. 多层子页面情况进行切换 3. 多个子页面相互切换 1. frame切换逻辑 1.1. 子页面的类型一般分为两种 frame标签 iframe标签 1.2. 子页面里面的元素和主页面的元素是相互独立 子页面元素需要进去切换才能操作 如果已经进入子页面&#xff0c;那么…

[python 刷题] 3 Longest Substring Without Repeating Characters

[python 刷题] 3 Longest Substring Without Repeating Characters 题目&#xff1a; Given a string s, find the length of the longest substring without repeating characters. 这到提要求找的是最长的&#xff0c;没有重复符号的子字符串 解题思路是用双指针哈希表&…

华为云API自然语言处理的魅力—AI情感分析、文本分析

云服务、API、SDK&#xff0c;调试&#xff0c;查看&#xff0c;我都行 阅读短文您可以学习到&#xff1a;人工智能AI自言语言的情感分析、文本分词、文本翻译 1 IntelliJ IDEA 之API插件介绍 API插件支持 VS Code IDE、IntelliJ IDEA等平台、以及华为云自研 CodeArts IDE&a…

JDBC-day02(使用PreparedStatement实现CRUD操作)

所需的数据库数据要导入到自己的数据库库中 三&#xff1a;使用PreparedStatement实现CRUD操作 数据库连接被用于向数据库服务器发送命令和 SQL 语句&#xff0c;并接受数据库服务器返回的结果。其实一个数据库连接就是一个Socket连接。CRUD操作&#xff1a;根据返回值的有无…

Flink学习笔记(一):Flink重要概念和原理

文章目录 1、Flink 介绍2、Flink 概述3、Flink 组件介绍3.1、Deploy 物理部署层3.2、Runtime 核心层3.3、API&Libraries 层3.4、扩展库 4、Flink 四大基石4.1、Checkpoint4.2、State4.3、Time4.4、Window 5、Flink 的应用场景5.1、Event-driven Applications【事件驱动】5.…

Flink+Doris 实时数仓

Flink+Doris 实时数仓 Doris基本原理 Doris基本架构非常简单,只有FE(Frontend)、BE(Backend)两种角色,不依赖任何外部组件,对部署和运维非常友好。架构图如下 可以 看到Doris 的数仓架构十分简洁,不依赖 Hadoop 生态组件,构建及运维成本较低。 FE(Frontend)以 Java 语…

好奇喵 | PT(Private Tracker)——什么是P2P,什么是BT,啥子是PT?

前言 有时候会听到别人谈论pt&#xff0c;好奇猫病又犯了&#xff0c;啥子是pt&#xff1f; PT——你有pt吗&#xff1f;啥是pt&#xff1f; 从BT开始 BitTorrent是一种点对点&#xff08;P2P&#xff09;文件共享协议&#xff0c;用于高速下载和上传大型文件。它允许用户通…

【Oracle】Oracle系列十九--Oracle的体系结构

文章目录 往期回顾前言1. 物理结构2. 内存结构2.1 SGA2.2 后台进程 3. 逻辑结构 往期回顾 【Oracle】Oracle系列之一–Oracle数据类型 【Oracle】Oracle系列之二–Oracle数据字典 【Oracle】Oracle系列之三–Oracle字符集 【Oracle】Oracle系列之四–用户管理 【Oracle】Or…

Springboot项目log4j与logback的Jar包冲突问题

异常信息关键词&#xff1a; SLF4J: Class path contains multiple SLF4J bindings. ERROR in ch.qos.logback.core.joran.spi.Interpreter24:14 - no applicable action for [properties], current ElementPath is [[configuration][properties]] 详细异常信息&#xff1a…

【深度学习】UNIT-DDPM核心讲解

文章目录 大致介绍&#xff1a;扩散损失&#xff1a;转换损失&#xff1a;循环一致性损失&#xff1a;推理过程&#xff1a;优缺点&#xff1a; 参考文章&#xff1a; https://blog.csdn.net/ssshyeong/article/details/127210086 这篇文章对整个文章 UNIT-DDPM: UNpaired Imag…

Reactor 模式网络服务器【I/O多路复用】(C++实现)

前导&#xff1a;本文是 I/O 多路复用的升级和实践&#xff0c;如果想实现一个类似的服务器的话&#xff0c;需要事先学习 epoll 服务器的编写。 友情链接&#xff1a; 高级 I/O【Linux】 I/O 多路复用【Linux/网络】&#xff08;C实现 epoll、select 和 epoll 服务器&#x…

开发与运营:“开发”和“运营”角色有何不同和重叠?

开发和运营是促进软件系统交付的两种角色。大多数大规模构建软件的组织都会雇用这两个学科的人员。不过,开发和运维并不是完全孤立的。团队重叠并实现更高的吞吐量是很常见的。 在本文中,您将学习区分开发人员和操作人员之间的主要区别,以及它们重叠的方式。尽管有将两者结合…

Synchronized的实现和锁升级

1.JVM是如何处理和识别Synchronized的&#xff1f; 我们从字节码角度分析synchronized的实现&#xff1a; Synchronized(锁对象){}同步代码块底层实现方式是monitorenter和monitorexit指令。 修饰普通同步方法时底层实现方式是执行指令会检查方法是否设置ACC_SYNCHRONIZED&am…

11个在线免费调整图像大小而不会降低质量工具

图片对于增强您的网站、博客和其他在线平台的视觉效果非常重要&#xff0c;而这些图片的正确尺寸在这里起着重要作用。如果您有多种尺寸的图像并且想要调整为一个尺寸&#xff0c;可以使用多种在线图像调整工具。使用在线工具&#xff0c;没有软件下载或安装的麻烦&#xff0c;…

比较常见的在线项目管理系统有哪些?

在线项目管理系统作为一个适用于各领域任务管理、工时收集、团队协作与即时沟通的企业级在线项目管理解决方案&#xff0c;可以为用户同时协调和管理数以百计的项目和团队成员&#xff0c;而软件所具有的成熟&#xff0c;可靠和友好特性&#xff0c;将不再让用户在易用性和功能…