最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

利用遞歸下降法實(shí)現(xiàn)基礎(chǔ)功能的計(jì)算器

2023-06-16 21:05 作者:鬼島譽(yù)  | 我要投稿

利用遞歸下降法能夠?qū)崿F(xiàn)計(jì)算器的運(yùn)算優(yōu)先級(jí)。

看了很多自制的計(jì)算器,并沒有運(yùn)用遞歸下降法,它們 都只是兩個(gè)數(shù)運(yùn)算獲得一個(gè)結(jié)果,然后利用這一結(jié)果繼續(xù)與一個(gè)數(shù)相運(yùn)算。我認(rèn)為這樣不能夠展示完全的運(yùn)算式,所以寫了這一個(gè)遞歸下降法計(jì)算器。

實(shí)現(xiàn)結(jié)果樣例

一個(gè)計(jì)算樣例



以下是實(shí)現(xiàn)代碼:


import javax.swing.*;

import java.awt.*;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.beans.Expression;

import java.util.ArrayList;

import java.util.Stack;

public class Calculator extends JFrame implements ActionListener {

// 第一行的計(jì)算式

private ArrayList<String> tokens;private int pos = 0;//pos用于確定token位置

private JTextField expText = new JTextField();

// 第二行的計(jì)算結(jié)果,初始值設(shè)為0

private JTextField resultText = new JTextField("0");

// 構(gòu)造方法

public Calculator() {

// 調(diào)用父類的構(gòu)造函數(shù),

super("計(jì)算器");

// 各個(gè)按鈕上的文字


String[] keysValue = { "7", "8", "9", "÷", "4", "5", "6",

"×", "1", "2", "3", "-", "0","CE", "+","=","(",")" };

// 各個(gè)按鈕上的動(dòng)作命令標(biāo)識(shí)

String[] actionCmd = { "7", "8", "9", "/", "4", "5", "6",

"*", "1", "2", "3", "-", "0","CE", "+","=","(",")" };

JButton keys[] = new JButton[keysValue.length];

Font font=new Font("宋體",Font.PLAIN,18);

expText.setBounds(10, 10, 240, 40);

expText.setFont(font);

expText.setBackground(Color.white);

expText.setEditable(false);// 計(jì)算式不能修改

// 設(shè)置計(jì)算結(jié)果文本框大小

resultText.setBounds(10, 50, 240, 40);

resultText.setFont(font);

resultText.setBackground(Color.white);

resultText.setHorizontalAlignment(SwingConstants.RIGHT);

resultText.setEditable(false);// 計(jì)算結(jié)果不能修改

// 設(shè)置窗口布局

this.setLayout(null);

this.add(expText);? // 將計(jì)算式文本框添加到窗口中

this.add(resultText);// 將計(jì)算結(jié)果文本框添加到窗口中

// 放置按鈕

int x = 10, y = 100;

for (int i = 0; i < keysValue.length; i++) {

keys[i] = new JButton();

keys[i].setText(keysValue[i]);

keys[i].setActionCommand(actionCmd[i]);

keys[i].setBounds(x, y, 60, 45);

keys[i].setFont(font);

if (x <= 130) {

x += 60;

} else {

x = 10;

y += 50;

}

this.add(keys[i]);

}

// 每個(gè)按鈕都添加監(jiān)聽

for (int i = 0; i < keysValue.length; i++) {

keys[i].addActionListener(this);

}

// 窗口大小不能調(diào)整

this.setResizable(false);

// 設(shè)置窗口大小

this.setSize(270, 400);

this.setLocationRelativeTo(null);

this.setDefaultCloseOperation(EXIT_ON_CLOSE);

this.setVisible(true);

}


// 事件處理 //遞歸下降法//

public void actionPerformed(ActionEvent e) {


? ? ? ?if(e.getActionCommand().equals("0")

? ? ||e.getActionCommand().equals("1")

? ? ||e.getActionCommand().equals("2")

? ? ||e.getActionCommand().equals("3")

? ? ||e.getActionCommand().equals("4")

? ? ||e.getActionCommand().equals("5")

? ? ||e.getActionCommand().equals("6")

? ? ||e.getActionCommand().equals("7")

? ? ||e.getActionCommand().equals("8")

? ? ||e.getActionCommand().equals("9")){

? ? ? ?expText.setText(expText.getText() + e.getActionCommand());

? ? ? ?

? ? ? ?}

? ? ? ?else if (e.getActionCommand().equals("+") || e.getActionCommand().equals("-")?

? ? ? ?|| e.getActionCommand().equals("*") || e.getActionCommand().equals("/")

? ? ? ?||e.getActionCommand().equals("(") ||e.getActionCommand().equals(")")) {

? ? ? ? ? ?// 如果點(diǎn)擊了運(yùn)算按鈕,將運(yùn)算符號(hào)添加到計(jì)算式文本框中

? ? ? ? ? ?expText.setText(expText.getText() + " " + e.getActionCommand() + " ");

? ? ? ?} else if (e.getActionCommand().equals("=")) {

? ? ? ? ? ?// 如果點(diǎn)擊了等號(hào)按鈕,計(jì)算計(jì)算式的結(jié)果并將其顯示在結(jié)果文本框中

? ? ? ? ? ?String exp = expText.getText();

? ? ? ? ? ?double result = eval(exp);

? ? ? ? ? ?resultText.setText(String.valueOf(result));

? ? ? ?} else if (e.getActionCommand().equals("CE")) {

? ? ? ? ? ?// 如果點(diǎn)擊了清除按鈕,清除文本框中的內(nèi)容

? ? ? ? ? ?expText.setText("");

? ? ? ? ? ?resultText.setText("0");

? ? ? ? ? ?pos = 0;

? ? ? ? ? ?tokens = new ArrayList<String>();

? ? ? ?}

? ? ? ?}


? ? public double eval(String exp) {

? ? /*eval() 方法接受一個(gè)字符串參數(shù),表示要計(jì)算的表達(dá)式。

? ? * 它首先調(diào)用 tokenize() 方法將表達(dá)式字符串分割成若干個(gè) token,

? ? * 然后調(diào)用 expression() 方法計(jì)算表達(dá)式的值。

? ? * 最后,它檢查是否還有剩余的token,如果有,則拋出異常。*/

? ? ? ? // 將表達(dá)式字符串分割成若干個(gè)token

? ? ? ? tokens = tokenize(exp);

? ? ? ? // 調(diào)用遞歸函數(shù)計(jì)算表達(dá)式的值,也就是把輸入在exp文本框里的字符串加入順序表tokens

? ? ? ? double result = expression();//利用expression()方法算出結(jié)果

? ? ? ? // 檢查是否還有剩余的 token

? ? ? ? if (pos < tokens.size()) {

? ? ? ? ? ? throw new RuntimeException("出現(xiàn)錯(cuò)誤");

? ? ? ? }

? ? ? ? return result;

}

? ??

? ??

? ??

? ??

? ??

private double expression() {

/*expression() 方法計(jì)算一個(gè)表達(dá)式的值。

* 它首先調(diào)用 term() 方法計(jì)算第一個(gè)項(xiàng)的值,然后檢查是否還有加法或減法運(yùn)算符。

* 如果有,則繼續(xù)調(diào)用 term() 方法計(jì)算下一個(gè)項(xiàng)的值,并根據(jù)運(yùn)算符執(zhí)行相應(yīng)的操作。*/

? ? ? ? double result = term();

? ? ? ? while (pos < tokens.size()) {

? ? ? ? ? ? String fh = tokens.get(pos);//讀取tokens所在的pos位,如果第pos位是運(yùn)算符號(hào)+,-

? ? ? ? ? ? if (fh.equals("+") || fh.equals("-")) {//那么就先調(diào)用term()計(jì)算*/值便于實(shí)現(xiàn)運(yùn)算符優(yōu)先級(jí)

? ? ? ? ? ? ? ? pos++;

? ? ? ? ? ? ? ? double val = term();

? ? ? ? ? ? ? ? if (fh.equals("+")) {

? ? ? ? ? ? ? ? ? ? result =result + val;

? ? ? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? ? ? result =result - val;

? ? ? ? ? ? ? ? }

? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? break;

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? return result;

? ? }






private double term() {

/*term() 方法計(jì)算一個(gè)項(xiàng)的值。它首先調(diào)用 factor() 方法計(jì)算第一個(gè)因子的值,

? * 然后檢查是否還有乘法或除法運(yùn)算符。如果有,則繼續(xù)調(diào)用 factor() 方法計(jì)算下一個(gè)因子的值,

? * 并根據(jù)運(yùn)算符執(zhí)行相應(yīng)的操作。*/

? ? ? ? double result = factor();

? ? ? ? while (pos < tokens.size()) {

? ? ? ? ? ? String op = tokens.get(pos);

? ? ? ? ? ? if (op.equals("*") || op.equals("/")) {//然后檢查是否還有乘法或除法運(yùn)算符。

? ? ? ? ? ? ? ? pos++;

? ? ? ? ? ? ? ? double val = factor();

? ? ? ? ? ? ? ? if (op.equals("*")) {

? ? ? ? ? ? ? ? ? ? result =result * val;

? ? ? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? ? ? result =result / val;

? ? ? ? ? ? ? ? }

? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? break;

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? return result;

? ? }

?

?

?

?

private double factor()? /*factor() 方法計(jì)算一個(gè)因子的值。它首先檢查當(dāng)前 token 是否為左括號(hào)

? * 一元加號(hào)或一元減號(hào)。

? * 如果是左括號(hào),則遞歸調(diào)用 expression() 方法計(jì)算括號(hào)內(nèi)的表達(dá)式的值;

? * 如果是一元加號(hào)或一元減號(hào),則遞歸調(diào)用 factor() 方法計(jì)算下一個(gè)因子的值,

? * 并根據(jù)運(yùn)算符返回相應(yīng)的值;否則,將當(dāng)前 token 解析為一個(gè)數(shù)字并返回。*/{

? ? ? ? String token = tokens.get(pos++);

? ? ? ? if (token.equals("(")) {? ? ? ?//實(shí)現(xiàn)括號(hào)的優(yōu)先級(jí)

? ? ? ? ? ? double result = expression();

? ? ? ? ? ? if (!tokens.get(pos++).equals(")")) {

? ? ? ? ? ? ? ? throw new RuntimeException("Error: invalid expression");

? ? ? ? ? ? }

? ? ? ? ? ? return result;

? ? ? ? } else if (token.equals("+") || token.equals("-")) {

? ? ? ? ? ? double val = factor();//如果是一元加號(hào)或一元減號(hào),則遞歸調(diào)用 factor() 方法計(jì)算下一個(gè)因子的值,

? ? ? ? ? ? if (token.equals("+")) {

? ? ? ? ? ? ? ? return +val;

? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? return -val;

? ? ? ? ? ? }

? ? ? ? } else {

? ? ? ? ? ? return Double.parseDouble(token); //返回結(jié)果

? ? ? ? }

? ? }

?

?

?

?

? private ArrayList<String> tokenize(String exp)?

? /*tokenize() 方法將表達(dá)式字符串分割成若干個(gè) token。

它遍歷表達(dá)式字符串中的每個(gè)字符,如果遇到空格則忽略;如果遇到數(shù)字,

則繼續(xù)向后掃描直到遇到非數(shù)字字符,并將這些數(shù)字字符組成的字符串添加到 token 列表中;

否則,將當(dāng)前字符作為一個(gè) token 添加到 token 列表中。*/{

?

ArrayList<String> tokens = new ArrayList<>();

? ? ? ? int i = 0;

? ? ? ? while (i < exp.length()) {

? ? ? ? ? ? char ch = exp.charAt(i);

? ? ? ? ? ? if (ch == ' ') {

? ? ? ? ? ? ? ? i++;? //若是判斷到空格,則判斷下一位是否為數(shù)字或者運(yùn)算符

? ? ? ? ? ? } else if (Character.isDigit(ch)) {

? ? ? ? ? ? ? ? int j = i + 1;//一遇到運(yùn)算數(shù)字 例如5678+ 7 則判斷5是否為數(shù)字,如果是的話

? ? ? ? ? ? ? ? while (j < exp.length() && Character.isDigit(exp.charAt(j)))

? ? ? ? ? ? ? ? j++;? ? ? ? ? //則利用循環(huán)判斷5的后一位是否為數(shù)字,如上如果判斷了6是數(shù)字則判斷7

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //直到判斷到了運(yùn)算符,停止循環(huán)

? ? ? ? ? ? ? ? tokens.add(exp.substring(i, j));//直接將檢查出來數(shù)的加入順序表tokens

? ? ? ? ? ? ? ? i = j;//交換i,j達(dá)成檢查后一位的目的

? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? tokens.add(String.valueOf(ch)); //如果ch不為數(shù)字而是運(yùn)算符,則把運(yùn)算符加入順序表

? ? ? ? ? ? ? ? i++;? ? ? ? ? ? ?//若是輸入5678 + 7 則順序表應(yīng)該是["5678","+","7"]

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? return tokens;

? ? }


? ? ? ?



// 主函數(shù)

public static void main(String[] args) {

new Calculator();

}

}



此次展示到此為止

謝謝大家

利用遞歸下降法實(shí)現(xiàn)基礎(chǔ)功能的計(jì)算器的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
醴陵市| 邵阳县| 武乡县| 荆州市| 墨脱县| 淮滨县| 巴马| 新和县| 金平| 汤原县| 溧水县| 盖州市| 汶上县| 颍上县| 鄂州市| 商南县| 乌鲁木齐县| 丹阳市| 剑川县| 崇阳县| 黄冈市| 凉山| 陈巴尔虎旗| 保德县| 古田县| 桃江县| 元氏县| 镇康县| 永修县| 山东省| 阿拉善盟| 改则县| 太康县| 平遥县| 安吉县| 陵川县| 沽源县| 邵阳市| 桓台县| 南乐县| 临西县|