【iOS】—— 写计算器遇到的一些问题

一.用到的知识点:

1.MVC设计模式

2.Masonry布局

3.简单四则运算

4.中缀表达式转后缀表达式

二.基本思路:

首先创建一个字符串,对应计算器中的按钮点击,点击什么给该字符串添加什么字符,一切输入完毕之后按下=就表示输入完毕,再进行下面操作,首先对最后得到的字符串进行判断,判断该字符串的格式是否正确,然后再对其进行中缀转后缀的操作,最后进行计算操作返回最后的得数,将它显示在计算器的现实屏上计算器就完成了。

写计算器没有什么太大的难度,最重要的是对前面所说的知识点的合理利用,让自己吸收之前自己学习到的知识,为之后打好基础。其中的难点就是对MVC模式中的各种数据传递和最终字符串错误的判断。

三. 基础代码:

1.判断字符串是否正确:

给一个数组每个单位分别存储数字和运算符,然后对这个数组进行判断。

- (void)checkErrors:(NSMutableArray *)floatArray {
    //计算可变数组的长度
    NSInteger length = 0;
    while (![floatArray[length] isEqualToString:@"="]) {
        length++;
    }
    
    //判断字符串的第一个字符是不是运算符
    if (OCCompare(floatArray[0]) == 1 || OCCompare(floatArray[0]) == 2) {
        self.search = 1;
        return;
    }
    
    //除法运算的分母不为0
    NSInteger i = 0;
    while (i < length - 1) {
        if ([floatArray[i] isEqualToString:@"/"] && [floatArray[i + 1] isEqualToString:@"0"]) {
            self.search = 1;
            return;
        }
        i++;
    }
    
    //括号匹配,判断字符串中的括号是否都对应
    NSMutableArray *symbolArray = [[NSMutableArray alloc] init];
    NSInteger symbolTop = -1;
    
    for (int i = 0; i < length; i++) {
        if ([floatArray[i] isEqualToString:@"("]) {
            [symbolArray addObject:@"("];
            symbolTop++;
        } else if ([floatArray[i] isEqualToString:@")"] && symbolTop != -1) {
            [symbolArray removeLastObject];
            symbolTop--;
        } else if ([floatArray[i] isEqualToString:@")"] && symbolTop == -1) {
            self.search = 1;
        } else if ([floatArray[i] isEqualToString:@"("] && [floatArray[i + 1] isEqualToString:@")"]) {
            self.search = 1;
            return;
        }
    }
    if (symbolTop != -1) {
        self.search = 1;
        return;
    }
    
    //运算符,判断字符串中的是否存在相连的运算符
    for (int i = 0; i < length - 1; i++) {
        if (OCCompare(floatArray[i]) < 4 && OCCompare(floatArray[i]) && OCCompare(floatArray[i + 1]) < 4 && OCCompare(floatArray[i + 1])) {
            self.search = 1;
            return;
        }
    }
}

//OC的比较,给出一个比较的标准,便于比较运算级的优先顺序
NSInteger OCCompare(NSString *str) {
    if ([str isEqualToString:@"+"] || [str isEqualToString:@"-"]) {
        return 1;
    } else if ([str isEqualToString:@"*"] || [str isEqualToString:@"/"]) {
        return 2;
    } else if ([str isEqualToString:@"("] || [str isEqualToString:@")"]) {
        return 4;
    } else if ([str isEqualToString:@"="]) {
        return 3;
    } else {
        return 0;
    }
}

2.中缀表达式转后缀表达式:

给一个待转换的字符串,最终返回一个转换完毕的字符串,详细的方法看我之前的博客。

