令牌迭代器类,用于反编译不使用数字的数学表达式

时间:2015-03-23 19:15:08

标签: java iterator token

我有一个类,我必须打印数学表达式的每个标记。我有我的代码,它打印出除数字之外的所有内容。我不确定要做什么来解决这个问题。

这就是所需的输出:

next token: [15] 

next token: [*] 

next token: [(] 

next token: [26] 

这就是我的代码目前产生的内容:

next token: [1] 

next token: [5] 

next token: [*] 

next token: [(] 

next token: [2] 
等等......

这是我的代码:

public class TokenIter implements Iterator<String> {
    static int counter = 0;
    private String line;
    private String nextToken;

    public TokenIter(String line) {
        this.line = line;
    }

    public void remove() {
        throw new UnsupportedOperationException();
    }

    public static void main(String[] args) {
        String line = "  15*(26+37) - 443/7*612 - (233-543234)   ";
        System.out.println("line: [" + line + "]");
        TokenIter tokIt = new TokenIter(line);
        // print tokens in square brackets to check absence of white space
        while (tokIt.hasNext()) {
            if (tokIt.next() != "no")
                System.out.println("next token: [" + tokIt.next() + "]");
            counter++;
        }
    }

    public boolean hasNext() {
        if (counter < line.length())
            return true;
        else
            return false;
    }

    public String next() {
        String s = "";
        if (!hasNext())
            return null;
        else {
            char c = line.charAt(counter);
            if (c == ('/')) {
                counter = counter++;
                s = "" + c;
                return s;
            }
            if (c == ('+')) {
                counter = counter++;
                s = "" + c;
                return s;
            }
            if (c == ('*')) {
                counter = counter++;
                s = "" + c;
                return s;
            }
            if (c == ('-')) {
                counter = counter++;
                s = "" + c;
                return s;
            }
            if (c == ('(')) {
                counter = counter++;
                s = "" + c;
                return s;
            }
            if (c == (')')) {
                counter = counter++;
                s = "" + c;
                return s;
            } else if (c == ' ') {
                counter = counter++;
                return "no";
            }
            while (Character.isDigit(c)) {
                counter = counter++;
                s += "" + c;
                return s;
            }
        }
        return s;
    }
}

我知道还有其他方法可以像带有分隔符的字符串标记器一样,但我需要这样做。

1 个答案:

答案 0 :(得分:0)

嗯,您的代码包含几个问题:

  • if (tokIt.next() != "no")

    这不是比较字符串的正确方法。请改为使用#equalsif (!tokIt.next().equals("no"))。您当前正确地比较了可以找到"no"的字符串,因为您使用了String literal。如果用户将“no”输入控制台并尝试使用!= "no"进行比较,则无法使用此功能。所以记住这一点

  • 您正在拨打tokIt.next()两次。第一次是在我上面提到的if语句中,第二次是System.out.println("next token: [" + tokIt.next() + "]");。如果您的代码正确地移动光标(通过增加counter),那么您将跳过每一秒令牌。创建一个新的String来携带令牌String token = tokIt.next();并使用它与“no”进行比较并打印它。

  • 您不应在counter++;方法中致电main。这会将光标移动到String中的下一个字符。将其留给next方法。只有这种方法才能移动光标。

  • 不是问题,但您的hasNext可以简化为:

    public boolean hasNext() {
        return counter < line.length();
    }
    
  • 请勿使用counter = counter++;counter++与以下内容相同:

    int temp = counter;
    counter = counter + 1;
    return temp;
    

    因此,如果您写counter = counter++;,则将counter设置为旧值,然后再添加1。这意味着,counter不会改变其价值。您可以删除counter =部分,但是......

  • 请勿在{{1​​}}方法的每个counter++分支中致电if。在next中执行一次:

    char c = line.charAt(counter);

    这样你就可以读取当前char c = line.charAt(counter++); 的值并增加其值,所以下次你读到的东西时,它将是下一个位置。

  • 不要创建变量counter:这不是问题,但也没有用。由于每个s分支都包含类似

    的内容
    if

    你可以写:

    if (c == (...)) {
        s = "" + c;
        return s;
    }
    

    这也避免了字符转换为字符串的“尴尬”版本:if (c == (...)) { return Character.toString(c); }

  • 不要使用这些"" + c语句进行简单检查,然后返回相同的字符。你可以这样做:

    if

    这样,您可以在一个if ("/+*-()".indexOf(c) >= 0) { return Character.toString(c); } 语句中检查所有允许的数学字符。而且添加新角色“更好”。

  • 这是您当前的if循环,应该读取每个组合数字:

    while

    如您所见,它将在第一个while (Character.isDigit(c)) { counter = counter++; s += "" + c; return s; } 循环迭代中返回s。您真正需要的是删除该返回并从源字符串中读取下一个字符以将其添加到while。这看起来像这样:

    s

在您按照我的评论后,您的输出应为:

String s = ""; // since we removed the old "s" (see my seventh remark), we need to create it here
while (Character.isDigit(c)) {
    s += Character.toString(c); // add current character to String s
    c = line.charAt(counter++); // read next character
    if (!Character.isDigit(c)) { // if it is not a digit
        counter--; // move the cursor one position back
        break; // stop the loop
    }
}

我知道,有更好的方法来实现OP的目标,但我认为他仍然应该使用自己的方法并从中学习。