首页 > 试题广场 > 简单表达式计算
[编程题]简单表达式计算

给定一个合法的表达式字符串,其中只包含非负整数、加法、减法以及乘法符号(不会有括号),例如7+3*4*5+2+4-3-1,请写程序计算该表达式的结果并输出;


输入描述:
输入有多行,每行是一个表达式,输入以END作为结束


输出描述:
每行表达式的计算结果
示例1

输入

7+3*4*5+2+4-3-1
2-3*1
END

输出

69
-1

备注:
每个表达式的长度不超过10000,保证所有中间结果和最后结果在[-2e9,2e9]范围内
def main():
    while 1:
        i = input()
        if i == "END":
            break
        exec("print("+i+")")

if __name__=="__main__":
    main()
python 直接exec就完事了
运行时间:34ms    占用内存:3840k

发表于 2019-06-26 18:23:22 回复(0)
#include <stdio.h>
#include <string.h>
#include <stack>
using namespace std;
#define ctoi(x)  x=='+'? 0 : x=='-' ? 1 : x=='*' ? 2 :3
int pr[4][4]=
{
    1,1,0,1,
    1,1,0,1,
    1,1,1,1,
    0,0,0,0
};
int main()
{
    stack<int> nums;
    stack<int> op;

    char str[10000];
    while(gets(str))
    {
        if(strcmp(str,"END") == 0)
            break;
        while(!nums.empty())
            nums.pop();
        while(!op.empty())
            op.pop();
        op.push(3);
        int len =strlen(str);
        str[len]='#';
        int idx=0;
        while(idx<=len)
        {
            if(str[idx]== ' ')
            {
                idx++;
            }
            else if(str[idx]>='0'&&str[idx]<='9')
            {
                int tmp=0;
                while(str[idx]>='0'&&str[idx]<='9')
                {
                    tmp=tmp*10+str[idx]-'0';
                    idx++;
                }
                nums.push(tmp);
            }
            else
            {
                while(pr[op.top()][ctoi(str[idx])]==1)
                {
                    int x2=nums.top();
                    nums.pop();
                    int x1=nums.top();
                    nums.pop();
                    int rst;
                    int ops =op.top();
                    op.pop();
                    switch(ops){
                    case 0: rst=x1+x2;break;
                    case 1: rst=x1-x2;break;
                    case 2: rst=x1*x2;break;


                    }
                    nums.push(rst);

                }
                op.push(ctoi(str[idx]));
                idx++;
            }
        }

        if(op.size()==2)
        {
            printf("%d\n",nums.top());
        }
    }
    return 0;
}

发表于 2019-08-05 11:15:07 回复(0)
while(line=readline()){
var lines = line.split('\r');
for(var i=0;i<lines.length;i++){
if(lines[i]=='END') break;
else print(eval(lines[i]));
}
}
对于js来说eval 就完事了
编辑于 2019-05-31 10:49:31 回复(2)
#include<iostream>
#include<stdlib.h>
#include<string.h>
using namespace std;

struct Node
{     int val;     Node *next;     Node():val(0),next(NULL){     }
};

