簡體   English   中英

Android計算器App好習慣?

[英]Android calculator App good practice?

大家好我是Android世界的新手,我正在努力構建我猜一個中等難度的計算器應用程序。 我提出了這種結構,但沒有實現任何東西,因為我有點懷疑這是否是正確的方法。 所以我走了:

我有一個操作數界面,帶有一種叫做“getValue()”的方法,應該返回一個double類型,以及一些實現該接口的其他對象,從而實現“getValue()”方法:

  • 表達式 ,我想過將這個對象作為一個私有成員字段來存儲所有的操作,所以這個表達式對象會有這樣的東西:

     public class Expression implements Operand { private List<Operation> operationList; ... } 

    operationList將是一個ArrayList,其中Operation是另一個對象,它將涉及兩個操作數(因此兩個操作數接口作為類型)與一個Operator對象綁定在一起,該對象具有一個枚舉類型,表明涉及這兩個操作數的操作是否為SUM,DIV ,MUL或SUB。 就像是:

     public class Operation { private Operand operand1; private Operand operand2; private Operator operator; public Operation(Operand operand1, Operator operator, Operand operand2) { this.operand1 = operand1; this.operand2 = operand2; this.operator = operator; } public double getResult() { if (operator.getType() == Operator.Type.SUM) { return operand1.getValue() + operand2.getValue(); } else if (operator.getType() == Operator.Type.SUB) { return operand1.getValue() - operand2.getValue(); } else if (operator.getType() == Operator.Type.MUL) { return operand1.getValue() * operand2.getValue(); } else if (operator.getType() == Operator.Type.DIV) { return operand1.getValue() / operand2.getValue(); } return 0; } ... } 

這樣,即使在像“3 +(4 * 3 - 2 *(4 - 1)/ 2 + 5)”這樣的表達式中使用子表達式,也會像操作數一樣評估操作數,特別是在此案件:

 operator   All this is another Expression object (a sub-expression that is treated 
   |         |                                     like an Operand
   | ________|____________                         cause it implements the Operand
 3 + (4 * 3 - 2 * (4 - 1))                         interface).
 |
Operand operand1
  • 實現Operand的Number類,它將是double值的簡單Wrapper類,並且將在它實現的getValue()方法中返回該double。

  • 具有枚舉類型的函數類,如果它是SIN,COS,TAN,ARCSIN,ARCCOS,ARCTAN,LOG或LN函數,則始終使用getValue()方法返回函數計算的雙重結果;

  • 實用程序,這個類可能會被誤解:它是一個類,用於取冪,平方根,數字的百分比或它的階乘等操作。 這里的想法是再次使用枚舉類型來區分操作類型。 我知道取冪是一個操作本身但我看起來更好,使它遠離前面解釋的操作類導致結構和計算不同(我想將指數視為操作數類型,而不是操作對我來說,一個操作只涉及兩個操作數和一個操作符,如前所述)。

然后我知道,給出一個表達式:

3 + 4 * ((5 + 2) - √4 + sin(4) + 3²) / 2

數據結構將是:

  Operand                              Operand
    |                                  |   
3 + 4 * ((5 + 2) - √4 + sin(4) + 3²) / 2
|       ¯¯¯¯¯¯¯¯¯¯¯¯¯|¯¯¯¯¯¯¯¯¯¯¯¯¯¯  
Operand             Operand

4個操作數,因此3個操作,但我需要建立優先級,所以我認為我應該遍歷operationList(Expression對象中的私有字段)來獲得這樣的優先級,因為我的數據結構會像(基於這個表達式,偽代碼):

列表:

- Item n° 1 -> Operation(Number(3), Operator(Operator.Type.SUM), Number(4));
- Item n° 2 -> Operation(Number(4), Operator(Operator.Type.MUL), Expression("(5 + 2) - √4 + sin(4) + 3²"));
- Item n° 3 -> Operation(Expression("(5 + 2) - √4 + sin(4) + 3²"), Operator(Operator.Type.DIV), Number(2));