//中缀转后缀
NSMutableArray* changeBehind(NSMutableArray *changeArray) {

    //计算可变数组的长度
    NSInteger length = 0;
    while (![changeArray[length] isEqualToString:@"="]) {
        length++;
    }
    
    //后缀
    NSMutableArray *behindArray = [[NSMutableArray alloc] init];
    
    //符号
    NSMutableArray *symbolArray = [[NSMutableArray alloc] init];
    NSInteger symbolTop = -1;
    
    NSInteger i = 0;

    while (i <= length) {
        if ([changeArray[i] isEqualToString:@"("]) {  //左括号就直接存入操作符栈
            [symbolArray addObject:changeArray[i]];
            i++;
            symbolTop++;
        } else if ([changeArray[i] isEqualToString:@")"]) {  //右括号就将括号中的内容逐一弹出存入后缀栈
            while (![symbolArray[symbolTop] isEqualToString:@"("]) {
                [behindArray addObject:symbolArray[symbolTop--]];
                [symbolArray removeLastObject];
            }
            [symbolArray removeLastObject];
            symbolTop--;
            i++;
        } else if (!OCCompare(changeArray[i])) { //数字就直接存入后缀栈
            if ([changeArray[i] isEqualToString:@"="]) {
                break;
            }
            [behindArray addObject:changeArray[i]];
            i++;
        } else {   //遇到操作符
            if ([changeArray[i] isEqualToString:@"="]) {
                while (symbolTop != -1) {
                    [behindArray addObject:symbolArray[symbolTop--]];
                    [symbolArray removeLastObject];
                }
            }
            if (symbolTop == -1 || OCCompare(symbolArray[symbolTop]) < OCCompare(changeArray[i]) || OCCompare(symbolArray[symbolTop]) == 4) {
                //操作符栈为空或者字符串中的操作符优先级大于操作符栈顶操作符的优先级就将该操作符压入操作符栈中
                [symbolArray addObject:changeArray[i]];
                i++;
                symbolTop++;
            } else {
                [behindArray addObject:symbolArray[symbolTop]];
                [symbolArray removeLastObject];
                symbolTop--;
            }
        }
    }
    [behindArray addObject:@"="];
    
    return behindArray;
}

3.最终将转化后的字符串根据简单的四字运算进行计算:

给一个待计算的数组,最终返回一个最终得数。

//计算结果
float endCalculation(NSMutableArray *newArray) {
    //计算可变数组的长度
    NSInteger length = 0;
    while (![newArray[length] isEqualToString:@"="]) {
        length++;
    }
    
    //计算栈
    NSMutableArray *endArray = [[NSMutableArray alloc] init];
    NSInteger endTop = -1;
    
    int i = 0;
    while (i < length) {
        if ([newArray[i] isEqualToString:@"="]) {
            break;
        }
        if (!OCCompare(newArray[i])) {
            [endArray addObject:newArray[i]];
            endTop++;
            i++;
        } else {
            NSMutableArray *transArray = [[NSMutableArray alloc] init];
            
            [transArray addObject:endArray[endTop]];
            endTop--;
            [endArray removeLastObject];
            
            [transArray addObject:endArray[endTop]];
            endTop--;
            [endArray removeLastObject];
            
            [transArray addObject:newArray[i]];
            i++;
            
            float num = Calculation(transArray);
            [endArray addObject:[NSString stringWithFormat:@"%f", num]];
            endTop++;
        }
    }
    
    return [endArray[0] floatValue];
}