int main()
{
    string S;
    while(cin>>S)
    {
        if(S != "END")
        {
            string str,str1,str2;
            int num[3] = {0},val = 0;
            Node *Head = new Node;
            Node *currentNode = Head;
            for(int i=0;i<S.length();++i)//将数字和符号分开
            {
                if(S[i]>='0' && S[i]<='9')
                {
                    val = val*10+S[i]-'0';
                }
                else if(S[i]=='*' || S[i]=='-' || S[i]=='+')
                {
                    Node *newNode = new Node;  //数字存放再链表中
                    newNode->val = val;
                    currentNode->next = newNode;
                    currentNode = newNode;
                    val = 0;

                    str += S[i];
                    if(S[i]=='*')
                        num[0]++;
                    if(S[i]=='-')
                        num[1]++;
                    if(S[i]=='+')
                        num[2]++;
                }
                if(i== S.length()-1)
                {
                    Node *newNode = new Node;
                    newNode->val = val;
                    currentNode->next = newNode;
                    currentNode = newNode;
                }
            }
            currentNode = Head->next;
            Node *preNode = Head;
            while(num[0] != 0)//先算乘法
            {
                int idx = str.find('*');
                for(int i=0;i<idx+1;++i)
                {
                    preNode = currentNode;
                    currentNode = currentNode->next;
                }
                preNode->val = currentNode->val * preNode->val;保留计算的结果
                preNode->next = currentNode->next;//算完的从链表中删除,
                str1 = str.substr(0,idx);
                str2 = str.substr(idx+1,str.length()-idx-1);//删除已用过的符号
                str = str1+str2;
                currentNode = Head->next;
                preNode = Head;
                num[0]--;
            }

            while(num[1] != 0)
            {
                int idx = str.find('-');
                for(int i=0;i<idx+1;++i)
                {
                    preNode = currentNode;
                    currentNode = currentNode->next;
                }
                preNode->val = preNode->val - currentNode->val;
                preNode->next = currentNode->next;
                str1 = str.substr(0,idx);
                str2 = str.substr(idx+1,str.length()-idx-1);
                str = str1+str2;
                currentNode = Head->next;
                preNode = Head;
                num[1]--;
            }
            int Y=0;
            while(currentNode)//除了乘法和减法,剩下的全是加法,累加得最终结果
            {
                Y += currentNode->val;
                currentNode = currentNode->next;
            }
            cout<<Y<<endl;
        }
    }
    return 0;
}
应用链表的知识
发表于 2019-05-15 15:43:10 回复(1)
C++的,可能不够简洁,但是思路可以参考。反正牛客的例子都能100%AC,如果有纰漏,欢迎指正。。。只是说明一下自己的思路,用C++实现一下。。

#include<cstdio>
#include<vector>
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;

//opt存储的,是该计算式依次的操作符号信息,pair第一个值表示该符号是+  -  *  哪一种,第二个值表示该符号在计算式中出现的位置
int main()
{
    string str;
    while (cin >> str)
    {
        if (str == "END")
            break;
                                    
        vector<pair<int, int>> opt;//pair第一个值0表示正,1表示负,2表示*   第二个值表示出现的位置

        opt.push_back(pair<int, int>(0, -1));//为了后面方便,对第一个算式因子,前面加一个“+”号,使得每一个算式因子前面,都有一个符号    //此时,opt的size和the_num的size,是一样大小的了
        for (int i = 0; i < str.size(); ++i)  //opt的初始化
        {
            if (str[i] == '+')
                opt.push_back(pair<int, int>(0, i));
            else if (str[i] == '-')
                opt.push_back(pair<int, int>(1, i));
            else if (str[i] == '*')
                opt.push_back(pair<int, int>(2, i));
        }

        vector<int> the_num;//保存计算式中,各个算式因子(按理来说第一个数可能是负数,但是本题没有负整数,不用考虑首位出现符号的情况)
        for (int i = 1; i < opt.size(); ++i)
        {
            the_num.push_back(stoi(str.substr(opt[i - 1].second + 1, opt[i].second - opt[i - 1].second - 1)));
        }
        the_num.push_back(stoi(str.substr(opt[opt.size() - 1].second+1)));//最后一个算式因子的加入

        
        int res=0;//存放最终结果

        //关于res结果的计算,分两个步骤,第一步,只计算各个乘法块的值
        int temp = 1;//用于辅助乘法块,做积的操作
        int add_or_minus;//对于每一个乘法块的结果,是加到res上,还是从res减去
        for (int i = 0; i < the_num.size(); ++i)
        {
            if (opt[i].first == 2)//乘法块出现了
            {
                add_or_minus = opt[i - 1].first;//该乘法块最前面的符号是什么,记录下来
                temp *= the_num[i - 1];
            
                while (i<the_num.size() && opt[i].first == 2)
                {
                    temp *= the_num[i];
                    ++i;
                }
                --i;//上面会多加一次的,这里减去,试一个例子就能明白

                if (add_or_minus == 0)//乘法块加到res上
                    res += temp;
                else//乘法块减到res上
                    res -= temp;

                temp = 1;//变回1,以便后续乘法块的使用
            }
        }

        //步骤2,:乘法块都解决完了,剩下的就是单个数的加法和减法的操作了
        for (int i = 0; i < the_num.size(); ++i)
        {
            if (opt[i].first == 2 || (i + 1 < the_num.size() && opt[i + 1].first == 2))//碰见乘法块,直接跳过
                continue;
            if (opt[i].first == 0)
                res += the_num[i];
            else
                res -= the_num[i];
        }
        cout << res << endl;
    }
    return 0;
}
发表于 今天 00:00:15 回复(0)
def main():
    while 1:
        i = input()
        if i == "END":
            break
        exec("print(" + i + ")")
