算法 计算四则运算字符串结果

RingBuffer面试后面一场,输入一个字符串,计算结果

字符串内容限制为“ 0-9,+,-,*,/”这些符号

例如输入"1+2*3/4-5",返回-2.5。

开始到时候直接想到了可以用树来维护计算关系,后来被问可以用其他数据结构么,然后想到应该用栈来实现,写的时候用了一个,写到后面突然意识到应该用两个栈,一个存数据,一个存操作符。

在家里写了完成大概写了一个小时不到,当时是没写完,后来口述了一下逻辑。

重点在于:

1.第一个符号到判断,可能第一个字符是“+”或者“-”。

2.末尾非法符号判断。

3.中间连续连个操作符的判断。

具体是几行粗体代码

package com.ljw.javatest;

import java.util.LinkedList;
import java.util.Stack;

public class Calculate {

    public static void print(Object value) {
        System.out.println(value);
    }

    public static void main(String[] args) throws Exception {
        String input = null;

        input = "1+2*3/4-5";
        print(calculate(input) == -2.5);

        input = "-1+2*3/4-5";
        print(calculate(input) == -4.5);

        try {
            input = "";
            calculate(input);
        } catch (Exception ex) {
            print(ex.getMessage().equals(exMsg));
        }

        try {
            input = null;
            calculate(input);
        } catch (Exception ex) {
            print(ex.getMessage().equals(exMsg));
        }

        try {
            input = "1+2*3/4-a5";
            calculate(input);
        } catch (Exception ex) {
            print(ex.getMessage().equals(exMsg));
        }

        try {
            input = "1+2*a3/4-5";
            calculate(input);
        } catch (Exception ex) {
            print(ex.getMessage().equals(exMsg));
        }

        try {
            input = "1+2**3/4-5";
            calculate(input);
        } catch (Exception ex) {
            print(ex.getMessage().equals(exMsg));
        }

        try {
            input = "1+2*3/4+-5";
            calculate(input);
        } catch (Exception ex) {
            print(ex.getMessage().equals(exMsg));
        }

        try {
            input = "1+-2*3/4-5";
            calculate(input);
        } catch (Exception ex) {
            print(ex.getMessage().equals(exMsg));
        }

        try {
            input = "1-2*3/4-5-";
            calculate(input);
        } catch (Exception ex) {
            print(ex.getMessage().equals(exMsg));
        }

    }

    static String exMsg = "invalid input";

    public static double calculate(String input) throws Exception {
        if (input == null || input.length() == 0) {
            throw new Exception(exMsg);
        }

        char[] arr = input.toCharArray();
        Stack<Double> valueStack = new Stack();
        Stack<String> opStack = new Stack();

        StringBuilder sb = new StringBuilder();
        boolean flag = false;
        for (int i = 0; i < arr.length; i++) {
            char temp = arr[i];
            if (temp != ‘+‘ && temp != ‘-‘ && temp != ‘*‘ && temp != ‘/‘) {
                if (temp < ‘0‘ || temp > ‘9‘) {
                    throw new Exception(exMsg);
                }
                sb.append(temp);

                continue;
            }
            Double value = null;
            if (sb.length() != 0) {
                value = Double.parseDouble(sb.toString());
                sb.setLength(0);
            }

            if(i<arr.length-1
                &&!(arr[i+1] != ‘+‘ && arr[i+1] != ‘-‘ && arr[i+1] != ‘*‘ && arr[i+1] != ‘/‘)){
                throw new Exception(exMsg);
            }
            if(i==arr.length-1){
                throw new Exception(exMsg);
            }

            if (flag) {
                if (value == null) {
                    throw new Exception(exMsg);
                }
                Double a = valueStack.pop();
                String op = opStack.pop();
                switch (op) {
                case "*":
                    value = a * value;
                    break;
                case "/":
                    value = a / value;
                    break;
                // default:
                //     throw new Exception(exMsg);
                }
                valueStack.push(value);
            } else {
                if (value != null) {
                    valueStack.push(value);
                }
            }

            opStack.push(String.valueOf(temp));
            if (temp == ‘+‘ || temp == ‘-‘) {
                flag = false;
            } else {
                flag = true;
            }
        }
        // if (sb.length() == 0) {
        //     throw new Exception(exMsg);
        // }
        valueStack.push(Double.parseDouble(sb.toString()));

        double result = valueStack.pop();

        while (!valueStack.isEmpty() && !opStack.isEmpty()) {
            double value = valueStack.pop();
            String op = opStack.pop();
            // 第一个输入可能是带符号
            if (valueStack.isEmpty() && opStack.size() == 1) {
                String extra = opStack.pop();
                if (extra.equals("-")) {
                    value = 0 - value;
                }
            }
            switch (op) {
            case "-":
                result = value - result;
                break;
            case "+":
                result = value + result;
                break;
            // default:
            //     throw new Exception(exMsg);
            }

        }

        // if (!valueStack.isEmpty() || !opStack.isEmpty()) {
        //     throw new Exception(exMsg);
        // }

        return result;
    }
}

