0

Here is an example String, which contains 2 delimiters used for parsing the String to integers:

"1,25,3-6,14,16-19"

The integers in the aforementioned string have to be parsed and added to ArrayList cotaining integers. So the ArrayList has to contain:

1,3,4,5,6,14,16,17,18,19,25

The values in the original string are never mentioned twice. So, there are no crossing sections. Below you can see the incomplete code I wrote so far, but I think that I'm going in a completely wrong direction and there should be an easier way to solve the parsing.

List<Integer> temp = new ArrayList<>();
Scanner s = new Scanner(System.in);
String str = s.nextLine();
char[] strCh = str.toCharArray();
for (int j = 0; j < strCh.length; j++) {
    char c = strCh[j];
    String number = "";
    char operator = 'n';
    if (Character.isDigit(c)) {
        do {
            number += c;
            j++;
            if (j != strCh.length - 1)
                c = strCh[j];
           } while (j < strCh.length && Character.isDigit(c));
    } else if (c == ',') {
        operator = ',';
        temp.add(Integer.parseInt(number));
        number = "";
    } else if (c == '-') {
        //still not sure
    }
}
Little Man
  • 11
  • 1
  • Read up on the `split` method of the `String` class. You'll need to call it twice. – Dawood ibn Kareem Jun 05 '17 at 01:07
  • Consider using a [Set](https://docs.oracle.com/javase/7/docs/api/java/util/Set.html) they will prevent duplicates from being added. Also consider using `split (",")` to split your String into individual elements – Scary Wombat Jun 05 '17 at 01:08
  • You can also use regex. – tsolakp Jun 05 '17 at 01:12
  • This issue arised when I was parsing the input for a problem from programming contest, so there were no need for sanity checks, because the constraints were well defined. Thank you for your advises! Would be also nice to hear the reason of the downvote. Thanks! – Little Man Jun 05 '17 at 01:52

4 Answers4

3

You can use String#split() twice to handle your input string. First split by comma, which leaves us with either an individual number, or an individual range of numbers. Then, in the case of range, split again by dash to obtain the starting and ending numbers of that range. We can iterate over that range, adding each number to our list.

String input = "1,25,3-6,14,16-19";
String[] parts = input.split(",");
List<Integer> list = new ArrayList<>();

for (String part : parts) {
    if (part.contains("-")) {
        String[] range = part.split("-");
        int start = Integer.parseInt(range[0]);
        int end = Integer.parseInt(range[1]);

        for (int i=start; i <= end; ++i) {
            list.add(i);
        }
    }
    else {
        int value = Integer.parseInt(part);
        list.add(value);
    }
}

This generated the following list of numbers:

1,25,3,4,5,6,14,16,17,18,19

Demo here:

Rextester

Tim Biegeleisen
  • 387,723
  • 20
  • 200
  • 263
3

To ensure there are no duplicates and in order as you expect, use Set:

    String inputData = "1,25,3-6,14,16-19";
    String[] numberRanges = inputData.split(",");
    Set<Integer> set = new TreeSet<>();

    for (String numberRange : numberRanges) {
        if (numberRange.contains("-")) {
            String[] range = numberRange.split("-");
            int startIndex = Integer.valueOf(range[0]);
            int endIndex = Integer.valueOf(range[1]);
            for (int i = startIndex; i <= endIndex; ++i) {
                set.add(i);
            }
        } else {
            set.add(Integer.valueOf(numberRange));
        }
    }
    System.out.println(set);
YuVi
  • 966
  • 7
  • 12
  • 1
    Originally I wrote a similar answer, but then noticed the OP said *The values in the original string are never mentioned twice. So, there are no crossing sections* – Scary Wombat Jun 05 '17 at 01:31
  • @Scary True, but using a `TreeSet` gives you sorting for free, rather than having to sort explicitly as per Yahya's answer. – Dawood ibn Kareem Jun 05 '17 at 01:40
  • @DawoodibnKareem It depends on what you want to achieve. if you're mainly retrieving, and don't sort often, `ArrayList` is the better choice. If you sort often but don't retrieve that much `TreeSet` would be a better choice. Added to that, theoretically, sorting at the end should be faster. Maintaining sorted state through the process could involve additional CPU time. – Yahya Jun 05 '17 at 01:51
1

You can try something like this:

String input = "1,25,3-6,14,16-19";

List<Integer> output = new ArrayList<Integer>();

for(String s : input.split(",")){
    try{
        if(!s.contains("-")){
           output.add(Integer.parseInt(s));
        }
        else{
            int i= Integer.parseInt(s.split("-")[0]);
            int upperBound = Integer.parseInt(s.split("-")[1]);
            for(;i<=upperBound;i++){
                 output.add(i);
            }
        }   
    }catch(NumberFormatException e){
            e.printStackTrace();
    }
}
Collections.sort(output); // sort the result
System.out.println(output); // test

Output

[1, 3, 4, 5, 14, 16, 17, 18, 19, 25]
Yahya
  • 9,370
  • 4
  • 26
  • 43
-2

Take a look at the StringTokenizer.

Igor F.
  • 2,434
  • 2
  • 28
  • 37
  • @ Dawood: Do what? – Igor F. Jun 05 '17 at 01:10
  • From the Javadoc that you linked to. _"...StringTokenizer is a legacy class that is retained for compatibility reasons although its use is discouraged in new code. It is recommended that anyone seeking this functionality use the split method of String or the java.util.regex package instead..."_ In other words, **don't** use `StringTokenizer` for this. Use the `split` method as per Tim Biegeleisen's answer, or something like it. – Dawood ibn Kareem Jun 05 '17 at 01:12
  • There might be reasons for and against: https://stackoverflow.com/questions/691184/scanner-vs-stringtokenizer-vs-string-split – Igor F. Jun 05 '17 at 01:19
  • There might be reasons for and against using the tokenising functionality of the `Scanner` class, as opposed to using `split`. But as per Michael Myers' answer on the question you linked to, there's never a reason to use `StringTokenizer`. When the makers of Java have said you shouldn't use something, it's worth listening to them. – Dawood ibn Kareem Jun 05 '17 at 01:37