if __name__ == "__main__":
    main()

发表于 2019-08-20 16:09:36 回复(0)
try:
    while True:
        line = input()
        if line == 'END':
            break
        jiafa = line.split('+')
        result = 0
        for j in range(len(jiafa)):
            jianfa = jiafa[j].split('-')
            for i in range(len(jianfa)):
                chengfa = jianfa[i].split('*')
                for c in range(len(chengfa)):
                    chufa = chengfa[c].split('/')
                    res = int(chufa[0])
                    if len(chufa)>1:
                        for u in range(1, len(chufa)):
                            res = int(res/int(chufa[u]))
                    chengfa[c] = res
                res = chengfa[0]
                if len(chengfa) > 1:
                    for u in range(1, len(chengfa)):
                        res = res*chengfa[u]
                jianfa[i] = res
            res = jianfa[0]
            if len(jianfa) > 1:
                for u in range(1, len(jianfa)):
                    res -= jianfa[u]
            result += res
        print(result)
except:
    pass

发表于 2019-08-20 10:40:01 回复(0)
来个好理解的,递归
import sys
def cal(s):
    if '+' in s:
        res = 0
        for i in s.split('+'):
            res += cal(i)
        return res
    if '-' in s:
        temp = s.split('-')
        res = cal(temp[0])
        for i in temp[1:]:
            res -= cal(i)
        return res      
    if '*' in s:
        res = 1
        for i in s.split('*'):
            res *= int(i)
        return res
    return int(s)
while True:
    s = sys.stdin.readline().strip()
    if s == 'END':
        break
    print(cal(s))

发表于 2019-08-19 21:59:38 回复(0)
import java.util.*;
 
public class Main {
    public static void main(String[] args) {
        Scanner reader = new Scanner(System.in);
        ArrayList<String> list = new ArrayList<>();
        String str = "";
        while (!"END".equals(str = reader.nextLine())) {
            list.add(str);
        }
        list.forEach(Main::Fun);
    }
 
    public static void Fun(String str) {
        LinkedList<Integer> nums = new LinkedList<>();
        LinkedList<Character> ops = new LinkedList<>();
        int i = 0;
        while (i < str.length()) {
            if (str.charAt(i) >= '0' && str.charAt(i) <= '9') {
                int start = i;
                i++;
                while (i < str.length() && (str.charAt(i) >= '0' && str.charAt(i) <= '9')) {
                    i++;
                }
                String a = i == str.length() - 1 ? str.substring(start) : str.substring(start, i);
                nums.add(Integer.parseInt(a));
            } else {
                ops.add(str.charAt(i));
                i++;
            }
        }
        Stack<Integer> stack = new Stack<>();
        if (nums.size() < 2) {
            return;
        }
        stack.push(nums.poll());
        stack.push(nums.poll());
        while (!ops.isEmpty()) {
            char op = ops.poll();
            if ((op == '+' || op == '-') && (!ops.isEmpty() && (ops.getFirst() == '*'))) {
                //如果加法、减法后面一个操作是乘法,则乘法优先操作
                if (!nums.isEmpty()) {
                    stack.push(nums.poll());
                    int a = stack.pop();
                    int b = stack.pop();
                    stack.push(a * b);
                    ops.poll();
                    ops.addFirst(op);
                } else {
                    return;
                }
            } else {
                if (op == '+') {
                    int a = stack.pop();
                    int b = stack.pop();
                    stack.push(a + b);
                } else if (op == '-') {
                    int a = stack.pop();
                    int b = stack.pop();
                    stack.push(b - a);
                } else if (op == '*') {
                    int a = stack.pop();
                    int b = stack.pop();
                    stack.push(a * b);
                }
                if(!nums.isEmpty()){
                    stack.push(nums.poll());
                }
            }
        }
        System.out.println(stack.pop());
    }
}

