Marek
Marek

Reputation: 245

expression in string to arraylist

I'm a beginner to java and programming. I have a string s="(((1+2))-((5+6))-((10+20))-((6-18))+((9+10)))" I would like to put it into a list or array.

Something like this,

[(, (, (, 1, +, 2, ), ), -, (, (, 5, +, 6, ), ), -, (, (, 10, +, 20, ), ), -, (, (, 6, -, 18, ), ), _, (, (, 9, +, 10, ), ), )]

Upon executing

char[] a = String.valueOf("(((1+2))-((5+6))-((10+20))-((6-18))+((9+10)))").toCharArray();

result is

[(, (, (, 1, +, 2, ), ), -, (, (, 5, +, 6, ), ), -, (, (, 1, 0, +, 2, 0, ), ), -, (, (, 6, -, 1, 8, ), ), +, (, (, 9, +, 1, 0, ), ), )]

please note that 10 is coming as 1 and 0

EDIT:

I would like to put it into a list of string

Something like this,

List<String> ls = [(, (, (, 1, +, 2, ), ), -, (, (, 5, +, 6, ), ), -, (, (, 10, +, 20, ), ), -, (, (, 6, -, 18, ), ), _, (, (, 9, +, 10, ), ), )]

Could somebody tell me how I can do it?

Upvotes: 1

Views: 315

Answers (2)

Oleg Cherednik
Oleg Cherednik

Reputation: 18245

As alternative, I offer a solution without using regular expression:

public static List<String> split(String str) {
    List<String> res = new ArrayList<>();
    StringBuilder buf = null;

    for (int i = 0; i < str.length(); i++) {
        char ch = str.charAt(i);

        if (ch >= '0' && ch <= '9') {
            if (buf == null)
                buf = new StringBuilder();
            buf.append(ch);
        } else {
            if (buf != null) {
                res.add(buf.toString());
                buf = null;
            }
            res.add(String.valueOf(ch));
        }
    }

    if (buf != null)
        res.add(buf.toString());

    return Collections.unmodifiableList(res);
}

Upvotes: 1

xingbin
xingbin

Reputation: 28279

Since the question is limited in positive numbers:

  • first way:

    Use regex to find every string group which matches ( or ) or + or - or * or \ or at least one number character.

  • second way:

    Use String.split() and regex lookaround to split the string when

    • ahead is not number, behind is not number
    • or ahead is number, behind is not number
    • or ahead is not number, behind is number
  • third way:

    Iterate on characters.

    • If it is a not digit, put into the list.
    • Else, loop to get a complete number.

Code example:

public static void main(String[] args) {
    String example = "(((1+2))-((5+6))-((10+20))-((6-18))+((9+10)))";


    List<String> firstList = new ArrayList<>();
    Pattern pattern = Pattern.compile("\\(|\\)|\\+|\\-|\\*|\\\\|\\d+"); // the back slashes are used for escaping
    Matcher matcher = pattern.matcher(example);
    while (matcher.find()) {
        firstList.add(matcher.group());
    }

    // second way:
    List<String> secondList = Arrays.asList(
            example.split("(?<!\\d)(?!\\d)|(?<=\\d)(?!\\d)|(?<!\\d)(?=\\d)"));

    // third way
    List<String> thirdList = new ArrayList<>();
    char[] chars = example.toCharArray();
    for (int index = 0; index < chars.length; ) {
        if (!Character.isDigit(chars[index])) {
            thirdList.add(String.valueOf(chars[index])); // put into list if not digit
            index++;
        } else {
            StringBuilder stringBuilder = new StringBuilder();
            while (Character.isDigit(chars[index])) {  // loop to get a complete number
                stringBuilder.append(chars[index]);
                index++;
            }
            thirdList.add(stringBuilder.toString());
        }
    }
}

Upvotes: 2

Related Questions