1. 程式人生 > >用java實現了一個小的計算器

用java實現了一個小的計算器

突然之間心血來潮,就是想試一試資料結構怎麼用.到現在才感覺的,資料結構是一種思想,一種思維方式,用怎樣的方式去解決怎樣的問題,這些是資料結構和演算法給我們的.

言歸正傳吧,說說這個小計算器(其實還有太多需要擴充套件和改進的地方).暫時只侷限在加減乘除,因為定義的是int型別的,所以也限制在整數運算吧.

主要思路是這樣的:計算器最主要的部分是獲取使用者輸入,然後根據演算法將獲取到的輸入儲存成為二叉樹.當然,肯定要用棧儲存的.

先看一下簡單的分析:

1+2-3:  儲存成二叉樹應該是這樣的:節點上的值為運算子,左右孩子為數值:

     +

    /   \

  +    3

/    \

1    2  

也就是說,存好後用後序方法來進行讀取,然後計算.

如果有*和/,則如下:

1+2*3-6/2:

                   -

               /     \

             +       /

            /  \    / \

           1   *  6  2

                / \

               2  3   

其實,從這些分析上,可以得出一個結論,暫且是對於這個計算器範圍內的結論(沒有括號之類的...)

(1)兩個棧,一個CTack,用來存放暫時的操作符,一個TTack,用來存放二叉樹.兩個棧結構,一個棧存放的是String型別,另一個存放二叉樹Node型別.

(2)一次對使用者輸入的字元進行遍歷,通過下面的原則判斷是否壓棧還是出棧組成二叉樹.

   方式:首先,在輸入字元是數字時,先建立一個TTack,左右孩子賦值為null,data值賦值為數字.

          輸入遍歷到操作符時:a: CTack為空;b:CTack當前操作符優先順序<讀入的操作符 ; 壓棧CTack

                                      aa:CTack當前操作符優先順序>=讀入操作符優先順序,新建Node,出棧TTack中的兩個Node分別

                                            作為新Node的左右孩子,操作符作為節點值,之後再次壓棧TTack.

(3)讀完後,如果CTack還不是null,則以此取出TTack中的兩個Node作為新Node的左右孩子,CTack出棧的操作符作為節點值.之後壓棧.

思路大體就是這樣,這個過程中其實有很多問題,其中比較難的是:如果操作符和已經有的是相等的關係,那麼就是迴圈進行新建節點,壓棧這些操作.

核心程式:

package com.pipi.MainProcess;

import com.pipi.structure.Node;
import com.pipi.structure.OperatorStacks;
import com.pipi.structure.Stacks;
import com.pipi.util.CheckPriority;
import com.pipi.util.Operate;


public class Structure {
	OperatorStacks CTack = new OperatorStacks(); //存放符號
	Stacks TTack = new Stacks(); //存放二叉樹結構
	
	private StringBuffer dowithstr = new StringBuffer();
	public String DowithStr(String getStr){
		char[] cc = getStr.toCharArray();
		String ch = new String();
		for (int i = 0;i < cc.length; i++){
			if(!Operate.isOperate(String.valueOf(cc[i]))){//如果是數字
				ch = ch + String.valueOf(cc[i]);
				int j = (i+1) == cc.length?(cc.length-1):i+1;
				if(Operate.isOperate(String.valueOf(cc[j])) || cc.length == i+1){
					Node n = new Node();
					n.setData(ch);
					n.setLchild(null);
					n.setRchild(null);
					TTack.push(n);
					ch = "";
				}
			}else{
				// 如果棧裡面當前操作符優先順序小於或者等於ch優先順序,則壓棧ch
				while(CheckPriority.getPriority(CTack.getFirstStr()) >= CheckPriority.getPriority(String.valueOf(cc[i]))){// 如果棧裡面當前操作符優先順序大於ch優先順序,則棧裡面當前操作符出棧,並取得TTack中兩個運算元進行運算
					Node a = TTack.pop();//第一個出棧
					Node b = TTack.pop();//第二個出棧
					Node n = new Node();
					n.setData(CTack.pop());
					n.setLchild(b);
					n.setRchild(a);
					TTack.push(n);
//					int m = CTack.getPoint()>0?(CTack.getPoint()-1):0;
//					CTack.setPoint(m);
					
				}
					CTack.push(String.valueOf(cc[i]));
			}
			}
		while(CTack.getPoint() > 0){
			Node a = TTack.pop();//第一個出棧
			Node b = TTack.pop();//第二個出棧
			
			Node n = new Node();
			
			n.setData(CTack.pop());
			n.setLchild(b);
			n.setRchild(a);
			TTack.push(n);
			
		}
		//計算最後的值
		int result = Operate.getResult(TTack.pop());
		
		/**
		 * 遍歷二叉樹元素,得出結果後沒有用啦
		 */
		int j = TTack.getPoint();  //當前棧中的個數
		for(int i = 0; i < j; i++){
			Node n = TTack.pop();
			System.out.println(n.getData()+"--------from the getData().");
			System.out.println(n.getLchild()+"--------from getLchild().");
			System.out.println(n.getRchild()+"--------from getRchild().");
		}
		
		/**
		 * 遍歷操作符,最後沒有了
		 */
		int k = CTack.getPoint();
		for(int i = 0; i < k; i++){
			System.out.println(CTack.pop());
		}
//		return "";
		return result+"";
	}
}