发表于 2019-08-19 13:57:05 回复(0)
细心是美好生活的前提。
#include<bits/stdc++.h>
using namespace std;
string str;
unordered_map<char, int> m;

void tran(vector<string>& sv){
    stack<char> sop;
    for(int i = 0; i < str.length(); i++){
        string st;
        while(i < str.length() && m[str[i]] == 0){
            st.push_back(str[i]);
            i++;
        }
        sv.push_back(st);
        if(i == str.length()){ // 关键的判断
            break;
        }
        if(sop.empty()){
            sop.push(str[i]);
        }else{
            while(!sop.empty() && m[sop.top()] >= m[str[i]]){
                char op = sop.top();
                string t;
                t.push_back(op);
                sop.pop();
                sv.push_back(t);
            }
            sop.push(str[i]);
        }
    }
    while(!sop.empty()){
        char op = sop.top();
        sop.pop();
        string t;
        t.push_back(op);
        sv.push_back(t);
    }
}
int main(){
    m['*'] = 2;
    m['/'] = 2;
    m['+'] = 1;
    m['-'] = 1;
    stack<int> st;

    while(cin >> str){
        if(str == " "){
            continue;
        }
        if (str == "END"){
            break;
        }
        vector<string> sv;
        // 转换为后缀表达式
        tran(sv);

        // 计算后缀表达式的值
        for(int i = 0; i < sv.size(); i++){
            if(sv[i] == "+" || sv[i] == "-" || sv[i] == "*" || sv[i] == "/"){
                int a = st.top();
                st.pop();
                int b = st.top();
                st.pop();
                if(sv[i] == "+"){
                    st.push(a+b);
                }else if(sv[i] == "-"){
                    st.push(b-a);
                }else if(sv[i] == "*"){
                    st.push(a*b);
                }else if(sv[i] == "/"){
                    st.push(b/a);
                }
            }else{
                st.push(stoi(sv[i]));
            }
        }
        cout << st.top() << endl;
        st.pop();
    }
    return 0;
}

编辑于 2019-08-21 20:45:09 回复(2)
好奇为啥用eval不通过
发表于 2019-08-17 00:23:37 回复(0)
#法一:直接eval
while True:
    try:
        s = input()
        if s != "END":
            print(eval(s))
    except:
        break

# 法二
def getdigit(s):
    k = 0
    while k < len(s) and s[k].isdigit():
        k += 1
    num = int(s[:k])
    return num, k

while True:
    try:
        s = input()
        #if s != "END":
        #    print(eval(s))
        flag = 1
        res = []
        i = 0
        while i < len(s):
            if s[i] == "+":
                flag = 1
                i += 1
            elif s[i] == "-":
                flag = -1
                i += 1
            elif s[i] == "*":
                num, k = getdigit(s[i+1:])
                i += k+1
                res[-1] *= num
            else:
                num, k = getdigit(s[i:])
                res.append(flag*num)
                i += k
                flag = 1
        print(sum(res))
    except:
        break


编辑于 2019-08-15 16:30:35 回复(0)