代码地址:计算器

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 很抱歉,作为一个自然语言处理模型,我无法出完整的代码,但是下面是一个简单的计算器的 Objective-C 代码示例: ``` #import <Foundation/Foundation.h> int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; double value1, value2; char operator; NSLog (@"请输入第一个数字和算术运算符:"); scanf ("%lf %c", &value1, &operator); NSLog (@"请输入第二个数字:"); scanf ("%lf", &value2); if ( operator == '+' ) NSLog (@"%.2f + %.2f = %.2f", value1, value2, value1 + value2); else if ( operator == '-' ) NSLog (@"%.2f - %.2f = %.2f", value1, value2, value1 - value2); else if ( operator == '*' ) NSLog (@"%.2f * %.2f = %.2f", value1, value2, value1 * value2); else if ( operator == '/' ) NSLog (@"%.2f / %.2f = %.2f", value1, value2, value1 / value2); else NSLog (@"无效的运算符"); [pool drain]; return 0; } ``` 这是一个简单的计算器代码示例,它可以实现加减乘除运算,你可以根据需要扩展其他功能。 ### 回答2: iOS上运行的计算器代码可以使用Swift语言编写。以下是一个简单的计算器代码示例: ```swift import UIKit class ViewController: UIViewController { @IBOutlet weak var displayLabel: UILabel! var operand1: Double = 0 var operand2: Double = 0 var operation: String = "" override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. } @IBAction func numberButtonPressed(_ sender: UIButton) { let digit = sender.currentTitle! displayLabel.text! += digit } @IBAction func operationButtonPressed(_ sender: UIButton) { operation = sender.currentTitle! operand1 = Double(displayLabel.text!)! displayLabel.text = "" } @IBAction func equalsButtonPressed(_ sender: UIButton) { operand2 = Double(displayLabel.text!)! var result: Double = 0 switch operation { case "+": result = operand1 + operand2 case "-": result = operand1 - operand2 case "×": result = operand1 * operand2 case "÷": result = operand1 / operand2 default: break } displayLabel.text = String(result) } @IBAction func clearButtonPressed(_ sender: UIButton) { displayLabel.text = "" operand1 = 0 operand2 = 0 operation = "" } } ``` 这个代码示例包括一个ViewController类,它继承自UIViewController。它具有数字按钮、运算符按钮、等于按钮和清除按钮的响应函数。 CalculatorViewController类中的一些重要成员变量包括`operand1`和`operand2`,用于存储操作数的值,`operation`用于存储当前选择的运算符。 在数字按钮和操作按钮的响应函数中,将所点击的按钮的标题添加到显示标签上。 在等于按钮的响应函数中,将当前显示标签上的文本转换为数字,并根据存储的运算符执行相应的计算。然后,将结果显示在显示标签上。 清除按钮的响应函数将显示标签上的内容、操作数和运算符重置为初始状态。 这是一个简单的iOS计算器代码示例,可以根据需要进行扩展和改进。 ### 回答3: 以下是一个简单的iOS计算器代码示例: ```swift import UIKit class ViewController: UIViewController { // 创建计算器显示区域的标签 let displayLabel: UILabel = { let label = UILabel() label.font = UIFont.systemFont(ofSize: 40) label.text = "0" label.textAlignment = .right return label }() var currentNumber = "" var previousNumber = "" var operation = "" override func viewDidLoad() { super.viewDidLoad() // 设置背景颜色 view.backgroundColor = .white // 设置计算器显示区域的布局和约束 displayLabel.frame = CGRect(x: 20, y: 100, width: view.frame.size.width - 40, height: 100) view.addSubview(displayLabel) // 设置数字按钮 for i in 0..<10 { let button = UIButton(type: .system) button.setTitle("\(i)", for: .normal) button.titleLabel?.font = UIFont.systemFont(ofSize: 30) button.frame = CGRect(x: CGFloat((i % 3)) * (view.frame.size.width/3), y: CGFloat(i / 3) * (view.frame.size.width/3) + 220, width: view.frame.size.width/3, height: view.frame.size.width/3) button.addTarget(self, action: #selector(numberButtonTapped), for: .touchUpInside) view.addSubview(button) } // 设置运算符按钮 let operators = ["+", "-", "*", "/"] for (index, operator) in operators.enumerated() { let button = UIButton(type: .system) button.setTitle(operator, for: .normal) button.titleLabel?.font = UIFont.systemFont(ofSize: 30) button.frame = CGRect(x: view.frame.size.width - 80, y: CGFloat(index) * (view.frame.size.width/3) + 220, width: 60, height: view.frame.size.width/3) button.addTarget(self, action: #selector(operatorButtonTapped), for: .touchUpInside) view.addSubview(button) } // 设置等号按钮 let equalsButton = UIButton(type: .system) equalsButton.setTitle("=", for: .normal) equalsButton.titleLabel?.font = UIFont.systemFont(ofSize: 30) equalsButton.frame = CGRect(x: view.frame.size.width - 80, y: CGFloat(operators.count) * (view.frame.size.width/3) + 220, width: 60, height: view.frame.size.width/3) equalsButton.addTarget(self, action: #selector(equalsButtonTapped), for: .touchUpInside) view.addSubview(equalsButton) } // 当数字按钮被点击时调用 @objc func numberButtonTapped(_ sender: UIButton) { if let numberText = sender.titleLabel?.text { currentNumber += numberText displayLabel.text = currentNumber } } // 当运算符按钮被点击时调用 @objc func operatorButtonTapped(_ sender: UIButton) { if let operatorText = sender.titleLabel?.text { previousNumber = currentNumber currentNumber = "" operation = operatorText } } // 当等号按钮被点击时调用 @objc func equalsButtonTapped(_ sender: UIButton) { let number1 = Double(previousNumber) ?? 0.0 let number2 = Double(currentNumber) ?? 0.0 var result: Double switch operation { case "+": result = number1 + number2 case "-": result = number1 - number2 case "*": result = number1 * number2 case "/": result = number1 / number2 default: result = 0.0 } displayLabel.text = String(result) currentNumber = "" previousNumber = "" operation = "" } } ``` 这个计算器可以处理基本的加、减、乘、除运算,并在屏幕上显示结果。界面使用了按钮和标签来显示数字和运算符,并实现了按钮点击事件的处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值