java - 在计算器程序中实现模运算符

标签 java algorithm

到目前为止,这是我的代码:

public class Token {
        // Data:
        private String type = "";
        private String name = "";
        private double value = 0;

        // Constructors:
        public Token() { this( "" ); }
        public Token( String t ) { this( t, 0 ); }
        public Token( String t, double v ) { this( t, t, v ); }
        public Token( String t, String n, double v ) { 
            type = t; name = n; value = v; 
        }

        // Methods:
        public String getType( ) { return type;}
        public String getName( ) { return name;}
        public double getValue( ) { return value; }
        public String toString( ) { return (" type="+type+" name="+name+" value="+value);}
}
import java.util.*;

public class Memory {

    private HashMap<String, Double> map;

    /** Creates new Memory */
    public Memory() {
        map = new HashMap<String, Double>();
    }

    public void store(String name, double value) {
        map.put(name, new Double(value));
    }

    public double fetch(String name) {
        Double x = (Double)map.get(name);
        if (x == null) return 0;
        return x.doubleValue();
    } 
}

public class Evaluator {
    private double value;
    private static EvalTokenizer str; 
    private static Memory mem = new Memory();

    public Evaluator( String s ) {
        str = new EvalTokenizer( s );
        value = evaluate();    
    }

    public double getValue() {
        return value;
    }
    public void storeCurrentValue(int line) {
        mem.store("$"+line, value);
    }
    private double evaluate() {
        return evalStatement(str.getToken());
    }

    private double evalStatement(Token firstToken) {
        /* <statement> ::= <var> = <expression> 
                         | <expression> 
                         */
        String s = firstToken.getType();
        // if (s.equals("goto")) return 0;
        if (s.equals("_id") && (str.peekToken().getType()).equals("=")) {
            // <statement> ::= <var> = <expression> 
            str.getToken();
            double x = evalExpression(str.getToken());
            mem.store(firstToken.getName(), x);
            return x;
        }
        return evalExpression(firstToken);
    }

    private double evalExpression(Token firstToken) {
        /* <expression> ::= <term> 
                          | <expression> + <term>
                          | <expression> - <term>
        */
        double x = evalTerm(firstToken);
        while (true) {
            String op = str.peekToken().getType();
            if (op.equals("+") || op.equals("-")) {
                str.getToken(); // skip "+" or "-"
                double y = evalTerm(str.getToken());
                if (op.equals("+")) x += y;
                else x -= y;
            } else
                return x;
        }
    }

    private double evalTerm(Token firstToken) {
        /* <term> ::= <factor>
                    | <term> * <factor> 
                    | <term> / <factor> 
        */
        double x = evalFactor(firstToken);
        while (true) {
            String op = str.peekToken().getType();
            if (op.equals("*") || op.equals("/") {
                str.getToken(); // skip "*" or "/"
                double y = evalFactor(str.getToken());
                if (op.equals("*")) x = x*y;
                else x= x/y;

            } else return x;


        }
    }

    private double evalFactor(Token firstToken) {
        /* <factor> ::= ( <expression> )
                    | + <factor>
                    | - <factor>
                    | <variable>  
                    | ++ <variable>  
                    | -- <variable>
                    | <number> 
        */
        String t = firstToken.getType();

        if (t.equals("(")) { 
            // <factor> ::= ( <expression> )
            double x = evalExpression(str.getToken());
            String nex = str.getToken().getType();
            if (!nex.equals(")")) throw new ArithmeticException("bad expression" );
            return x;
        }

        // <factor> ::= + <factor> | - <factor>
        if (t.equals("+")) return (evalFactor(str.getToken()));
        if (t.equals("-")) return (-evalFactor(str.getToken()));

        // <factor> ::= <number> 
        if (t.equals("_num")) return firstToken.getValue(); 

        // <factor> ::= <variable> 
        if (t.equals("_id")) return mem.fetch(firstToken.getName());

        if (t.equals("++") || t.equals("--")) { 
            // <factor> ::= ++ <variable> | -- <variable> 
            firstToken = str.getToken();
            if ((firstToken.getType()).equals("_id")) {
                double x = mem.fetch(firstToken.getName());
                if (t.equals("++")) {
                    mem.store(firstToken.getName(), x+1);
                    return x+1;
                } else {
                    mem.store(firstToken.getName(), x-1);
                    return x-1;
                }
            }
        }

        throw new ArithmeticException("bad expression" );
    }
}
import java.util.StringTokenizer;

public class EvalTokenizer {
    // Data:
    private StringTokenizer str;
    private Token nextToken = new Token();

    public EvalTokenizer( String line ) { 
        str = new StringTokenizer(line, "+*-/().<>!=%,|& ", true);
        getToken();
    }

    public Token peekToken() { return nextToken; }

