分享一段计算24点的程序,后缀表达式计算

//分享一段计算24点的程序,用后缀表达式计算,自己写的,全排列算法来自网络,没有转化成利于阅读的中缀表达式

//可以继续优化,并转换成中缀表达式,去掉重复的(例如先后顺序的差异)

import java.util.Stack;

winion 2020-5-10
public class Main {

    static char[] ops = new char[] { '?', '?', '+', '-', '*', '/' };

    static int count = 0;

    //数字的全排列
    public static void permutation(char[] ss, int i) {
        if (ss == null || i < 0 || i > ss.length) {// 1
            return;
        }
        if (i == ss.length - 1) {// 2
            gen(ss);
        } else {
            for (int j = i; j < ss.length; j++) {// 3
                char temp = ss[j];// 交换前缀,使之产生下一个前缀
                ss[j] = ss[i];
                ss[i] = temp;
                permutation(ss, i + 1);// 4
                temp = ss[j]; // 将前缀换回来,继续做上一个的前缀排列.//5
                ss[j] = ss[i];
                ss[i] = temp;
            }
        }
    }

    public static void gen(char[] ss) {
        char[] opstr = new char[7];
        opstr[0] = ss[0];
        opstr[1] = ss[1];

        ops[0] = ss[2];
        ops[1] = ss[3];
        int opcount = 0;
        int curr = 2;
        //循环产生所有的表达式组合,此处可以优化,少循环几次
        for (int i = 0; i < ops.length; i++) {
            opstr[curr++] = ops[i];
            for (int j = 0; j < ops.length; j++) {
                opstr[curr++] = ops[j];
                for (int l = 0; l < ops.length; l++) {
                    opstr[curr++] = ops[l];
                    for (int m = 0; m < ops.length; m++) {
                        opstr[curr++] = ops[m];
                        for (int n = 0; n < ops.length; n++) {
                            opstr[curr++] = ops[n];
                            // 判断是否合法,运算符的数量是三个,数字两个且无重复,另外两个在开头,不用计算
                            opcount = 0;
                            for (int p = 2; p < opstr.length; p++) {
                                if (opstr[p] == '+' || opstr[p] == '-' || opstr[p] == '*' || opstr[p] == '/') {
                                    opcount++;
                                }
                            }
                            if (opcount == 3) {
                                // 判断是否有重复数字
                                char exists = '0';
                                for (int p = 2; p < opstr.length; p++) {
                                    if (opstr[p] >= '1' && opstr[p] <= '6') {
                                        if (exists == '0')
                                            exists = opstr[p];
                                        else if (exists != '0' && exists == opstr[p]) {
                                            exists = 'E';//E代表有重复了
                                            break;
                                        }
                                    }
                                }
                                if (exists == '0' || exists != 'E') {
                                    float re = calc(opstr);
                                    System.out.println(new String(opstr) + "=" + re);
                                    if (re > 0)
                                        count++;
                                }
                            }
                            curr--;
                        }
                        curr--;
                    }
                    curr--;
                }
                curr--;
            }
            curr--;
        }
    }

    public static float calc(char[] opstr) {
        Stack<Float> temp = new Stack<>();
        for(int i=0;i<opstr.length;i++) {
            char c1 =opstr[i];
            if (c1 > '0' && c1 <= '6') {
                temp.push((int) (c1 - '0') + 0f);
            } else {
                // 运算符,每遇到一个运算符将计算栈里的数据
                if (temp.size() >= 2) {
                    float t1 = temp.pop();
                    float t2 = temp.pop();
                    if (c1 == '+') {
                        temp.push(t1 + t2);
                    } else if (c1 == '-') {
                        temp.push(t2 - t1);
                    } else if (c1 == '*') {
                        temp.push(t1 * t2);
                    } else if (c1 == '/') {
                        temp.push(t2 / t1);
                    }
                } else {
                    //如果栈里的数据不够,说明表达式错误
                    return -1f;
                }
            }
        }
        return temp.pop();
    }

