欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java編寫簡單計算器的完整實現(xiàn)過程

 更新時間:2020年12月07日 12:14:06   作者:雪,,,  
這篇文章主要給大家介紹了關于Java編寫簡單計算器的完整實現(xiàn)過程,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

前言

本文用Javaswing來實現(xiàn)一個簡單計算器,主要內容為圖形用戶界面GUI的實現(xiàn)以及運算表達式核心算法的設計編寫。

程序運行環(huán)境為Windows10 ,編譯環(huán)境為MyEclipse 。

一、具體功能:

1、:輸入,輸出

輸入:允許輸入帶有括號的完整計算式(例 8*(4-95)+5÷2*e-pi)
輸出:輸出Double類型的結果
輸出:整個運算表達式并保存于歷史記錄中

2、:功能

 基本的加,減,乘,除,四則運算
 平方運算
 開方運算
 求余運算

最終界面如下圖:

除了常規(guī)的數字按鈕和運算符,還有兩個常數e,pi(π),清空鍵AC,括號運算符(),平方(x^x)和開方(sqrt)運算符,輸入顯示框以及歷史記錄文本框,文本框的垂直滾動條和水平滾動條。

二、主要思想:

1:中綴表達式轉為后綴表達式

準備:

①后綴表達式隊列:postQueue,用于存儲逆波蘭表達式(其實不用隊列排序直接輸出也行)
②操作符棧:opStack,對用戶輸入的操作符進行處理,用于存儲運算符

算法思想:

從左向右依次讀取算術表達式的元素X,分以下情況進行不同的處理:
(1)如果X是操作數,直接入隊
(2)如果X是運算符,再分以下情況:
a)如果棧為空,直接入棧。
b)如果X==”(“,直接入棧。
c)如果X==”)“,則將棧里的元素逐個出棧,并入隊到后綴表達式隊列中,直到第一個配對的”(”出棧。(注:“(”和“)”都不 入隊)
d)如果是其他操作符(+ - * /),則和棧頂元素進行比較優(yōu)先級。 如果棧頂元素的優(yōu)先級大于等于X,則出棧并把棧中彈出的元素入隊,直到棧頂元素的優(yōu)先級小于X或者棧為空。彈出完這些元素后,才將遇到的操作符壓入到棧中。
(3)最后將棧中剩余的操作符全部入隊。

示意圖:

2、計算后綴表達式

準備:

需要用到一個結果棧Res_Stack :用于存放計算的中間過程的值和最終結果

算法思想:

1、從左開始向右遍歷后綴表達式的元素。
2、如果取到的元素是操作數,直接入棧Res_Stack,如果是運算符,從棧中彈出2個數進行運算,然后把運算結果入棧
3、當遍歷完后綴表達式時,計算結果就保存在棧里了。

示意圖:

三、結果測試

分析:

1、可實現(xiàn)基本四則運算及平方、開方、求余運算。
2、運算表達式可顯示于輸入界面并保存于歷史記錄欄
3、輸入界面和歷史記錄欄皆可實現(xiàn)不斷字自動換行功能以及滾動條功能
4、不足之處:進行平方和開方運算時其保存在歷史記錄中的表達式會出現(xiàn)兩個等號及兩個結果。

四、完整源代碼(每行代碼已附有詳細注釋)

package software;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