迭代此列表我可以發現操作號2(項目編號2)必須在操作編號1之前執行。但我認為這種方式不太好因為你看我每次都需要整理所有的ArrayList當執行操作N°2並獲得雙重結果時,從操作原因獲取結果,我需要為該結果創建一個Number()對象,以像操作數一樣再次處理它,並以操作的方式重新組織ArrayList第一個沒有Number(4)作為第二個操作數,但是包含在Number對象中的Operation 2 getResult()的新結果。 此外,位置3處的操作不再具有表達式作為第一個操作數,而是將前一個操作的結果作為操作數。

在我看來,這種結構的處理有點貴,我問的是,是否有人面臨同樣的問題,並提出了更好的解決方案,或者這個解決方案可能沒問題。 另一種方法是將完整的Expression存儲為String,並使用RegExp對其進行解析,以按順序確定所有操作。 這是一個更好的解決方案,因為我想讓用戶在他輸入表達式時動態更改操作數,即如果他寫了上一個表達式:

3 + 4 * ((5 + 2) - √4 + sin(4) + 3²) / 2

如果他想要點擊“等於”按鈕執行操作,他可以​​將√4更改為ln(6)。 所以我想使用以前的ArrayList會很難管理這樣的改變,因為我需要保持我的表達式的每個操作數的位置...

例如Google如何在他的計算器應用程序中執行此操作,例如,如果您查看 - > https://www.google.it/search?q=2%2B2&oq=2%2B2&aqs=chrome.0.69i59j0l2j69i65l2j0.1141j0j7&sourceid=chrome&es_sm=94&ie= UTF-8#q = + 3 +%2B + 4 + * +((5 +%2B + 2)+ - + SIN(4)+%2B + 3)+%2F + 2

我知道這是Javascript,但我猜每種語言的邏輯都是一樣的。

您認為可能的解決方案是什么? 謝謝你的關注!

編輯:我不明白的事情:

  /**
       Evaluates a simple expression (such as "1+1") and returns its value.
       @throws SyntaxException in these cases:
       <ul>
       <li> the expression is not well-formed
       <li> the expression is a definition (such as "a=1+1")
       <li> the expression is an implicit function (such as "x+1")
       </ul>
     */
    public synchronized double eval(String expression) throws SyntaxException {
        return compiler.compileSimple(this, expression).eval();
    }

此方法調用編譯器編譯對象的.compileSimple:

Function compileSimple(Symbols symbols, String expression) throws SyntaxException {
    rpn.setConsumer(simpleCodeGen.setSymbols(symbols));
    lexer.scan(expression, rpn);
    return simpleCodeGen.getFun();
}

它返回一個Function對象,然后在其上調用eval()方法。 看看Function.eval()方法,我看到了這個:

/**
       Evaluates an arity-0 function (a function with no arguments).
       @return the value of the function
    */
    public double eval() {
        throw new ArityException(0);
    }

方法eval必須返回一個double類型,並且實現拋出一個具有此實現的ArityException:

public class ArityException extends RuntimeException {
    public ArityException(String mes) {
        super(mes);
    }

    public ArityException(int nArgs) {
        this("Didn't expect " + nArgs + " arguments");
    }
}

它如何評估String並在拋出ArityException時返回double?

您可能想看一下隨平台打包的官方Android計算器應用程序的源代碼。

我認為Logic.java將是您正在尋找的類。 它具有格式化代碼,檢查運算符,估值等: Android計算器

編輯

Android計算器使用Arity Arithmetic Engine,它是一個開源庫,用於評估表示為字符串的算術表達式。 我無法找到該項目的活動鏈接,它已從code.google.com中刪除。 但您可以參考以下鏈接獲取更多信息:

  1. http://www.developerfusion.com/project/62854/arity/
  2. 下載arity .jar

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM