数据结构Demo——简单计算器

这篇具有很好参考价值的文章主要介绍了数据结构Demo——简单计算器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、项目介绍

本项目实现了一个通过网页访问的简单计算器,它可以对带括号的加减乘除表达式进行计算并将计算结果返回给用户,并且可以对用户输入的表达式进行合法性判断,以下是项目的界面展示:
数据结构Demo——简单计算器,数据结构
使用者可以通过点击网页上的按钮来输入一个算数表达式,之后点击等于号便可以将结果展示在界面上,具体效果如下:
数据结构Demo——简单计算器,数据结构

二、技术使用

在这个计算器中主要使用了前端html,css,JavaScript,后端spring boot以及数据结构中栈的使用方式与相关的算法。

  • 在前端中使用了html来对界面进行了整体的布局,然后使用了css来对界面效果做了美化,最后使用JavaScript来实现每个按钮的点击事件,并且通过Ajax将请求参数发给后台服务器,然后将后台处理的结果接收并处理,最后展示给用户。
  • 在后端中主要使用了spring boot框架来搭建一个简单的服务器,并对前端发来的请求进行处理,最后将处理的结果返回给前端。
  • 在处理表达式的时候主要使用了数据结构中有关栈的一些知识,通过对栈的使用来对表达式进行计算。

三、具体代码实现

1.前端部分

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>计算器</title>
    <link rel="stylesheet" href="./css/style.css">
</head>
<body>
    <div class="container">
        <div class="calculator dark">
            <div class="display-screen">
                <div id="display"></div>
            </div>
            <div class="buttons">
                <table>
                    <tr>
                        <td><button class="btn-operator" id="clear">C</button></td>
                        <td><button class="btn-operator" id="/">&divide;</button></td>
                        <td><button class="btn-operator" id="*">&times;</button></td>
                        <td><button class="btn-operator" id="backspace"><</button></td>
                    </tr>
                    <tr>
                        <td><button class="btn-number" id="7">7</button></td>
                        <td><button class="btn-number" id="8">8</button></td>
                        <td><button class="btn-number" id="9">9</button></td>
                        <td><button class="btn-operator" id="-">-</button></td>
                    </tr>
                    <tr>
                        <td><button class="btn-number" id="4">4</button></td>
                        <td><button class="btn-number" id="5">5</button></td>
                        <td><button class="btn-number" id="6">6</button></td>
                        <td><button class="btn-operator" id="+">+</button></td>
                    </tr>
                    <tr>
                        <td><button class="btn-number" id="1">1</button></td>
                        <td><button class="btn-number" id="2">2</button></td>
                        <td><button class="btn-number" id="3">3</button></td>
                        <td rowspan="2"><button class="btn-equal" id="equal" onclick="submit()">=</button></td>
                    </tr>
                    <tr>
                        <td><button class="btn-operator" id="(">(</button></td>
                        <td><button class="btn-number" id="0">0</button></td>
                        <td><button class="btn-operator" id=")">)</button></td>
                    </tr>
                </table>
            </div>
        </div>
    </div>
    <script src="./js/script.js"></script>
</body>
</html>

以上为html部分的代码,主要是对使用者的界面进行了整体布局,确定了各个按钮的位置与功能。

*{
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    outline: 0;
    transition: all 0.5s ease;
}
body{
    font-family: sans-serif;
}
a{
    text-decoration: none;
    color: #fff;
}
body{
    background-image: linear-gradient(to bottom right, rgb(10, 88, 232), rgb(41, 231, 225));
}
.container{
    height: 100vh;
    width: 100vw;
    display: grid;
    place-items: center;
}
.calculator{
    position: relative;
    height: auto;
    width: auto;
    padding: 20px;
    border-radius: 10px;
    box-shadow: 0 0 30px #000;
}
#display{
    margin: 0 10px;
    height: 150px;
    width: auto;
    max-width: 270px;
    display: flex;
    align-items: flex-end;
    justify-content: flex-end;
    font-size: 30px;
    overflow-x: scroll;
}
#display::-webkit-scrollbar{
    display: block;
    height: 3px;
}
button{
    height: 60px;
    width: 60px;
    border: 0;
    border-radius: 30px;
    margin: 5px;
    font-size: 20px;
    cursor: pointer;
    transition: all 200ms ease;
}
button:hover{
    transform: scale(1.1);
}
button#equal{
    height: 130px;
}