//Calculator類,繼承JFrame框架,實現(xiàn)事件監(jiān)聽器接口
public class Calculator extends JFrame implements ActionListener {
  private String[] KEYS = { "7", "8", "9", "AC", "4", "5", "6", "-", "1", "2", "3", "+", "0", "e", "pi", "/", "sqrt",
	  "%", "x*x", "*", "(", ")", ".", "=" };
  private JButton keys[] = new JButton[KEYS.length];
  private JTextArea resultText = new JTextArea("0.0");// 文本域組件TextArea可容納多行文本;文本框內容初始值設為0.0
  private JTextArea History = new JTextArea();// 歷史記錄文本框初始值設為空
  private JPanel jp1=new JPanel();
  private JPanel jp2=new JPanel();
  private JScrollPane gdt1=new JScrollPane(resultText);//給輸入顯示屏文本域新建一個垂直滾動滑條
  private JScrollPane gdt2=new JScrollPane(History);//給歷史記錄文本域新建一個垂直滾動滑條
  // private JScrollPane gdt3=new JScrollPane(History);//給歷史記錄文本域新建一個水平滾動滑條
  private JLabel label = new JLabel("歷史記錄");
  private String b = "";

// 構造方法
  public Calculator() {
	super("Caculator");//“超”關鍵字,表示調用父類的構造函數,
	resultText.setBounds(20, 18, 255, 115);// 設置文本框大小
	resultText.setAlignmentX(RIGHT_ALIGNMENT);// 文本框內容右對齊
	resultText.setEditable(false);// 文本框不允許修改結果
	History.setBounds(290, 40, 250,370);// 設置文本框大小
	History.setAlignmentX(LEFT_ALIGNMENT);// 文本框內容右對齊
	History.setEditable(false);// 文本框不允許修改結果
	label.setBounds(300, 15, 100, 20);//設置標簽位置及大小
	jp2.setBounds(290,40,250,370);//設置面板窗口位置及大小
	jp2.setLayout(new GridLayout());
	jp1.setBounds(20,18,255,115);//設置面板窗口位置及大小
	jp1.setLayout(new GridLayout());
	resultText.setLineWrap(true);// 激活自動換行功能
	resultText.setWrapStyleWord(true);// 激活斷行不斷字功能
	resultText.setSelectedTextColor(Color.RED);
	History.setLineWrap(true);//自動換行
	History.setWrapStyleWord(true);
	History.setSelectedTextColor(Color.blue);
	gdt1.setViewportView(resultText);//使?jié)L動條顯示出來
	gdt2.setViewportView(History);
	gdt1.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);//設置讓垂直滾動條一直顯示
	gdt2.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);//設置讓垂直滾動條一直顯示
	gdt2.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);//設置讓水平滾動條一直顯示
	jp1.add(gdt1);//將滾動條添加入面板窗口中
	jp2.add(gdt2);
	this.add(jp1);//將面板添加到總窗體中
	this.add(jp2);//將面板添加到總窗體中
	this.setLayout(null);
	this.add(label);// 新建“歷史記錄”標簽
	//this.add(resultText);// 新建文本框,該語句會添加進去一個新的JTextArea導致帶有滾動條的文本無法顯示或者發(fā)生覆蓋
	//this.add(History);// 新建歷史記錄文本框,該語句會添加進去一個新的JTextArea導致帶有滾動條的文本無法顯示
	
	// 放置按鈕
	int x = 20, y = 150;
	for (int i = 0; i < KEYS.length; i++)
	{
	  keys[i] = new JButton();
	  keys[i].setText(KEYS[i]);
	  keys[i].setBounds(x, y, 60, 40);
	  if (x < 215) {
		x += 65;
	  } else {
		x = 20;
		y += 45;
	  }
	  this.add(keys[i]);
	}
	for (int i = 0; i < KEYS.length; i++)// 每個按鈕都注冊事件監(jiān)聽器
	{
	  keys[i].addActionListener(this);
	}
	this.setResizable(false);
	this.setBounds(500, 200, 567, 480);
	this.setDefaultCloseOperation(EXIT_ON_CLOSE);
	this.setVisible(true);
  }

