简体   繁体   English

Java StringTokenizer考虑括号

[英]Java StringTokenizer considering parentheses

I am creating a program that tokenizes boolean logic expressions and returns the String array of tokens. 我正在创建一个将布尔逻辑表达式标记化并返回标记字符串数组的程序。 The following is my code: 以下是我的代码:

public static String[] tokenize(String s)
{
    String delims = "+";
    StringTokenizer st = new StringTokenizer(s, delims);
    String[] tokens = new String[st.countTokens()];

    int i=0;
    while (st.hasMoreElements()) {
        tokens[i++] = st.nextElement().toString();
    }

    return tokens;
}

For example, I have the following string as an input: 例如,我将以下字符串作为输入:

A+B+(C+D+(A+B))+(B+C) A + B +(C + D +(A + B))+(B + C)

Using the code I have, it will only generate the following tokens: 使用我拥有的代码,它将仅生成以下令牌:

A
B
(C
D
(A
B))
(B
C)

Is it possible (using the same structure of code) to come up with these tokens? 是否可以(使用相同的代码结构)提出这些标记? If not, how is it code-able? 如果没有,它如何编码?

A
B
(C+D+(A+B))
(B+C)
    ArrayList<String> tokens = new ArrayList<String>();
    String current = "";
    int counter = 0;
    for(int i = 0 ; i < input.length(); i++)
    {
        char c = input.charAt(i);
        if(counter==0 && c=='+')
        {
            tokens.add(current);
            current = "";
            continue;
        }
        else if(c=='(')
        {
            counter++;
        }
        else if(c==')')
        {
            counter--;
        }
        current += c;
    }
    tokens.add(current);

This is the solution for my comment: 这是我的评论的解决方案:

You could just loop through 1 character at a time, when you reach a + while not in a parenthesis, save the characters read up to there, and start a new set. 您可以一次遍历一个字符,当您到达+时而不用括号括起来,保存到此读取的字符,然后开始一个新的字符集。 The way to track if you're in aa set of parentheses is with a counter. 跟踪是否在括号中的方法是使用计数器。 When you hit a open parenthesis, you increment a counter by 1, when you hit a close parenthesis you decrement the counter by 1. If the counter > 0 then you're in parentheses. 当您点击一个圆括号时,您将计数器加1,当您点击一个圆括号时,您将计数器减1。如果计数器> 0,则位于括号中。 Oh, and if counter ever goes negative, the string is invalid, and if counter is not 0 at the end, then the string is also invalid. 哦,如果counter变为负数,则该字符串无效,并且如果counter最后不为0,则该字符串也无效。

You can do the checks on counter and return false or something, to show that it is an invalid string. 您可以检查计数器并返回false或其他内容,以表明它是无效的字符串。 If you know the string is valid then this works as is. 如果您知道该字符串是有效的,则可以按原样运行。 You can get an array from the ArrayList, with tokens.toArray() 您可以使用tokens.toArray()从ArrayList中获取一个数组。

If you can find a simple solution go with it otherwise try mine 如果您可以找到简单的解决方案,请尝试使用我的解决方案

    String s = "A+B+(C+D+(A+B))+(B+C)";
    List<String> l = new ArrayList<>();
    StringBuilder sb = new StringBuilder();
    int p = 0;
    for (char c : s.toCharArray()) {
        if (c == '(') {
            p++;
            sb.append(c);
        } else if (c == ')') {
            p--;
            sb.append(c);
        } else if (p == 0 && c == '+') {
            l.add(sb.toString());
            sb.setLength(0);
        } else {
            sb.append(c);
        }
    }
    if (sb.length() > 0) {
        l.add(sb.toString());
    }
    System.out.println(l);

output 产量

[A, B, (C+D+(A+B))]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM