用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的定義 線性表是最基本、最簡單、也是最常用的一種資料結構。 線性表中資料元素之間的關係是一對一的關係