簡易計算器的java實現


偽代碼

public class MainTestwei
{
    定義兩個數組,List<Double> number和 List<Character>calculation分別用來裝數字和 計算符
     //與老師上課講的入棧出棧差不多
     public Count() {}方法初始化number和 calculation
    public void init()方法清空數組
    private boolean check()方法檢查輸入算式是否合法同時檢查數字個數是否比計算符個數大1
    private int findCount(String text, String regex, int len)方法返回輸入的算式中匹配正則表達式得到元素的個數
    private void setValue()給number和 calculation數組定初值(應用正則表達式)
    private double sum()用case語句進行求值,注意*/在前+-在后
    public String out(String text)判斷是否合法,合法輸出結果,不合法輸出error
}

各個方法的依次實現

1.初始化number和 calculation

public Count() {
        number = new ArrayList<>();
        calculation = new ArrayList<>();

    }

其中已經提前定義過

private List<Double> number;
    private List<Character> calculation;
    private String text;

即number是 型的。calculation
字符型的。

2.private int findCount(String text, String regex, int len)方法返回輸入的算式中匹配正則表達式得到元素的個數。代碼如下

 private int findCount(String text, String regex, int len) {
        int count = 0;
        Pattern compile = Pattern.compile(regex);
        Matcher matcher = compile.matcher(text);
        while (matcher.find()) {
            count++;
            if (len > 0) {//
                System.out.println(matcher.group().length());
                if (matcher.group().length() != len)//不理解matcher.group().length()
                {
                    System.out.println(matcher.group().length());
                    return -1;
                }


            }
        }
        return count;

其中

matcher.group().length()

是關於正則表達式中含有括號的個數。如
regex1 = "[+\-*/]+"它的matcher.group().length()即為1.因為中。間沒有()分割。

regex = "\d+"它的matcher.group().length()也為1.

matcher.group()即為一次匹配得到的所有,不考慮括號()問題,而matcher.group(i)即為匹配第i個括號中所得到的表達式。

其中

if (len > 0) {//為什么
                System.out.println(matcher.group().length());
                if (matcher.group().length() != len)//不理解matcher.group().length()
                {
                    return -1;
                }

是為了避免式子中出現括號。

3.private boolean check()方法檢查輸入算式是否合法同時檢查數字個數是否比計算符個數大1。
代碼如下

private boolean check() {
        if (text == null || !text.matches("[0-9+\\-*/]+"))//正則表達式不太理解
            return false;

        String regex= "\\d+";
        String regex1 = "[+\\-*/]+";
        if (findCount(text, regex1, 1) == -1)
            return false;
        return findCount(text, regex1, 1) == findCount(text, regex, 0) - 1;

    }

regex是匹配數字用的正則表達式,regex1是匹配+ -/的正則表達式,而-/ 都需要轉義,故在前面加上//。

如果出現括號則error,否則如果數字個數比字符個數多1,則正確,返回true。

4.private void setValue()給number和 calculation數組定初值(應用正則表達式),代碼如下:

   private void setValue() {
        Pattern compile = Pattern.compile("\\d+");
        Matcher matcher = compile.matcher(text);
        while (matcher.find()) {
            number.add(Double.parseDouble(matcher.group()));
        }
        Pattern compile1 = Pattern.compile("[+-/*]");
        Matcher matcher1 = compile1.matcher(text);
        while (matcher1.find()) {
            calculation.add(matcher1.group().charAt(0));
        }
    }

matcher.group()代表的就是匹配的內容,因為數字與字符交替排列,故每次add matcher.group()即可,轉化為Double型。

5.private double sum()用case語句進行求值,注意*/在前+-在后。
代碼如下:

private double sum() {

        for (int i = 0; i < calculation.size(); i++) {
            char c = calculation.get(i);
            switch (c) {
                case '*':
                    number.set(i, number.get(i) * number.get(i + 1));
                    number.remove(i + 1);
                    calculation.remove(i);
                    i -= 1;//為什么要加i=i-1;
                    break;
                case '/':
                    number.set(i, (Double) number.get(i) / number.get(i + 1));
                    number.remove(i + 1);
                    calculation.remove(i);
                    i -= 1;
                    break;
            }
        }

        for (int i = 0; i < calculation.size(); i++) {
            char c = calculation.get(i);
            switch (c) {
                case '+':
                    number.set(i, number.get(i) + number.get(i + 1));
                    number.remove(i + 1);
                    calculation.remove(i);
                    i -= 1;
                    break;
                case '-':
                    number.set(i, (Double) number.get(i) - number.get(i + 1));
                    number.remove(i + 1);
                    calculation.remove(i);
                    i -= 1;
                    break;
            }
        }

        return number.get(0);
    }

其中為什么需要i=i-1?
因為上面有 for (int i = 0; i < calculation.size(); i++)循環,當你執行 calculation.remove(i);之后,i所指向的已經是下一個符號或者是數字了,但因為for循環仍然需要i++,故要提前把i-1。

此處與棧的操作類型有幾分相似之處,再MyDC.java中,經過

while (tokenizer.hasMoreTokens()) //進行遍歷
{
            token = tokenizer.nextToken();
           //token是單字符的字符串
           //如果是運算符,調用isOperator
            if (isOperator(token)==true) {
                op2=stack.pop();
                op1=stack.pop();
                //從棧中彈出操作數2
                //從棧中彈出操作數1
                result=evalSingleOp(token.charAt(0),op1,op2);
                //根據運算符和兩個操作數調用evalSingleOp計算result;
                stack.push(result);
                //計算result入棧;
            }
            else//如果是操作數
            {
                stack.push(Integer.parseInt(token));//需要轉化為int型
            }
            //操作數入棧;
        }


6.public String out(String text)判斷是否合法,合法輸出結果,不合法輸出error
代碼如下

public String out(String text) {
        init();
        if (getString(text)) {
            return sum() +"";//sum()為double類型,需要轉化為字符串類型,則加上“”即可

        } else {
            return "error";
        }

    }

其中init()用clear()方法即可。

最終代碼

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MainTest {
    public static void main(String[] args) {
        while (true) {
            Scanner input = new Scanner(System.in);
            String text = input.nextLine();
            String string = new Count().out(text);
            System.out.println(string);
        }

    }

}

class Count {
    private List<Double> number;
    private List<Character> calculation;
    private String text;

    public Count() {
        number = new ArrayList<>();
        calculation = new ArrayList<>();

    }

    public String out(String text) {
        init();
        if (getString(text)) {
            return sum() +"";

        } else {
            return "error";
        }

    }

    private double sum() {

        for (int i = 0; i < calculation.size(); i++) {
            char c = calculation.get(i);
            switch (c) {
                case '*':
                    number.set(i, number.get(i) * number.get(i + 1));
                    number.remove(i + 1);
                    calculation.remove(i);
                    i -= 1;//為什么要加i=i-1;
                    break;
                case '/':
                    number.set(i, (Double) number.get(i) / number.get(i + 1));
                    number.remove(i + 1);
                    calculation.remove(i);
                    i -= 1;
                    break;
            }
        }

        for (int i = 0; i < calculation.size(); i++) {
            char c = calculation.get(i);
            switch (c) {
                case '+':
                    number.set(i, number.get(i) + number.get(i + 1));
                    number.remove(i + 1);
                    calculation.remove(i);
                    i -= 1;
                    break;
                case '-':
                    number.set(i, (Double) number.get(i) - number.get(i + 1));
                    number.remove(i + 1);
                    calculation.remove(i);
                    i -= 1;
                    break;
            }
        }

        return number.get(0);
    }

    public void init() {
        number.clear();//清空數組
        calculation.clear();
    }

    public boolean getString(String text) {
        this.text = text;
        if (check()) {

            setValue();
            return true;
        }
        return false;
    }

    private void setValue() {
        Pattern compile = Pattern.compile("\\d+");
        Matcher matcher = compile.matcher(text);
        while (matcher.find()) {
            number.add(Double.parseDouble(matcher.group()));
        }
        Pattern compile1 = Pattern.compile("[+-/*]");
        Matcher matcher1 = compile1.matcher(text);
        while (matcher1.find()) {
            calculation.add(matcher1.group().charAt(0));
        }
    }

    private boolean check() {
        if (text == null || !text.matches("[0-9+\\-*/]+"))//正則表達式不太理解
            return false;

        String regex = "\\d+";
        String regex1 = "[+\\-*/]+";
        if (findCount(text, regex1, 1) == -1)
            return false;
        return findCount(text, regex1, 1) == findCount(text, regex, 0) - 1;

    }
    private int findCount(String text, String regex, int len) {
        int count = 0;
        Pattern compile = Pattern.compile(regex);
        Matcher matcher = compile.matcher(text);
        while (matcher.find()) {
            count++;
            if (len > 0) {//為什么
                System.out.println(matcher.group().length());
                if (matcher.group().length() != len)//不理解matcher.group().length()
                {
                    return -1;
                }


            }
        }
        return count;
    }

}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM