简体   繁体   中英

How to Split a mathematical expression on operators as delimiters, while keeping them in the result?

I need to split an expression like

a+b-c*d/e 

and get a , b , c , d , e seperately(as array of strings) as well as = , - , * , d , / (also an array of operators) separately. I have tried like:

String myString;

String myString={"a+b-c*d/e");

String[] result=new String();

String[] separator=new String[]{"+","-","/","*"};

result=myString.split(separator);

But, it shows an error. How to solve it?

1st problem: -

Multiple declaration of String myString;

2nd problem: -

String initialized incorrectly. Double quotes missing at the ends. Remove bracket and brace from the ends.

String myString = "a+b-c*d/e";

3rd problem: -

String array initialized with an String object, rather than an array object.

String[] result=new String();  // Should be `new String[size]`

In fact, you don't need to initialize your array before hand.

4th problem: -

String.split takes a Regular Expression as argument, you have passed an array. Will not work.

Use: -

String[] result = myString.split("[-+*/]");

to split on all the operators.


And regarding your this statement: -

as well as =, -, *, d, / (also an array of operators) separately.

I don't understand what you want here. Your sample string does not contains = . And d is not an operator . Please see if you want to edit it.

UPDATE : -

If you mean to keep the operators as well in your array, you can use this regex: -

String myString= "a+b-c*d/e";
String[] result = myString.split("(?<=[-+*/])|(?=[-+*/])");
System.out.println(Arrays.toString(result));

/*** Just to see, what the two parts in the above regex print separately ***/
System.out.println(Arrays.toString(myString.split("(?<=[-+*/])")));
System.out.println(Arrays.toString(myString.split("(?=[-+*/])")));

OUTPUT : -

[a, +, b, -, c, *, d, /, e]
[a+, b-, c*, d/, e]
[a, +b, -c, *d, /e]

(?<=...) means look-behind assertion , and (?=...) means look-ahead assertion .

Besides the split approach, you could also use java.util.StringTokenizer :

 String myString = "a+b-c*d/e";

 List<String> operatorList = new ArrayList<String>();
 List<String> operandList = new ArrayList<String>();
 StringTokenizer st = new StringTokenizer(myString, "+-*/", true);
 while (st.hasMoreTokens()) {
    String token = st.nextToken();

    if ("+-/*".contains(token)) {
       operatorList.add(token);
    } else {
       operandList.add(token);
    }
 }

 System.out.println("Operators:" + operatorList);
 System.out.println("Operands:" + operandList);

Result:

Operators:[+, -, *, /]
Operands:[a, b, c, d, e]

Just to get the a/b/c/d/e:

String myString = "a+b-c*d/e";
String[] result=myString.split("[-+*/]");

In a more readable form:

String myString = "a+b-c*d/e";
String[] result2=myString.split("["+Pattern.quote("+-*/")+"]");

To get the +-*/:

ArrayList<Character> list = new ArrayList<Character>();
for (char c:myString.toCharArray())
{
   if ("+-*/".contains(""+c)) list.add(c);
}
System.out.println(list);

Edit: removed unneeded escape characters.

As far as I know you cannot do what you are after right out of the box. The split(String regex) does not take an entire array (unlike C#), just a string representing a valid regular expression.

What you could do would be to define a Set which contains your operators and 2 ArrayLists . Once you have that, you iterate over your string, check if the set contains that given character (thus determining if it is an operator or not). If it is, then, you put it in one list, if not, you put it in the other.

Finally, you can then use toArray(new String\\[arraySize\\]) to get back your ArrayLists as String arrays.

I think what you want to do, is more like a parser, rather than a tokenizer.

With a string tokenizer, you usually have a long string (ie "parameter1;parameter2;parameter3") with several elements concatenated, and using a "token" to separate these elements. With function "String.split", you are basically saying: "Ok, give all elements from this string, but taking into account that character ';' separates different elements". And then you get "parameter1", "parameter2", "parameter3". You do not care about separators.

But in a mathematical expression like yours: "a+bc*d/e", you want to get all the individual elements (operands and operators). Here there are no explicit separators, and the order is also important for you. I would use a parser library and write a small grammar instead.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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