3

I am working on a mini scientific calculator which works on infix to postfix algorithm. My input is an infix string .. and my infix to postfix conversion logic requires an array of string. So how can i split an infix string like this:

 100+(0.03*55)/45-(25+55)

To an array of String in which each operand and operator is an array element. like this

 "100" , "+" , "(" , "0.03" , "*" , "55" , ")" , "/" , "45" , "-"

and so on...

Note that there is no space in the string so it can't be split on the basis of regex " ".

5 Answers 5

2

Apparently each character is an apart token, except for consecutive digits with possibly a dot. So a simple solution would be iterating over the string, and then when you see a digit that is preceded by another digit (or the decimal separator, a dot), you add the character to the previous token, otherwise add it to a new token.

Here the code:

public static List<String> getTokens(String inputString) {
    List<String> tokens = new ArrayList<String>();
    // Add the first character to a new token. We make the assumption
    // that the string is not empty.
    tokens.add(Character.toString(inputString.charAt(0)));

    // Now iterate over the rest of the characters from the input string.
    for (int i = 1; i < inputString.length(); i++) {
        char ch = inputString.charAt(i); // Store the current character.
        char lch = inputString.charAt(i - 1); // Store the last character.

        // We're checking if the last character is either a digit or the
        // dot, AND if the current character is either a digit or a dot.
        if ((Character.isDigit(ch) || ch == '.') && (Character.isDigit(lch) || lch == '.')) {
            // If so, add the current character to the last token.
            int lastIndex = (tokens.size() - 1);
            tokens.set(lastIndex, tokens.get(lastIndex) + ch);
        }
        else {
            // Otherwise, add the current character to a new token.
            tokens.add(Character.toString(ch));
        }
    }
    return tokens;
}

Note that this method is faster than most regular expression methods.

Sign up to request clarification or add additional context in comments.

Comments

2

You can use regex for parsing a mathamatical expression stored in a string.

expString.split("(?<=[-+*/\\(\\)])|(?=[-+*/\\(\\)])");

will do the trick for you.

Say,

String str = "100+(0.03*55)/45-(25+55)";
String[] outs = str.split("(?<=[-+*/\\(\\)])|(?=[-+*/\\(\\)])");
for (String element : outs)
{
    System.out.println(element);
}

Will give you an output of,

100
+
(
0.03
*
55
)
/
45
-
(
25
+
55
)

Please check my experiment @ http://rextester.com/QEMOYL38160

1 Comment

The output is not correct, [100, +, (0.03, *, 55), /, 45, -, (25, +, 55)]
1

Here's an algorithm I would use:

start with an empty string array, and an empty string buffer

  • walk from character 0 to character n
  • for current character determine type (digit/period, open paren, close paren, math operators)
  • if current character type is same as last character type
  • add current character to buffer
  • if not same, then put buffer into array of string, and start a new buffer

Comments

1

You need to use lookahead and look behind with split.

This works. Ofcourse, improve regex, if you want to include more elements.

public static void main(String[] args) {
    String input = "100+(0.03*55)/45-(25+55)";
    String test[] = input.split("((?<=[\\+\\-\\*\\/\\(\\)\\{\\}\\[\\]])|(?=[\\+\\-\\*\\/\\(\\)\\{\\}\\[\\]]))");
    System.out.println(Arrays.toString(test));
}

Update :

((?<=[a-z]]) , means it will split based on any character and include the character in the splited array as well after element.

(?=[a-z]) , means it will split based on any character and include the character in splited array before each element.

| , is the or operator between two regex.

[\\+\\-\\*\\/\\(\\)\\{\\}\\[\\]]) , is the regex to match to possible combinations

2 Comments

can you please explain how it works, or can you give me the link where i can study how this split function is working??? i have used split function with simple regex but not like that,
@AfzalAshraf Updated
0

Please take a look at the answers to this other question.

This should do the trick:

Pattern p = Pattern.compile("(?:(\\d+)|([+-*/\\(\\)]))");
Matcher m = p.matcher("100+(0.03*55)/45-(25+55)");
List<String> tokens = new LinkedList<String>();
while(m.find())
{
  String token = m.group( 0 ); //group 0 is always the entire match   
  tokens.add(token);
}

1 Comment

With the regex (?:(\\d+)|([+-*/\\(\\)]) the outermost group is not captured, so it starts at group 0. Might improve performance.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.