對棧的操作:

package com.pipi.structure;

public class OperatorStacks {
	private int point = 0; //當前位置
	private String[] sb = new String[100]; //當前位置的內容
	
	/**
	 * 獲取最上面的元素
	 * 如果有,則返回,如果沒有,則返回一個"###"
	 */
	public String getFirstStr(){
		
		if(point>0){
			return sb[point-1];
		}
		return "###";
	}
	
	public String pop(){
		if(point > 0){
			point = point - 1;
		}
		return sb[point];
		
	}
	
	public void push(String n){
		sb[point] = n;
		point++;
	}

	public int getPoint() {
		return point;
	}

	public void setPoint(int point) {
		this.point = point;
	}

	public String[] getSb() {
		return sb;
	}

	public void setSb(String[] sb) {
		this.sb = sb;
	}

	

	
}

工具操作:其中getResult方法用到了遞迴呼叫的方法.

package com.pipi.util;

import com.pipi.structure.Node;
import com.pipi.structure.OperatorStacks;
import com.pipi.structure.Stacks;

/**
 * 兩個數之間的計算
 * @author ya皮皮
 *
 */
public class Operate {
	public static String opr(String str, int num2, int num1){
		if(str.equals("+")){
			return (num2 + num1 +"");
		}else if(str.equals("-")){
			return (num2-num1 +"");
		}else if(str.equals("*")){
			return (num2*num1 +"");
		}else{
			if(num1!=0)
				{
				return (num2/num1 +"");
				}
			return 0+"";
				}
			
	}
	
	/**
	 * 
	 * @param TTack
	 * @param CTack
	 * @return
	 */
	
	//計算
	public static int getResult(Node n){
		String result = new String();
		if(null == n.getLchild() && null == n.getRchild()){
			result = n.getData();
		}else{
			result = opr(n.getData(),getResult(n.getLchild()),getResult(n.getRchild()));
		}
		return Integer.parseInt(result);
	}

	/**
	 * 判斷是不是操作符
	 */
	public static boolean isOperate(String str){
		return "+-*/".indexOf(str) != -1?true:false;
	}
	
}

 定義優先順序:

public class CheckPriority {
	public static int getPriority(String s){
		if(null == s){
			return 0;
		}
		if(s.equals("*") || s.equals("/")){ //* / 是1級
			return 2;
		}else if(s.equals("+") || s.equals("-")){ // + -是0級
			return 1;
		}else{
			return -1;
		}
	}
}

定義二叉樹:

package com.pipi.structure;
/**
 * 
 * @author pipi
 * 定義二叉樹
 */
public class Node {
	String data = new String(); //資料
	Node lchild = null; //左孩子,如果沒有,設定為null
	Node rchild = null; //右孩子,如果沒有,設定為null
	public String getData() {
		return data;
	}
	public void setData(String data) {
		this.data = data;
	}
	public Node getLchild() {
		return lchild;
	}
	public void setLchild(Node lchild) {
		this.lchild = lchild;
	}
	public Node getRchild() {
		return rchild;
	}
	public void setRchild(Node rchild) {
		this.rchild = rchild;
	}
	
	
}

總結:

其實,這個程式只是實現了一個思想,還有很多沒有考慮到的地方,還有很多程式碼需要重構.總的來說,學會了這種思想也是一個小小的進步,接下來會好好完善一下程式碼.

GOGO~

相關推薦

java實現一個計算器

突然之間心血來潮,就是想試一試資料結構怎麼用.到現在才感覺的,資料結構是一種思想,一種思維方式,用怎樣的方式去解決怎樣的問題,這些是資料結構和演算法給我們的. 言歸正傳吧,說說這個小計算器(其實還有太多需要擴充套件和改進的地方).暫時只侷限在加減乘除,因為定義的是int型別的

Python實現一個小說網站雛形

前言 前段時間做了一個爬取妹子套圖的小功能,小夥伴們似乎很有興趣,為了還特意組建了一個Python興趣學習小組,來一起學習。十個python九個爬,在大家的印象中好像Python只能做爬蟲。然而並非如此,Python 也可以做Web開發,接下來給大家展示一下如何做一個小說站點。 相關軟體

Java實現一個萬年曆