原文地址:https://www.cnblogs.com/lvjianwei/p/11167382.html

时间: 2024-08-28 20:28:39

算法 计算四则运算字符串结果的相关文章

一步一步写算法(之字符串查找 中篇)

原文:一步一步写算法(之字符串查找 中篇) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 昨天我们编写了简单的字符查找函数.虽然比较简单,但是也算能用.然而,经过我们仔细分析研究一下,这么一个简单的函数还是有改进的空间的.在什么地方改进呢?大家可以慢慢往下看. 下面的代码是优化前的代码,现在再贴一次,这样分析起来也方便些: char* strstr(const char* str, char* data) { int index; in

一步一步写算法(之字符串查找 下篇)

原文:一步一步写算法(之字符串查找 下篇) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 前面我们谈到了KMP算法,但是讲的还不是很详细.今天我们可以把这个问题讲的稍微详细一点.假设在字符串A中寻找字符串B,其中字符串B的长度为n,字符串A的长度远大于n,在此我们先忽略. 假设现在开始在字符串A中查找,并且假设双方在第p个字符的时候发现查找出错了,也就是下面的情况: /* * A: A1 A2 A3 A4 ... Ap ........

Fp关联规则算法计算置信度及MapReduce实现思路

说明:參考Mahout FP算法相关相关源代码. 算法project能够在FP关联规则计算置信度下载:(仅仅是单机版的实现,并没有MapReduce的代码) 使用FP关联规则算法计算置信度基于以下的思路: 1. 首先使用原始的FP树关联规则挖掘出全部的频繁项集及其支持度:这里须要注意,这里是输出全部的频繁项集,并没有把频繁项集合并,所以须要改动FP树的相关代码,在某些步骤把全部的频繁项集输出:(ps:參考Mahout的FP树单机版的实现,进行了改动,暂不确定是否已经输出了全部频繁项集) 为举例简

计算四则运算表达式(Java语言实现)

计算四则运算表达式主要是分两步运算  第一步是把 中缀表达式 转换成 后缀表达式.参考大一下期学的 <数据结构与算法分析--C语言描述>3.3.3 教材,完成下列代码: static String mid_to_suf(String str){ Stack<Character> s = new Stack<Character>(); String suf = new String(); HashMap<Character, Integer> map = ne

Canopy算法计算聚类的簇数

Kmeans算是是聚类中的经典算法.步骤例如以下: 选择K个点作为初始质心 repeat 将每一个点指派到近期的质心,形成K个簇 又一次计算每一个簇的质心 until 簇不发生变化或达到最大迭代次数 算法中的K须要人为的指定.确定K的做法有非常多,比方多次进行试探.计算误差.得出最好的K.这样须要比較长的时间.我们能够依据Canopy算法来粗略确定K值(能够觉得相等).看一下Canopy算法的过程: (1)设样本集合为S.确定两个阈值t1和t2,且t1>t2. (2)任取一个样本点p.作为一个C

计算指定字符串出现次数插件

计算指定字符串出现次数插件: 有时候需要计算移一段字符串中指定字符串的出现次数,可能应用不是那么频繁. 本章节分享一段代码实例能够实现类似的功能,当然也可以根据实际需要进行扩展. 代码如下: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="author" content="http://www.51texiao.cn/&q

编程算法 - 左旋转字符串 代码(C)

左旋转字符串 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部. 请定义一个函数实现字符串左旋转操作的功能. 编程珠玑, 首先翻转前部分, 再翻转后部分, 最后全部翻转. 代码: /* * main.cpp * * Created on: 2014.6.12 * Author: Spike */ /*eclipse cdt, gcc 4.8.1*/ #include <stdio

小算法-计算下一个排列

2 8 5 3 1 1.从后往前,找到第一个逆序的数 pivot 2.从后往前,找到第一个比pivot大的数 change 3.交换 pivot 和 change的值 4.把pivot这个位置后面的数 reverse,就是 8 5 2 1变成 1 2 5 8 最终为3 1 2 5 8 #include <iostream> #include <vector> #include <algorithm> using namespace std; /* * num.begin

一步一步写算法(之字符串查找 上篇)

原文:一步一步写算法(之字符串查找 上篇) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 字符串运算是我们开发软件的基本功,其中比较常用的功能有字符串长度的求解.字符串的比较.字符串的拷贝.字符串的upper等等.另外一个经常使用但是却被我们忽视的功能就是字符串的查找.word里面有字符串查找.notepad里面有字符串查找.winxp里面也有系统自带的字符串的查找,所以编写属于自己的字符串查找一方面可以提高自己的自信心,另外一方面在某