// 事件處理
  public void actionPerformed(ActionEvent e)
  {
	//History.setText(b);//使輸入的表達式顯示在歷史記錄文本框中
	String label=e.getActionCommand();//獲得事件源的標簽
	if(label=="=")//
	{
	  resultText.setText(this.b);
	  History.setText(History.getText()+resultText.getText());
	  if(label=="=")//調用計算方法,得出最終結果
	  {
		String s[]=houzhui(this.b);
		String result=Result(s);
		this.b=result+"";
		//更新文本框,當前結果在字符串b中,并未刪除,下一次輸入接著此結果以實現(xiàn)連續(xù)運算
		resultText.setText(this.b);
		History.setText(History.getText()+"="+resultText.getText()+"\n");
	  }
	}
	 else if(label=="AC")//清空按鈕,消除顯示屏文本框前面所有的輸入和結果
	  {
		this.b="";
		 resultText.setText("0");//更新文本域的顯示,顯示初始值;
	  }
	else if(label=="sqrt")
	{
	  String n=kfys(this.b);
	  resultText.setText("sqrt"+"("+this.b+")"+"="+n);//使運算表達式顯示在輸入界面
	  History.setText(History.getText()+"sqrt"+"("+this.b+")"+"=");//獲取輸入界面的運算表達式并使其顯示在歷史記錄文本框
	  this.b=n;
	}
	else if(label=="x*x")
	{
	  String m=pfys(this.b);
	  resultText.setText(this.b+"^2"+"="+m);//使運算表達式顯示在輸入界面
	  History.setText(History.getText()+this.b+"^2"+"=");//獲取輸入界面的運算表達式并使其顯示在歷史記錄文本框
	  this.b=m;
	}
	else if(label=="e"||label=="pi")
	{
	  if(label=="e")
	  {
		String m=String.valueOf(2.71828);//將e的值以字符串的形式傳給m
		 this.b=this.b+m;//保留顯示m之前輸入的運算符或數字字符繼續(xù)下一步運算
		 resultText.setText(this.b);
		// History.setText(History.getText()+this.b);
	  }
	  if(label=="pi")
	  {
		String m=String.valueOf(3.14159265);
		 this.b=this.b+m;
		 resultText.setText(this.b);
		// History.setText(History.getText()+this.b);
	  }
	}
	else
	{
	  this.b=this.b+label;
	  resultText.setText(this.b);
	 // History.setText(History.getText()+this.b);
	  
	  
	}
	//History.setText(History.getText()+this.b);//使輸入的表達式顯示在歷史記錄文本框中
  }