import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        while(in.hasNext()){
            String express = in.nextLine();
            if(express.contains("END")){
                break;
            }else{
                Main main = new Main();
                String sufix = main.infix2Sufix(express);
                int result = main.calcSufix(sufix);
                System.out.println(result);
                 
            }
        }
    }
   
     /**
     * 计算后缀表达式
     * 遍历后缀表达式,如果遇到数字则入栈,如果遇到符号,则出栈两个数字,进行计算,然后将计算结果入栈
     *
     * @param express
     * @return
     */
    public int calcSufix(String express) {
        Stack<Integer> numStack = new Stack<>();
        String[] expressArr = express.split(" ");
        for (int i = 0; i < expressArr.length; i++) {
            String cur = expressArr[i];
            if (isNumber(cur)) {
                numStack.push(Integer.valueOf(cur));
            } else {
                int num1 = numStack.pop();
                int num2 = numStack.pop();
                int re = cal(num2, num1, cur);
                numStack.push(re);
            }
        }
        return numStack.pop();
    }

    /**
     * 中缀表达式转后缀表达式
     * 依次遍历表达式中的元素,遇到数字则输出,遇到符号则入栈,如果符号为有括号或者优先级不高于栈顶元素,则将栈顶元素出栈并输出
     *
     * @param express
     * @return
     */
    private String infix2Sufix(String express) {
        char[] expressArray = express.trim().toCharArray();
        StringBuilder sb = new StringBuilder();
        Stack<Character> opStack = new Stack<>();
        for (int i = 0; i < expressArray.length; ) {
            char curChar = expressArray[i];
            if (curChar >= '0' && curChar <= '9') {
                while (i < expressArray.length && expressArray[i] >= '0' && expressArray[i] <= '9') {
                    sb.append(expressArray[i]);
                    i++;
                }
                sb.append(" ");
            } else {
                if (curChar == ')') {
                    while (!opStack.isEmpty() && opStack.peek() != '(') {
                        sb.append(opStack.peek());
                        sb.append(" ");
                        opStack.pop();
                    }
                    if (!opStack.isEmpty() && opStack.peek() == '(') {
                        opStack.pop();
                    }
                } else if (getPriority(curChar) == 1 || getPriority(curChar) == 0) {
                    while (!opStack.isEmpty() && hasHigerOrEqualPriority(opStack.peek(), curChar)) {
                        sb.append(opStack.peek());
                        sb.append(" ");
                        opStack.pop();
                    }
                    opStack.push(curChar);
                } else {
                    opStack.push(curChar);
                }
                i++;
            }
        }
        while (!opStack.isEmpty()) {
            sb.append(opStack.pop());
            sb.append(" ");
        }
        return sb.toString();
    }

    private boolean hasHigerOrEqualPriority(char c1, char c2) {
        if (getPriority(c1) >= getPriority(c2)) {
            return true;
        } else {
            return false;
        }
    }

    private int getPriority(char c1) {
        if ((c1 == '*' || c1 == '/')) {
            return 1;
        } else if ((c1 == '+' || c1 == '-')) {
            return 0;
        } else {
            return Integer.MIN_VALUE;
        }
    }
    
    private boolean isNumber(String s){
        try{
            Integer.valueOf(s);
            return true;
        }catch (Exception e){
            return false;
        }
    }

    private int cal(int num1, int num2, String op) {
        switch (op) {
            case "+":
                return num1 + num2;
            case "-":
                return num1 - num2;
            case "*":
                return num1 * num2;
            case "/":
                return num1 / num2;
            default:
                return 0;
        }

    }
}


编辑于 2019-08-13 19:32:45 回复(0)
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.Stack;

public class Main {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		while(scanner.hasNext()) {
			String string = scanner.next();
			if(string.equals("END")) break;
			char[] ch = string.toCharArray();
			Stack<String> stack = new Stack<>();
			int sum = 0;
			for(int i = 0; i < ch.length; i++) {
				if(ch[i] >= '0' && ch[i] <= '9') {
					sum = sum * 10 + (ch[i] - '0');
				}
				else {
					stack.push(String.valueOf(sum));
					sum = 0;
					stack.push(String.valueOf(ch[i]));
				}
			}
			stack.push(String.valueOf(sum));
			System.out.println(solution(stack));
		}
	}
	public static int solution(Stack<String> stack) {
		Stack<String> stack1 = new Stack<>();
		while(!stack.isEmpty()) {
			String str = stack.pop();
			if(stack1.isEmpty()) stack1.push(str);
			else {
				String str1 = stack1.peek();
				if(str1.equals("*")) {
					int stackNum = Integer.valueOf(str);
					stack1.pop();
					int stack1Num = Integer.valueOf(stack1.pop());
					stack1.push("" + (stackNum * stack1Num));
				}
				else {
					stack1.push(str);
				}
			}
		}
		int sum = 0;
		
		Stack<String> stack2 = new Stack<>();
		while(!stack1.isEmpty()) {
			stack2.push(stack1.pop());
		}
		while(!stack2.isEmpty()) {
			int num = Integer.valueOf(stack2.pop());
			sum = stack2.isEmpty() || !stack2.isEmpty() && stack2.pop().equals("+") ? sum + num : sum - num;
		}
		return sum;
	}
}