.calculator{
    background-color: #fff;
}
.calculator #display{
    color: #0a1e23;
}
.calculator button#clear{
    background-color: #ffd5d8;
    color: #fc4552;
}
.calculator button.btn-number{
    background-color: #c3eaff;
    color: #000;
}
.calculator button.btn-operator{
    background-color: #7ed0b0;
    color: #f39408;
}
.calculator button.btn-equal{
    background-color: #adf9e7;
    color: #000;
}

以上是css部分的代码,主要对界面的颜色样式进行了美化。

const display = document.querySelector('#display');
const buttons = document.querySelectorAll('button');

const submit = function () {
    let subdata = null;
    // 定义表单对象
    const data = {}
    // 获取input框内内容
    const displayData = display.innerText
    data.display = displayData
    console.log(data);
    const req = fetch('http://localhost:8081/cal/c', {
        body: JSON.stringify(data),
        method: "POST",
        headers: {
            'Content-Type': 'application/json'
        }
    })
    req.then(res => res.text())
        .then(res => {
            subdata = JSON.parse(res);
            if (!subdata.status)
                display.innerText = '输入格式错误'
            else {
                console.log(subdata);
                display.innerText = subdata.result
            }
        })
        .catch(err => {
            console.log(err)
        })
}

buttons.forEach((item) => {
    item.onclick = () => {
        if (item.id == 'clear') {
            display.innerText = '';
        } else if (item.id == 'backspace') {
            let string = display.innerText.toString();
            display.innerText = string.substr(0, string.length - 1);
        } else if (display.innerText != '' && item.id == 'equal') {
            submit()
        } else if (display.innerText == '' && item.id == 'equal') {
            display.innerText = 'Empty!';
            setTimeout(() => (display.innerText = ''), 2000);
        } else {
            display.innerText += item.id;
        }
    }
})
const calculator = document.querySelector('.calculator');

以上是JavaScript部分的代码,主要负责按钮的点击事件、给后端发送请求以及对后端返回结果的处理。

2.后端部分

@RestController
@RequestMapping("/cal")
public class Controller {
    @Autowired
    private ServiceImpl service;

    @PostMapping("/c")
    public Res calcula(@RequestBody data data) {
        return service.calculate(data.getDisplay());
    }
}

@Service
public class ServiceImpl {
    public Res calculate(String text) {
        return new Res(Calculator.isValidExpression(text) ? 
                Calculator.calculateExpression(text) : null,
                Calculator.isValidExpression(text) ? 1 : 0);
    }
}

以上是后端给出的请求接口以及业务逻辑层的方法。

@Data
@AllArgsConstructor
public class Res {
    public Integer result;
    public int status;
}

public class data {
    private String display;

    public data() {
    }

    public String getDisplay() {
        return display;
    }

    public void setDisplay(String display) {
        this.display = display;
    }

    public data(String display) {
        this.display = display;
    }

    @Override
    public String toString() {
        return "data{" +
                "display='" + display + '\'' +
                '}';
    }
}

以上是给前端返回结果的包装类以及接收前端数据的实体类。

public class Calculator {
    public static int priority(int oper) {
        if (oper == '*' || oper == '/') {
            return 1;
        } else if (oper == '+' || oper == '-') {
            return 0;
        } else {
            return -1;
        }
    }

    public static boolean isOper(char val) {
        return val == '+' || val == '-' || val == '*' || val == '/';
    }

    public static int cal(int num1, int num2, int oper) {
        int res = 0;
        switch (oper) {
            case '+':
                res = num1 + num2;
                break;
            case '-':
                res = num2 - num1;
                break;
            case '*':
                res = num1 * num2;
                break;
            case '/':
                res = num2 / num1;
                break;
        }
        return res;
    }