//將中綴表達式轉換為后綴表達式
  private String[] houzhui(String str) {
	String s = "";// 用于承接多位數的字符串
	char opStack[] = new char[100];// 靜態(tài)棧,對用戶輸入的操作符進行處理,用于存儲運算符
	String postQueue[] = new String[100];// 后綴表達式字符串數組,為了將多位數存儲為獨立的字符串
	int top = -1, j = 0;// 靜態(tài)指針top,控制變量j
	for (int i = 0; i < str.length(); i++)// 遍歷中綴表達式
	// indexof函數,返回字串首次出現(xiàn)的位置;charAt函數返回index位置處的字符;
	{
	  if ("0123456789.".indexOf(str.charAt(i)) >= 0) // 遇到數字字符的情況
	  {
		s = "";// 作為承接字符,每次開始時都要清空
		for (; i < str.length() && "0123456789.".indexOf(str.charAt(i)) >= 0; i++) {
		  s = s + str.charAt(i);
		}
		i--;
		postQueue[j] = s;// 數字字符直接加入后綴表達式
		j++;
	  } else if ("(".indexOf(str.charAt(i)) >= 0) {// 遇到左括號
		top++;
		opStack[top] = str.charAt(i);// 左括號入棧
	  } else if (")".indexOf(str.charAt(i)) >= 0) {// 遇到右括號
		for (;;)// 棧頂元素循環(huán)出棧,直到遇到左括號為止
		{
		  if (opStack[top] != '(') {// 棧頂元素不是左括號
			postQueue[j] = opStack[top] + "";// 棧頂元素出棧
			j++;
			top--;
		  } else { // 找到棧頂元素是左括號
			top--;// 刪除棧頂左括號
			break;// 循環(huán)結束
		  }
		}
	  }
	  if ("*%/".indexOf(str.charAt(i)) >= 0)// 遇到高優(yōu)先級運算符
	  {
		if (top == -1) {// 若棧為空則直接入棧
		  top++;
		  opStack[top] = str.charAt(i);
		} else {// 棧不為空,把棧中彈出的元素入隊,直到棧頂元素優(yōu)先級小于x或者棧為空
		  if ("*%/".indexOf(opStack[top]) >= 0) {
			// 棧頂元素也為高優(yōu)先級運算符
			postQueue[j] = opStack[top] + "";// 棧頂元素出棧進入后綴表達式
			j++;
			opStack[top] = str.charAt(i);// 當前運算符入棧
		  } else if ("(".indexOf(opStack[top]) >= 0) {// 棧頂元素為左括號,當前運算符入棧
			top++;
			opStack[top] = str.charAt(i);
		  } else if ("+-".indexOf(str.charAt(i)) >= 0) {// 遇到低優(yōu)先級運算符
			postQueue[j] = opStack[top] + "";// 棧頂元素出棧進入后最表達式
			j++;
			opStack[top] = str.charAt(i);// 當前元素入棧
		  }
		}
	  } else if ("+-".indexOf(str.charAt(i)) >= 0) {
		if (top == -1) {
		  top++;
		  opStack[top] = str.charAt(i);
		} else {
		  if ("*%/".indexOf(opStack[top]) >= 0) {
			// 棧頂元素也為高優(yōu)先級運算符
			postQueue[j] = opStack[top] + "";// 棧頂元素出棧進入后綴表達式
			j++;
			opStack[top] = str.charAt(i);// 當前運算符入棧
		  } else if ("(".indexOf(opStack[top]) >= 0) {// 棧頂元素為左括號,當前運算符入棧
			top++;
			opStack[top] = str.charAt(i);
		  } else if ("+-".indexOf(str.charAt(i)) >= 0) {// 遇到低優(yōu)先級運算符
			postQueue[j] = opStack[top] + "";// 棧頂元素出棧進入后最表達式
			j++;
			opStack[top] = str.charAt(i);// 當前元素入棧
		  }
		}
	  }
	}
	for (; top != -1;) {// 遍歷結束后將棧中剩余元素依次出棧進入后綴表達式
	  postQueue[j] = opStack[top] + "";
	  j++;
	  top--;
	}
	return postQueue;
  }

//開方運算方法
  public String kfys(String str) {
	String result = "";
	double a = Double.parseDouble(str), b = 0;
	b = Math.sqrt(a);
	result = String.valueOf(b);//將運算結果轉換為string類型并賦給string類型的變量result
	return result;
  }

//平方運算方法
  public String pfys(String str) {
	String result = "";
	double a = Double.parseDouble(str), b = 0;
	b = Math.pow(a, 2);
	result = String.valueOf(b);
	return result;
  }
  
// 計算后綴表達式,并返回最終結果
  public String Result(String str[]) {
	String Result[] = new String[100];// 順序存儲的棧,數據類型為字符串
	int Top = -1;// 靜態(tài)指針Top
	for (int i = 0; str[i] != null; i++) {
	  if ("+-*%/".indexOf(str[i]) < 0) {
		Top++;
		Result[Top] = str[i];
	  }
	  if ("+-*%/".indexOf(str[i]) >= 0)// 遇到運算符字符,將棧頂兩個元素出棧計算并將結果返回棧頂
	  {
		double x, y, n;
		x = Double.parseDouble(Result[Top]);// 順序出棧兩個數字字符串,并轉換為double類型
		Top--;
		y = Double.parseDouble(Result[Top]);
		Top--;
		if ("-".indexOf(str[i]) >= 0) {
		  n = y - x;
		  Top++;
		  Result[Top] = String.valueOf(n);// 將運算結果重新入棧
		}
		if ("+".indexOf(str[i]) >= 0) {
		  n = y + x;
		  Top++;
		  Result[Top] = String.valueOf(n);// 將運算結果重新入棧
		}
		if ("*".indexOf(str[i]) >= 0) {
		  n = y * x;
		  Top++;
		  Result[Top] = String.valueOf(n);// 將運算結果重新入棧

		}
		if ("/".indexOf(str[i]) >= 0)
		{
		  if (x == 0)// 被除數不允許為0
		  {
			String s = "error!";
			return s;
		  } else {
			n = y / x;
			Top++;
			Result[Top] = String.valueOf(n);// 將運算結果重新入棧
		  }
		}
		if ("%".indexOf(str[i]) >= 0) 
		{
		  if (x == 0)// 被除數不允許為0
		  {
			String s = "error!";
			return s;
		  } else {
			n = y % x;
			Top++;
			Result[Top] = String.valueOf(n);// 將運算結果重新入棧
		  }
		}
		
	  }
	}
	return Result[Top];// 返回最終結果
  }

  // 主函數
  public static void main(String[] args) {
	Calculator a = new Calculator();
  }
}