    public static void main(String args[]) {
        permutation(new char[] { '6', '5', '4', '1' }, 0);
        System.out.println(count);
    }

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这里是一个简单的程序示例: ```c #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <string.h> #define STACK_SIZE 100 typedef struct { int top; char data[STACK_SIZE]; } Stack; void init_stack(Stack *s) { s->top = -1; } void push(Stack *s, char c) { if (s->top == STACK_SIZE - 1) { fprintf(stderr, "Stack overflow\n"); exit(EXIT_FAILURE); } s->data[++s->top] = c; } char pop(Stack *s) { if (s->top == -1) { fprintf(stderr, "Stack underflow\n"); exit(EXIT_FAILURE); } return s->data[s->top--]; } char peek(Stack *s) { if (s->top == -1) { fprintf(stderr, "Stack underflow\n"); exit(EXIT_FAILURE); } return s->data[s->top]; } int is_empty(Stack *s) { return s->top == -1; } int is_operator(char c) { return c == '+' || c == '-' || c == '*' || c == '/'; } int priority(char c) { switch (c) { case '+': case '-': return 1; case '*': case '/': return 2; default: return 0; } } void infix_to_postfix(char *infix, char *postfix) { Stack s; init_stack(&s); int i, j; for (i = 0, j = 0; infix[i] != '\0'; i++) { if (isdigit(infix[i]) || infix[i] == '.') { postfix[j++] = infix[i]; } else if (is_operator(infix[i])) { while (!is_empty(&s) && priority(peek(&s)) >= priority(infix[i])) { postfix[j++] = pop(&s); } push(&s, infix[i]); } else if (infix[i] == '(') { push(&s, infix[i]); } else if (infix[i] == ')') { while (!is_empty(&s) && peek(&s) != '(') { postfix[j++] = pop(&s); } if (is_empty(&s)) { fprintf(stderr, "Mismatched parentheses\n"); exit(EXIT_FAILURE); } pop(&s); } else if (isspace(infix[i])) { continue; } else { fprintf(stderr, "Invalid character: %c\n", infix[i]); exit(EXIT_FAILURE); } } while (!is_empty(&s)) { if (peek(&s) == '(') { fprintf(stderr, "Mismatched parentheses\n"); exit(EXIT_FAILURE); } postfix[j++] = pop(&s); } postfix[j] = '\0'; } double evaluate_postfix(char *postfix) { Stack s; init_stack(&s); int i; for (i = 0; postfix[i] != '\0'; i++) { if (isdigit(postfix[i])) { double num = 0; while (isdigit(postfix[i]) || postfix[i] == '.') { if (postfix[i] == '.') { i++; break; } num = num * 10 + (postfix[i] - '0'); i++; } i--; push(&s, num); } else if (is_operator(postfix[i])) { double b = pop(&s); double a = pop(&s); switch (postfix[i]) { case '+': push(&s, a + b); break; case '-': push(&s, a - b); break; case '*': push(&s, a * b); break; case '/': push(&s, a / b); break; } } else { fprintf(stderr, "Invalid character: %c\n", postfix[i]); exit(EXIT_FAILURE); } } if (s.top != 0) { fprintf(stderr, "Too many operands\n"); exit(EXIT_FAILURE); } return pop(&s); } int main() { char infix[100], postfix[100]; int choice; do { printf("Menu:\n"); printf("1. Enter infix expression\n"); printf("2. Convert and evaluate\n"); printf("3. Quit\n"); printf("Enter choice: "); scanf("%d", &choice); switch (choice) { case 1: printf("Enter infix expression: "); scanf(" %[^\n]s", infix); break; case 2: infix_to_postfix(infix, postfix); printf("Postfix expression: %s\n", postfix); printf("Result: %f\n", evaluate_postfix(postfix)); break; case 3: break; default: printf("Invalid choice\n"); break; } } while (choice != 3); return 0; } ``` 这个程序使用栈来实现将中缀表达式转换为后缀表达式,并计算后缀表达式的值。其中包括了菜单,可以让用户输入中缀表达式,转换为后缀表达式计算结果,或者退出程序。注意,这个程序假设输入的表达式是合理的,因此没有进行错误处理的情况下不一定能正确处理所有输入。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值