    /**
     * A token is either a number literal (integer or double), an identifier, or special symbols 
     * getToken finds the next token, skipping blanks, and return it.
     * For _int or _double token, place the processed value in value.
     * For _id, place the name of the identifier in name.
     * Throw ArithmeticException if input is unrecognized.
     */
    public Token getToken( ) throws ArithmeticException {

         static boolean isVariable(String id) {

         }
        Token result = nextToken;
        nextToken = getNextToken();
        String t1 = result.getType();
        String t2 = nextToken.getType();

        // handle floating numbers
        if (t1.equals("_num") && t2.equals(".")) {
            nextToken = getNextToken();
            t2 = nextToken.getType();
            if (!t2.equals("_num")) throw new ArithmeticException("number format error" );
            t2 = nextToken.getName();
            double x = result.getValue()+nextToken.getValue()*Math.pow(10.0, -t2.length());
            nextToken = getNextToken();
            return new Token("_num", "", x);
        }

        if (t1.equals("$")) {
            if (t2.equals("_int")) {        
                double x = nextToken.getValue();
                nextToken = getNextToken();
                return new Token("_dollar", x);
            } else 
                throw new ArithmeticException("dollar variable format error" );
        }

        if (t1.equals("+")) {
            if (t2.equals("+")) { nextToken = getNextToken(); return new Token("++"); }
        }

        if (t1.equals("-")) {
            if (t2.equals("-")) { nextToken = getNextToken(); return new Token("--"); }
        }

        if (t2.equals("=")) { 
            if (t1.equals(">")) { nextToken = getNextToken(); return new Token(">="); }
            if (t1.equals("<")) { nextToken = getNextToken(); return new Token("<="); }
            if (t1.equals("=")) { nextToken = getNextToken(); return new Token("=="); }
        }
        System.out.println("token = "+result);
        return result;
    }

    private Token getNextToken() throws ArithmeticException {
        long theValue;    
        // Return a default empty token when no more tokens in str.
        if( !str.hasMoreTokens()) return new Token();  

        String s = str.nextToken( );
        if( s.equals( " " ) ) return getNextToken();

        char c = s.charAt(0);
        if ('0' <= c && c <= '9') {  // numbers
            try { theValue = Long.parseLong( s ); }
            catch( NumberFormatException e ) {
                throw new ArithmeticException("number format error" );
            }
            return new Token( "_num", s, theValue);
        } 

        if ('A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || c == '$') // identifiers
            return new Token( "_id", s, 0);

        return new Token( s, s, 0 );
    }

}
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Calculator {
    /**
     * Simple main to exercise Evaluator class.
     */
    public static void main( String [ ] args )
    {
        String str;
        BufferedReader in = new BufferedReader( new InputStreamReader( System.in ) );
        int line = 1;
        System.out.print( "Enter expressions, one per line:\nline 1: " );

        while (true) {
            try {
                str = in.readLine( );
                if (str == null) continue; 
                if (str.equals("quit")) break;
                Evaluator ev = new Evaluator( str );
                System.out.println( "line " + line + " result >>> " + ev.getValue( ) );
                ev.storeCurrentValue(line);

                line++;
                System.out.print( "line "+line+": " );
            }
            catch( IOException e ) { 
                System.err.println( e );
                System.out.print( "line "+line+": " );
            }
            catch (ArithmeticException e) { 
                System.err.println( e );
                System.out.print( "line "+line+": " );
            }
        } // end while

        System.out.println("Goodbye.");
    } // end main
}

我需要编辑此代码块以实现 % 运算符:

private double evalTerm(Token firstToken) {
        /* <term> ::= <factor>
                    | <term> * <factor> 
                    | <term> / <factor> 
        */
        double x = evalFactor(firstToken);
        while (true) {
            String op = str.peekToken().getType();
            if (op.equals("*") || op.equals("/") {
                str.getToken(); // skip "*" or "/"
                double y = evalFactor(str.getToken());
                if (op.equals("*")) x = x*y;
                else x= x/y;

            } else return x;


        }
    }

我已经试过了,但出于某种原因它无法正常工作,即使 % 是我的 token 的一部分:

private double evalTerm(Token firstToken) {
        /* <term> ::= <factor>
                    | <term> * <factor> 
                    | <term> / <factor> 
        */
        double x = evalFactor(firstToken);
        while (true) {
            String op = str.peekToken().getType();
            if (op.equals("*") || op.equals("/") || op.equals("%")) || {
                str.getToken(); // skip "*" or "/"
                double y = evalFactor(str.getToken());
                if (op.equals("*")) x = x*y;
                if (op.equals("/")) x= x/y;
                else x = x%y;
            } else return x;


        }
    }

我做错了什么,我该如何解决?

最佳答案

在你的代码中你有

if (op.equals("*")) x = x*y;
if (op.equals("/")) x= x/y;
else x = x%y;

我想你的意思是在第二行有一个 else if

if (op.equals("*")) x = x*y;
else if (op.equals("/")) x= x/y;
else x = x%y;

关于java - 在计算器程序中实现模运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4149064/

相关文章:

arrays - 看不懂CLRS问题4-2案例2

java - 查找达到给定值的最小包装数

python - 通过删除 "middlest"项从数组中删除条目的算法?

java - 编辑文本不将背景设为透明

java - 创建 EnityManagerFactory 时出现 NullPointerException

Java 在一个类中打开文件流并在另一个类中关闭/删除文件

c++ - Bresenham 用于球体?

java - 并行数组和从文件读取整数/ double 的问题

java - 设置Swing程序的默认字体

c++ - 把最胖的人从重载的飞机上扔下来。