    public static int calculateExpression(String expression) {
        Stack<Integer> numStack = new Stack<>();
        Stack<Character> operStack = new Stack<>();
        int index = 0;
        int num1 = 0;
        int num2 = 0;
        int oper = 0;
        int res = 0;
        char ch = ' ';
        String keepNum = "";
        while (true) {
            ch = expression.substring(index, index + 1).charAt(0);
            if (isOper(ch)) {
                if (!operStack.isEmpty()) {
                    if (priority(ch) <= priority(operStack.peek())) {
                        num1 = numStack.pop();
                        num2 = numStack.pop();
                        oper = operStack.pop();
                        res = cal(num1, num2, oper);
                        numStack.push(res);
                        operStack.push(ch);
                    } else {
                        operStack.push(ch);
                    }
                } else {
                    operStack.push(ch);
                }
            } else if (ch == '(') {
                int endIndex = getEndBracketIndex(expression, index);
                String subExpression = expression.substring(index + 1, endIndex);
                int subRes = calculateExpression(subExpression);
                numStack.push(subRes);
                index = endIndex;
            } else {
                keepNum += ch;
                if (index == expression.length() - 1) {
                    numStack.push(Integer.parseInt(keepNum));
                    keepNum = "";
                } else {
                    if (isOper(expression.substring(index + 1, index + 2).charAt(0))) {
                        numStack.push(Integer.parseInt(keepNum));
                        keepNum = "";
                    }
                }
            }
            index++;
            if (index >= expression.length()) {
                break;
            }
        }
        while (!operStack.isEmpty()) {
            num1 = numStack.pop();
            num2 = numStack.pop();
            oper = operStack.pop();
            res = cal(num1, num2, oper);
            numStack.push(res);
        }
        return numStack.pop();
    }

    private static int getEndBracketIndex(String expression, int startIndex) {
        Stack<Integer> stack = new Stack<>();
        for (int i = startIndex; i < expression.length(); i++) {
            char ch = expression.charAt(i);
            if (ch == '(') {
                stack.push(i);
            } else if (ch == ')') {
                stack.pop();
                if (stack.isEmpty()) {
                    return i;
                }
            }
        }
        return 0;
    }

    public static boolean isValidExpression(String expr) {
        // 去除空格
        expr = expr.replaceAll("\\s", "");
        // 使用栈保存左括号
        Stack<Character> stack = new Stack<>();
        for (int i = 0; i < expr.length(); i++) {
            char c = expr.charAt(i);
            if (isLeftParenthesis(c)) {
                stack.push(c);
            } else if (isRightParenthesis(c)) {
                if (stack.isEmpty()) {
                    return false;
                } else {
                    stack.pop();
                }
            } else if (isOperator(c)) {
                if (i == 0 || i == expr.length() - 1 || isOperator(expr.charAt(i - 1)) || isOperator(expr.charAt(i + 1))) {
                    return false;
                }
                if (c == '/' && (i == expr.length() - 2 || expr.charAt(i + 2) == '0')) {
                    return false;
                }
            } else if (!Character.isDigit(c)) {
                return false;
            }
        }
        return stack.isEmpty();
    }

    public static boolean isLeftParenthesis(char c) {
        return c == '(';
    }

    public static boolean isRightParenthesis(char c) {
        return c == ')';
    }

    public static boolean isOperator(char c) {
        return c == '+' || c == '-' || c == '*' || c == '/';
    }
}

以上是对表达式进行处理并计算结果的一个简单的计算器类,该类提供了以下几个方法:文章来源地址https://www.toymoban.com/news/detail-734121.html

  • priority(int oper):根据运算符的优先级,返回一个整数值,其中乘法和除法的优先级为1,加法和减法的优先级为0,其他情况返回-1。
  • isOper(char val):判断给定字符是否为运算符(+、-、*、/)。
  • cal(int num1, int num2, int oper):根据给定的两个数字和一个运算符,进行相应的计算并返回结果。运算符对应的计算包括加法、减法、乘法和除法。
  • calculateExpression(String expression):通过指定的数学表达式进行计算,并返回计算结果。该方法使用两个栈来实现计算过程。一个栈用于存储数字,另一个栈用于存储运算符。遍历表达式的字符,根据字符的类型进行相应的操作。如果是运算符,则根据运算符的优先级决定是否进行计算;如果是左括号,则寻找对应的右括号,并将括号内的子表达式进行递归计算;如果是数字,则将数字压入数字栈中。最后,将剩余的运算符依次进行计算,直到栈为空,返回最终的计算结果。
  • getEndBracketIndex(String expression, int startIndex):辅助方法,用于获取给定表达式中与指定左括号对应的右括号的位置。
  • isValidExpression(String expr):判断给定的表达式是否为有效的数学表达式。方法首先去除字符串中的空格,然后使用栈来检查表达式中的括号是否匹配以及运算符的使用是否正确。具体规则如下:左括号入栈,遇到右括号出栈,如果栈为空则表示括号不匹配;如果遇到运算符,则判断其前后是否有运算符,以及除法运算符是否除以0,如果不符合规则则表达式无效;如果遇到非数字和非运算符的字符,则表达式无效。最后,如果栈为空,则表示括号匹配,返回true,否则返回false。

