牛客面试Top101: BM8 表达式求值【java,go】

题目

BM49 表达式求值

题目

题解(304)

讨论(241)

排行

面经

中等 通过率:37.06% 时间限制:1秒 空间限制:256M

知识点

栈

递归

描述

请写一个整数计算器,支持加减乘三种运算和括号。

数据范围:

0≤∣s∣≤100,保证计算结果始终在整型范围内

要求:空间复杂度:

O(n),时间复杂度

O(n)

示例1

输入:

"1+2"

复制

返回值:

3

复制

示例2

输入:

"(2*(3-4))5"
复制
返回值:
-10
复制
示例3
输入:
"3+2
3*4-1"

复制

返回值:

26

Java

java 复制代码
import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 返回表达式的值
     * @param s string字符串 待计算的表达式
     * @return int整型
     */
    public int solve (String s) {
        return f_bm49(s, 0).curdata;
    }

    public Info f_bm49(String s, int i) {
        LinkedList<String> list = new LinkedList<>();
        Info info = new Info();
        int cur = 0;
        while (i < s.length() && s.charAt(i) != ')') {
            char c = s.charAt(i);
            if (c == ' ') {
                i++;
                continue;
            } else if (c >= '0' && c <= '9') {
                cur = cur * 10 + (int)(c - '0');
                i++;
            } else if (c != '(') { //遇到运算符了
                addNumToLinkedlist(list, cur);
                list.addLast(c + "");
                cur = 0;
                i++;
            } else {
                info = f_bm49(s, i + 1);
                i = info.curindex + 1;
                cur = info.curdata;
            }
        }
        addNumToLinkedlist(list, cur);
        info.curdata = getAllDataSum(
                           list); //list里只存储数字,加和减,乘除已经提前处理了
        info.curindex = i;
        return info;
    }

    public int getAllDataSum(LinkedList<String> list) {
        int cursum = 0;
        boolean add = true;
        while (!list.isEmpty()) {
            String tmp = list.pollFirst();
            if (tmp.equals("+")) add = true;
            else if (tmp.equals("-")) add = false;
            else {
                if (add) cursum += Integer.valueOf(tmp);
                else cursum -= Integer.valueOf(tmp);
            }
        }
        return cursum;
    }
    public void addNumToLinkedlist(LinkedList<String> list, int curnum) {
        if (!list.isEmpty()) {
            String top = list.pollLast();
            if (top.equals("+") || top.equals("-")) list.addLast(top);
            else {
                int tmp =   Integer.valueOf(list.pollLast());
                if (top.equals("*")) curnum = tmp * curnum;
                else curnum = tmp / curnum;
            }
        }

        list.addLast(String.valueOf(curnum));
    }
    static class Info {
        int curdata;
        int curindex;
        public Info() {}
    }
}

golang

go 复制代码
package main

import "strconv"

/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 返回表达式的值
 * @param s string字符串 待计算的表达式
 * @return int整型
 */
func solve(s string) int {
	info := dfs_zch(s, 0)
	return info.data
}

func dfs_zch(s string, i int) InfoZCH {
	doublelist := []string{}
	cur := 0
	help := InfoZCH{}
	for i < len(s) && s[i] != ')' {
		c := s[i]
		if c == ' ' {
			i++
			continue
		}

		if c >= '0' && c <= '9' {
			cur = cur*10 + int(c-'0')
			i++
		} else if c != '(' { //遇到运算符了
			addCurToList(&doublelist, cur)
			doublelist = append(doublelist, string(c))
			cur = 0
			i++
		} else {
			help = dfs_zch(s, i+1)
			i = help.index + 1
			cur = help.data
		}
	}

	addCurToList(&doublelist, cur)
	help.data = addListsum(&doublelist)
	help.index = i
	return help
}

func addListsum(doublelist *[]string) int {
	add := true
	ans := 0

	for len(*doublelist) > 0 {
		top := (*doublelist)[0]
		*doublelist = (*doublelist)[1:]
		if top == "+" {
			add = true
		} else if top == "-" {
			add = false
		} else {
			curint, _ := strconv.Atoi(top)
			if add {
				ans += curint
			} else {
				ans -= curint
			}
		}
	}
	return ans
}

func addCurToList(doublelist *[]string, cur int) {
	if len(*doublelist) > 0 {
		top := (*doublelist)[len(*doublelist)-1]
		*doublelist = (*doublelist)[:len(*doublelist)-1]
		if top == "+" || top == "-" {
			*doublelist = append(*doublelist, top)
			*doublelist = append(*doublelist, strconv.Itoa(cur))
		} else {
			if len(*doublelist) > 0 {
				prevalue := (*doublelist)[len(*doublelist)-1]
				*doublelist = (*doublelist)[:len(*doublelist)-1]
				prevalueint, _ := strconv.Atoi(prevalue)

				if top == "*" {
					cur = prevalueint * cur
				} else {
					cur = prevalueint / cur
				}
			}
			*doublelist = append(*doublelist, strconv.Itoa(cur))
		}
	} else {
		*doublelist = append(*doublelist, strconv.Itoa(cur))
	}
}

type InfoZCH struct {
	data  int
	index int
}
相关推荐
糖果豆豆1 小时前
对象是字段,还是关系?集合论和范畴论吵了三十年,答案是两个都对
算法·架构
十年Java程序媛1 小时前
Java String、StringBuilder、StringBuffer 底层原理|字符串拼接性能与线程安全
java·开发语言·spring boot·安全·面试
SamDeepThinking2 小时前
CyclicBarrier的底层实现
java·后端·面试
第六种自由2 小时前
[路飞]_Leetcode 22. 括号生成
javascript·算法·leetcode
isyoungboy2 小时前
事件驱动状态机与循环扫描状态机:两种计算模型的比较研究
算法·状态机
ShineWinsu2 小时前
对于HTML:HTML常见标签的解析—上
前端·面试·html·浏览器·标签·图片·超链接
行者全栈架构师2 小时前
【鸿蒙心迹】从手机到平板、折叠屏——多端适配自查清单与踩坑实录(HarmonyOS 7.x)
前端·算法·架构
花间相见2 小时前
【计算基础|网络13】UDP 与可靠传输
后端·面试
考研保研资料分享2 小时前
北大软微软件工程保研经验:哈工大面试追问与补录风险取舍
面试·职场和发展·软件工程
longlongzihan2 小时前
LeetCode 24.两两交换链表中的节点:虚拟头结点与指针
算法·leetcode·链表