Split String based on Shrinking Sliding Window/ 2D array

Junaid388 :

I am trying to create fragments of A string on multiple delimiters. For Example I have the following String.

Chronic Lymphocytic Leukemia :: Small Lymphocytic Lymphoma

I need to split the String first based on this delimiter ::

That part is easy.

The from each of the substrings(Term) I need to generate fragments based on the following rule

A term composed of words A, B and C, i.e., 'A B C' is fragmented into 'A B C' (0), 'A B' (1), 'B C' (2), 'A' (3), 'B' (4), 'C' (5)

A term length is not fixed. It can be three words or more or less.

logic is that each word in the term should only be concatenated to next words in the array in a shrinking window logic. So first word is A and it has B C after it. So combination will be A B C. then window shrinks from right to left so next Combo will be A B and next will be C.

FOR so in case of a term A B C D the output fragments will be

'A B C D'
'A B C',
'A B',
'A',
'B C D',
'B C',
'B',
'C D',
'C',
'D'

and in case of a term A B C D E the output fragments will be

'A B C D E','A B C D', 'A B C', 'A B','A', 'B C D E','B C D', 'B C,'B','C D E','C D','C','D E','D','E'

In the above "Chronic Lymphocytic Leukemia" and "Small Lymphocytic Lymphoma" are two terms.

The output for Chronic Lymphocytic Leukemia I need is

Chronic Lymphocytic Leukemia
Chronic Lymphocytic
Chronic
Lymphocytic Leukemia
Lymphocytic
Leukemia

I am trying to split this into a 2D array and then iterate through them and try to concatenate them but I am hitting a road block

String str="Chronic Lymphocytic Leukemia :: Small Lymphocytic Lymphoma";
String[] rows=str.split("::");
String[][] table=new String[rows.length][];
for (int i=0; i<rows.length;i++)
  {
     table[i]=rows[i].split(" ");
  }

for (int i=0;i<table.length;i++)
  {
    for(int j=0;j<table[i].length;j++)
      {
        System.out.println(table[i][j]);
      }
  }

Any ideas how I can achieve this

user85421 :

Almost straight-forward:

  • a loop that selects the first word;
  • a second loop inside the first one that selects the final word, going backwards.
  • inside that loop you just need to join the words an add to the result

Something like:

List<String> fragments(String[] words) {
    var result = new ArrayList<String>();
    for (var i = 0; i < words.length; i++) {
        for (var j = words.length; j > i; j--) {
            result.add(Arrays.stream(words, i, j).collect(Collectors.joining(" ")));
        }
    }
    // result.remove(0);  // if you don't want the whole sequence inside the result
    return result;
}

If, for some reason, stream is not an option, a third loop is needed to collect the words:

List<String> fragments(String[] words) {
    var result = new ArrayList<String>();
    for (var i = 0; i < words.length; i++) {
        for (var j = words.length; j > i; j--) {
            var fragment = new StringBuilder();
            for (var k = i; k < j; k++) {
                if (k > i) {
                    fragment.append(" ");
                }
                fragment.append(words[k]);
            }
            result.add(fragment.toString());
        }
    }
    // result.remove(0);  // if you dont want the whole sequence inside the result
    return result;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=131286&siteId=1