到了这里,关于数据结构Demo——简单计算器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • AndroidStudio案例——简单计算器

                设计一款带有可视化界面的简单计算器,供用户输入数据并查看结果。用户通过点击相应按钮(加减乘除运算符、等号、数字)输入正确的表达式,计算器进行相应的加减乘除运算,且可以进行小数和整数的运算;长按清除按钮3秒,可以清除已录入的内容。

    2024年02月02日
    浏览(34)
  • Qt编写简单计算器

    一、使用LCD Number、Push Button和GridLayout编辑计算器页面。  二、代码 widget.h main.cpp widget.cpp

    2024年02月12日
    浏览(41)
  • Qt项目---简单的计算器

    在这篇技术博客中,我们将介绍如何使用Qt框架实现一个简单的计算器应用。我们将使用C++编程语言和Qt的图形用户界面库来开发这个应用,并展示如何实现基本的算术操作。   首先,我们需要在Qt Creator中创建一个新的Qt Widgets应用程序项目。这个项目将提供我们所需的基本框

    2024年02月14日
    浏览(44)
  • Android 实战项目:简单计算器

    虽然只学了一些Android的简单控件,但是只要活学善用这些布局和控件,也能够做出实用的App。 接下来让我们尝试设计并实现一个简单计算器。 Windows计算器,它主要由上半部分的计算结果与下半部分的计算按钮两块区域组成,据此可创建一个界面相似的计算器App,同样由计算

    2024年02月03日
    浏览(52)
  • tkinter制作一个简单计算器

            我们知道tkinter是python常用的UI框架,那么它是如何使用的呢?我们用一个简单的例子来显示它的作用,制作一个简单的计算器,如下图所示。 上图是一个计算器,我们可以看出它一共有20个键,每个按键都表示一个功能,在最上方是一个文本框用来显示数值。接下

    2024年02月11日
    浏览(60)
  • 【Python】简单计算器实现(四)

    解决思路: 最后,我们来看看最简单的运算函数和判断运算符函数。 定义函数: def calculate(n1, n2, operator) param n1: float param n2: float param operator: + - * / return: float 定义函数: def is_operator(e) param e: str return: bool 最后的调用 这里定义了两个变量 result 和 _ 来接收 final_calc 返回的两个

    2024年02月16日
    浏览(41)
  • 微信小程序——简单计算器

    实现代码: computer.json 欢迎大家阅读,本人见识有限,写的博客难免有错误或者疏忽的地方,还望各位指点,在此表示感激不尽。文章持续更新中…

    2024年02月06日
    浏览(51)
  • 模拟实现一个简单的计算器

    2024年02月11日
    浏览(53)
  • 用代码实现一个简单计算器

    作者主页: paper jie的博客_CSDN博客-C语言,算法详解领域博主 本文作者: 大家好,我是paper jie,感谢你阅读本文,欢迎一建三连哦。 本文录入于 《C语言》专栏,本专栏是针对于大学生,编程小白精心打造的。笔者用重金(时间和精力)打造,将C语言基础知识一网打尽,希望可

    2024年02月08日
    浏览(43)
  • 【c++】简单的日期计算器

    🔥个人主页 : Quitecoder 🔥 专栏 : c++笔记仓 朋友们大家好啊,在我们学习了默认成员函数后,我们本节内容来完成知识的实践,来实现一个简易的日期计算器 头文件声明所有函数: 第一个函数,获取 某月天数 为了按照月的月份直接访问数组,我们设置大小为13,由于要进

    2024年04月09日
    浏览(74)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包