到此這篇關于Java編寫簡單計算器的文章就介紹到這了,更多相關Java編寫簡單計算器內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 深入Java冒泡排序與選擇排序的區(qū)別詳解

    深入Java冒泡排序與選擇排序的區(qū)別詳解

    本篇文章是對Java冒泡排序與選擇排序的區(qū)別進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • Mybatis-Plus 自動填充失效問題解決

    Mybatis-Plus 自動填充失效問題解決

    在使用MyBatis-Plus時,自動填充功能可能會失效,這通常與版本和配置有關,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-10-10
  • Java開發(fā)druid數據連接池maven方式簡易配置流程示例

    Java開發(fā)druid數據連接池maven方式簡易配置流程示例

    本篇文章主要為大家介紹了java開發(fā)中druid數據連接池maven方式的簡易配置流程示例,文中附含詳細的代碼示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2021-10-10
  • 解決Java中的強制類型轉換和二進制表示問題

    解決Java中的強制類型轉換和二進制表示問題

    這篇文章主要介紹了解決Java中的強制類型轉換和二進制表示問題,需要的朋友可以參考下
    2019-05-05
  • Java中的@Repeatable注解的作用詳解

    Java中的@Repeatable注解的作用詳解

    這篇文章主要介紹了Java中的@Repeatable注解的作用詳解,@Repeatable注解是用來標注一個注解在同一個地方可重復使用的一個注解,使被他注釋的注解可以在同一個地方重復使用,需要的朋友可以參考下
    2024-01-01
  • Java深入數據結構理解掌握抽象類與接口

    Java深入數據結構理解掌握抽象類與接口

    在類中沒有包含足夠的信息來描繪一個具體的對象,這樣的類稱為抽象類,接口是Java中最重要的概念之一,它可以被理解為一種特殊的類,不同的是接口的成員沒有執(zhí)行體,是由全局常量和公共的抽象方法所組成,本文給大家介紹Java抽象類和接口,感興趣的朋友一起看看吧
    2022-05-05
  • 解決SpringBoot集成Eureka導致返回結果由json變?yōu)閤ml的問題

    解決SpringBoot集成Eureka導致返回結果由json變?yōu)閤ml的問題

    這篇文章主要介紹了解決SpringBoot集成Eureka導致返回結果由json變?yōu)閤ml的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • springboot jpa分庫分表項目實現(xiàn)過程詳解

    springboot jpa分庫分表項目實現(xiàn)過程詳解

    這篇文章主要介紹了springboot jpa分庫分表項目實現(xiàn)過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-01-01
  • Java多線程模擬銀行系統(tǒng)存錢問題詳解

    Java多線程模擬銀行系統(tǒng)存錢問題詳解

    本文將利用Java多線程模擬一個簡單的銀行系統(tǒng),使用兩個不同的線程向同一個賬戶存錢。文中的示例代碼講解詳細,感興趣的可以了解一下
    2022-09-09
  • shiro無狀態(tài)web集成的示例代碼

    shiro無狀態(tài)web集成的示例代碼

    本篇文章主要介紹了shiro無狀態(tài)web集成的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09

最新評論