import java.util.Scanner; public class DaysCelandar {     // 判斷是不是閏月年     public static boolean isRun(int year) {        if ((year % 4

JAVA一個簡單的JS程式碼格式化工具

/** * cn.newweapon.JsFormatter */package cn.newweapon;import java.io.File;import java.io.FileReader;import java.io.FileWriter;import java.io.FilenameFilter

集合70多種推薦演算法,東北大學老師Java一個開源庫,在GitHub上收穫近1500個Star...

 【AI科技大本營導讀】在經過一年多的開發工作之後,LibRec 3.0 版本終於釋出了。LibRec 是一個基於 Java 的開源演算法工具庫,覆蓋了 70 餘個各型別推薦演算法,可以有效解決評分預測和物品推薦兩大關鍵的推薦問題,目前已經在 GitHub 上收穫

css實現一個精緻的縱向導航選單

<html><head><meta http-equiv="Content-Type" content="text/html; charset=gb2312"><title>縱向導航選單</title><sty

Java和Jquery實現一個砸金蛋例子

之前在網上找到了一個Jquery+PHP實現的砸金蛋的例子,正好公司也要我寫一個類似的砸金蛋的功能,於是在網上找了找參考,用Jsp程式也弄了一個出來,首先是Html的效果,我打算每次在頁面上只顯示一個金蛋,點選的時候用Ajax提交,Java在後臺處理一下返回結果

java實現一個簡單的單戶登陸功能的思路

get 單用戶 這樣的 簡單的 lock ref 數據庫 清除 一個 引用 所謂“單用戶單賬戶登錄”是指:在同一系統中,一個用戶名不能在兩個地方同時登錄。 我們參照 QQ 實現效果:當某賬號在 A 處登錄後,在未退出的情況下,如果再到 B 處登錄,那麽,系統會擠下 A 處

java實現一個簡易編譯器1-詞法解析入門

new 概念 自加 我們 sta 數字 獲得 () 操作系統 本文對應代碼下載地址為: http://download.csdn.net/detail/tyler_download/9435103 視頻地址: http://v.youku.com/v_show/id_XMT

java算法面試題:排序都有哪幾種方法?請列舉。JAVA實現一個快速排序。選擇冒泡快速集合至少4種方法排序

算法 err div println rda print 算法面試 ++ 快速排序 package com.swift; import java.util.ArrayList; import java.util.Collections; import java.util

利用socket技術實現java實現客戶端向服務端傳送檔案,伺服器端接收檔案並給出一個響應。

通訊是網路程式設計中重要的組成部分,而socket程式設計是網路程式設計的基礎。利用socket可以實現客戶端和伺服器端的通訊。下面我先把客戶端和伺服器端的程式碼粘上去再進行詳細的分析。 package test1; import java.io.File; import java.io

[原始碼分享]使用JAVA開發一個雷霆戰機遊戲^_^

本程式使用Myeclipse開發,編碼為UTF-8。 本程式實現的主要功能有玩家飛機的控制、玩家飛機子彈發射、敵機移動、敵機子彈發射、boss飛機的折線運動、boss飛機的子彈發射、玩家飛機和boss飛機的血量顯示、遊戲的暫停開始及重新開始、控制遊戲音效的播放、玩家戰機的選擇(五種戰機)、飛

女朋友發一個化妝速成的視訊給我!我Python實現倒放!嘿嘿

現在的各種動圖層出不窮,深受大家喜歡,今天給大家介紹一個可以把gif動圖倒放的python程式,先來看下效果。 女朋友這裡就不貼出來給大家看了,萬一你們都喜歡我女朋友了咋辦!還是得藏好!就給一個成功的例子給大家kanyix       &

java實現一個行鎖(RowLock)

java 版本的資料庫行鎖,使用wait/notify實現,當然可以使用別的方式如Lock下的await/signal 需求使用java寫一個類,這個類有一個lock(String identifie

一個Java實現密碼演算法,使用socket引發的血案

public static void main(String[] args) throws IOException, ParseException { ServerSocket serverSocket = new ServerSocket(1

最普通的文件,我做一個助手,沒有一行程式碼

當我寫下第一行文字時,雅格布就這樣誕生了。 我的助手雅格布 雅格布是我的助手,它能在工作中,幫我做出正確的選擇; 還能讓我在工作中持續投入時間,並保持激情。 簡單來說,雅格布是一個決策工具,專門解決選擇的問題,另一方面透過它,我們還能追求事情本身的確定性; 在

閒來無事,Python寫一個pm2.5查詢程式,還是很有趣的

    今天教大家用python完成首個MVP,如何用CLI(command-line interface,命令列介面)來執行第一個空氣質量查詢程式。 更多Python視訊、原始碼、資料加群960410445免費獲取   知識點

(2) java實現一個簡易編譯器1-詞法解析入門

轉載地址 : http://blog.csdn.net/tyler_download/article/details/50668983/ 視訊地址 : http://study.163.com/course/courseLearn.htm?courseId=10028300

JAVA實現一個爬蟲,爬取知乎的上的內容(程式碼已無法使用)

在學習JAVA的過程中寫的一個程式,處理上還是有許多問題,爬簡單的頁面還行,複雜的就要跪. 爬取內容主要使用URLConnection請求獲得頁面內容,使用正則匹配頁面內容獲得所需的資訊存入檔案,使用正則尋找這個頁面中可訪問的URL,使用佇列儲存未訪問的URL

java實現一個簡單的ArrayList

重複造輪子雖然不可取,但是溫習一下資料結構,光看不做總是少了什麼,所以也來實現一下List,希望多多包涵。 既然要實現一個List,先來簡單說一下List的定義 線性表是最基本、最簡單、也是最常用的一種資料結構。 線性表中資料元素之間的關係是一對一的關係