0

I wanted to substring a String depending on int that I will passed on the method. I used nested loop for this. But everytime it loops I wanted to substring only from last substring to int the I passed in the method and get also the last string. How can I achieve this?

private static void input(String s, int I)
{
    List list = new ArrayList();

    for(int a = 0; a < s.length(); a++)
    {
        for(int position = 0; position < s.length(); position++)
        {
            if(position + a + I <= s.length())
            {
                list.add(s.substring(position, position + a + I));
            }
        }
    }

}

input("abaca", 2);

Expected output: "ab", "ac", "a"

Francisunoxx
  • 1,440
  • 3
  • 22
  • 45
  • in other words: you want to slice the input string into pieces of a length passed in? `input("abaca", 2)` does mean: slice "abaca" into substrings of length 2? – Harmlezz Jun 08 '17 at 07:54
  • @Harmlezz Yes exactly like that. – Francisunoxx Jun 08 '17 at 07:54
  • See link below: [Stackoverflow topic](https://stackoverflow.com/questions/9276639/java-how-to-split-a-string-by-a-number-of-characters) – sf_ Jun 08 '17 at 07:56
  • A) dont use raw types B) dont use single character variable names. Names should tell the reader something about the purpose of the thing behind it. Your code is 10 times harder to understand, just for lazy naming. – GhostCat Jun 08 '17 at 07:56
  • @Oleg Estekhin duplicate? maybe, but look at the answer here to do it using regex one-liner! The old question wouldn't get attention to get such new brilliant answer! What about if over time there are new ways to do same things? How to improve, or somehow renew (to get new answers) such old questions on SO? Or maybe we should ask new? – Krzysztof Cichocki Jun 08 '17 at 08:55
  • @krzysztof-cichocki that "regex one-liner" is taken from https://stackoverflow.com/questions/2297347/splitting-a-string-at-every-n-th-character which is another candidate for duplicate – Oleg Estekhin Jun 08 '17 at 09:53

3 Answers3

2

You don't need nested loops. Just iterate over the String once, and add an I character substring in each iteration.

Note that a is the starting index of the current substring, and it therefore incremented by I in each iteration.

The last substring may have a shorter length. If a + I > s.length(), the last index of the last substring will be s.length() - 1 instead of a + I - 1.

for(int a = 0; a < s.length(); a+=I) {
    list.add(s.substring(a, Math.min(a + I, s.length())));
}

This produces

[ab, ac, a]

for input("abaca", 2).

Eran
  • 387,369
  • 54
  • 702
  • 768
2

You can also simply split the string:

private static void input(String s, int i){
    List list = Arrays.asList(s.split("(?<=\\G.{"+i+"})"));
    System.out.println(list);
}

\\G means The end of the previous match

?<= means positive lookbehind

Thanks to positive lookbehind (?<=) it will split on all zero length strings (without cutting off anything from the input string) preceded by where previous match ends (\\G) followed by i signs (.{"+i+"}).

Krzysztof Cichocki
  • 6,294
  • 1
  • 16
  • 32
Grisha Weintraub
  • 7,803
  • 1
  • 25
  • 45
0

It's really better to completely rewrite your code, but if you want to save your structure(even though it's not correct), just remove 1 loop and do something like this:

private static void input(String s, int I) {
    List list = new ArrayList();

    for (int position = 0; position < s.length();position += I) {
        if (position + I <= s.length()) {
            list.add(s.substring(position, position + I));
        } else {
            list.add(s.substring(position, s.length()));
            return;
        }
    }
}
Max
  • 766
  • 9
  • 19