发表于 2019-08-12 14:52:55 回复(0)
# 常规解法
# 单个表达式
# 时间复杂度: O(n)
# 空间复杂度: O(n), 栈
import sys

def compute(op1, op2, opt):
	if opt == '+':
		return op1 + op2
	elif opt == '-':
		return op1 - op2
	elif opt == '*':
		return op1 * op2
	else:
		raise Exception('error')

	
input_strs = []
for line in sys.stdin:
	input_strs.append(line.replace("\n", ""))
priority = {ord('+'): 0, ord('-'): 0, ord('*'): 1}
for line in input_strs:
	if line == 'END':
		break
	# 利用栈保存结果
	stack_result = []
	k = 0
	index = 0
	length_line = len(line)
	while index < length_line:
		if line[index] in ['*', '-', '+']:
			# print(stack_result)
			if len(stack_result) and stack_result[-1] == '*':
				op2 = k
				opt = stack_result.pop(-1)
				op1 = stack_result.pop(-1)
				stack_result.append(compute(op1, op2, opt))
				stack_result.append(line[index])
			else:
				# 压入操作数和操作符
				stack_result.append(k)
				stack_result.append(line[index])
			k = 0
			index += 1
		else:
			k = k * 10 + int(line[index])
			index += 1
			continue
	stack_result.append(k)
	if stack_result[-2] == '*':
		# 计算最后一个表达式(可能是乘法)
		op2 = stack_result.pop(-1)
		opt = stack_result.pop(-1)
		op1 = stack_result.pop(-1)
		stack_result.append(compute(op1, op2, opt))
	# 计算栈中剩余数字的结果(只有加法或者减法)
	while len(stack_result) > 1:
		# print(stack_result)
		op1 = stack_result.pop(0)
		opt = stack_result.pop(0)
		op2 = stack_result.pop(0)
		stack_result.insert(0, compute(op1, op2, opt))
	print(stack_result[0])

发表于 2019-08-09 21:29:35 回复(0)
//用 eval 计算字符串 表达式
computerString(str){
let arr = str.split(/\n/);
arr[arr.length-1]=arr[arr.length-1].replace(/\s/g,'')
for(let i =0;i<arr.length;i++){
if(i!=arr.length-1){
console.log(eval(arr[i]))
}else{
console.log(arr[i])
}
}
},
发表于 2019-05-29 16:23:20 回复(0)
看看有多少人跟我一样赖皮
importjava.io.BufferedReader;
importjava.io.FileInputStream;
importjava.io.IOException;
importjava.io.InputStreamReader;
 
importjavax.script.ScriptEngine;
importjavax.script.ScriptEngineManager;
importjavax.script.ScriptException;
 
publicclassMain {
    publicstaticvoidmain(String[] args) throwsScriptException, IOException {
        BufferedReader in = newBufferedReader(newInputStreamReader(System.in));
        String line;
        ScriptEngine scriptEngine = newScriptEngineManager().getEngineByName("nashorn");
        while(!(line = in.readLine()).equals("END")) {
            System.out.println(String.valueOf(scriptEngine.eval(line)));
        }
        in.close();
    }
}

发表于 2019-05-13 15:12:37 回复(2)

热门推荐

通过挑战的用户

查看代码