iOS仿写计算器中缀转后缀 表达式求值

github地址

iOS计算器

准备工作

由于OC没有自带的栈文件,只能链表模拟栈

typedef struct {
    char data[50];
    int top;
}Stack;//符号栈
//之前把Double写成了Char改了两天的bug后来还是岳靖翔哥哥改好的
//爱岳靖翔哥哥
typedef struct {
    double data[50];
    int top;
}StackNum;//数字栈

需要用到的方法

//出栈
- (void) pop:(Stack *)stack {
    stack->top = stack->top-1;
}
//进符号栈
- (void) pushfu: (char)s: (Stack *)stack {
    stack->top++;
    stack->data[stack->top] = s;
}
//进数字栈
- (void) pushshu: (double)s: (StackNum *)stack {
    stack->top++;
    stack->data[stack->top] = s;
}
//判断栈空
- (BOOL)isEmpty:(Stack *)stack {
    if (stack->top == -1) {
        return true;
    } else {
        return false;
    }
}
//判断运算符优先级
- (int) whoFirst:(char) c {
    if (c == '('){
        return 0;
    } else if (c == '+' || c == '-') {
        return 1;
    } else if (c == '*' || c == '/') {
        return 2;
    }
    return 0;
}
//数字运算 用于之后的后缀表达式求值
- (double) jieshu: (double)a : (double)b : (char)c {
    if (c == '+')
        return a + b;
    if (c == '-')
        return a - b;
    if (c == '*')
        return a * b;
    if (c == '/')
        return a / b;
    return 0;
}
//括号是否匹配 用于后来按下计算器中等于键之后的防止括号不匹配问题
- (BOOL) piPei: (char *)s {
    int len = strlen(s);
    for (int i = 0; i<len; i++) {
          if(s[i]=='('&&s[i+1]==')')
              return false;
      }
    Stack *stack = malloc(sizeof(Stack));
    stack->top = -1;
    for (int i = 0; i<len; i++) {
        if (s[i] == '(') {
            stack->top++;
        }
        if (s[i] == ')') {
            if(stack->top == -1)
                return false;
            stack->top--;
        }
    }
    if (stack->top == -1) {
        return true;
    }
    else {
        return false;
    }
    return false;
}

重点方法

- (double) end:(char *)s {
	//表达式数组
    char ans[500];
    int k = 0;
    int len = strlen(s);
    s[len] = '=';
    //开辟两个栈
    Stack *fuhao = malloc(sizeof(Stack));
    fuhao->top = -1;
    
    StackNum *shu = malloc(sizeof(StackNum));
    shu->top = -1;
    //中缀转后缀
    for (int i = 0; i <= len; i++) {
        if ((s[i]>='0' && s[i] <= '9') || s[i] =='.'){
                ans[k++] = s[i];
        } else if(s[i] == '+' || s[i] == '-' || s[i] == '*' || s[i] == '/') {
            ans[k++] = '#';
            if ([self isEmpty:fuhao]) {
                    [self pushfu:s[i] :fuhao];
            } else {
                while (![self isEmpty:fuhao] && [self whoFirst:fuhao->data[fuhao->top]] >=  [self whoFirst:s[i]]) {
                    ans[k++] = fuhao->data[fuhao->top];
                    fuhao->top--;
                    }
                [self pushfu:s[i] :fuhao];
            }
        } else if (s[i] == '(') {
            [self pushfu:s[i] :fuhao];
        } else if(s[i]==')') {
            while(fuhao->data[fuhao->top] != '(') {
                ans[k++] = fuhao->data[fuhao->top];
                fuhao->top--;
            }
            fuhao->top--;;
        } else if(s[i] == '=') {
            while(![self isEmpty:fuhao]) {
                ans[k++] = fuhao->data[fuhao->top];
                fuhao->top--;
            }
        }
    }
    //验证是否转换成功
    //比如0.2*5-1(中缀表达式
    //转换成0.2#5#*1-(后缀表达式
    puts(ans);
    //后缀表达式求值
    int pos = 0;
    for (int i = 0; i < k; i++) {
        pos = 0;
        if (ans[i] >= '0' && ans[i] <= '9') {
            for(int j = i; j < k; j++) {
                if ((ans[j] >= '0' && ans[j] <= '9') || ans[j] == '.') {
                    pos++;
                } else {
                    break;
                }
            }
            double h = 1, sum1 = 0, sum2 = 0;
            for (int j = i + pos - 1; j >= i; j--) {
                if (ans[j] >= '0' && ans[j] <= '9') {
                    sum1 += (ans[j] - '0') * h;
                    h *= 10;
                } else if (ans[j] == '.') {
                    sum1 /= h;
                    h = 1;
                    sum2 += sum1;
                    sum1 = 0;
                }
            }
            sum2 += sum1;
            [self pushshu:sum2 :shu];
            i += pos - 1;
        } else if (ans[i] == '+'|| ans[i] == '-'|| ans[i] == '*'|| ans[i] == '/') {
            double x = shu->data[shu->top];
            shu->top--;
            double y = shu->data[shu->top];
            shu->top--;
            shu->top++;
            shu->data[shu->top] = [self jieshu :y :x :ans[i] ];
        }
    }
    return shu->data[shu->top];
}

完整代码就是上面的加起来 组成MVC设计模式中的M

你可能感兴趣的:(ios,栈)