Open in App
Not now

# Substring Sort

• Last Updated : 25 Mar, 2023

Given n strings, we need to sort those strings such that every string is a substring of all strings after it. If not possible to sort, then print the same.

Examples:

```Input : {"d", "zddsaaz", "ds", "ddsaa", "dds"}
Output :
d
ds
dds
ddsaa
zddsaaz

Input : {"geeks", "ee", "geeksforgeeks", "forgeeks", "ee"}
Output :
ee
ee
geeks
forgeeks
geeksforgeeks```
• Observation 1:
• If A substring of B
• Then length of A <= length of B
• Observation 2:
• If (A substring of B ) and (B substring of C)
• Then A substring of C

Solution:

Based on the two above observations, the solutions is as follows

1. Sort all the string from the shorter to the longer
2. Validate that each string is a substring of the following string

If we validate that each string is a substring of the following string then based on observation 2, each string is a substring of all the strings come after it.

Implementation:

## C++

 `// C++ code to sort substrings` `#include ` `using` `namespace` `std;`   `bool` `compare(string s1, string s2)` `{` `    ``return` `s1.length() < s2.length();` `}`   `void` `substringSort(string arr[], ``int` `n)` `{` `    ``// sort the given array from shorter string to longer` `    ``sort(arr, arr + n, compare); ``// validate that each` `                                 ``// string is a substring of` `    ``// the following one` `    ``for` `(``int` `i = 0; i < n - 1; i++) {` `        ``if` `(arr[i + 1].find(arr[i]) == string::npos) {`   `            ``// the array can't be sorted` `            ``cout << ``"Cannot be sorted"``;` `            ``return``;` `        ``}` `    ``}`   `    ``// The array is valid and sorted` `    ``// print the strings in order` `    ``for` `(``int` `i = 0; i < n-1; i++) {` `        ``cout << arr[i] << endl;` `    ``}` `}`   `int` `main()` `{` `    ``// Test 1` `    ``string arr1[]` `        ``= { ``"d"``, ``"zddsaaz"``, ``"ds"``, ``"ddsaa"``, ``"dds"` `};` `    ``substringSort(arr1,` `                  ``sizeof``(arr1) / ``sizeof``(arr1[0])); ``// Test 2` `    ``string arr2[] = { ``"for"``, ``"rof"` `};` `    ``substringSort(arr2, ``sizeof``(arr2) / ``sizeof``(arr2[0]));`   `    ``return` `0;` `}`

## Java

 `// Java code to sort substrings` `import` `java.util.Arrays;` `import` `java.util.Comparator;`   `public` `class` `Demo {` `    ``public` `static` `void` `substringSort(String[] arr, ``int` `n)` `    ``{` `        ``// sort the given array from shorter string to longer` `        ``Arrays.sort(arr, ``new` `Comparator() {` `            ``public` `int` `compare(String s1, String s2)` `            ``{` `                ``return` `Integer.compare(s1.length(), s2.length());` `            ``}` `        ``});`   `        ``// validate that each string is a substring of` `        ``// the following one'` `        ``for` `(``int` `i = ``0``; i < n - ``1``; i++) {` `            ``if` `(!arr[i + ``1``].contains(arr[i])) {`   `                ``// the array can't be sorted` `                ``System.out.println(``"Cannot be sorted"``);` `                ``return``;` `            ``}` `        ``}`   `        ``// The array is valid and sorted` `        ``// print the strings in order` `        ``for` `(``int` `i = ``0``; i < n - ``1``; i++) {` `            ``System.out.println(arr[i]);` `        ``}` `    ``}`   `    ``public` `static` `void` `main(String[] args)` `    ``{` `        ``// Test 1` `        ``String[] arr1 = { ``"d"``, ``"zddsaaz"``, ``"ds"``, ``"ddsaa"``, ``"dds"` `};` `        ``substringSort(arr1, arr1.length);`   `        ``// Test 2` `        ``String[] arr2 = { ``"for"``, ``"rof"` `};` `        ``substringSort(arr2, arr2.length);` `    ``}` `}`

## Python3

 `# Python code to sort substrings` `import` `functools`   `def` `substringSort(arr, n):` `    ``# sort the given array from shorter string to longer` `    ``arr.sort(key``=``len``)` `    `  `    ``# validate that each string is a substring of` `    ``# the following one` `    ``for` `i ``in` `range``(n ``-` `1``):` `        ``if` `not` `arr[i ``+` `1``].find(arr[i]) !``=` `-``1``:` `            ``# the array cannot be sorted` `            ``print``(``"Cannot be sorted"``)` `            ``return`   `    ``# the array is valid and sorted` `    ``# print the strings in order` `    ``for` `i ``in` `range``(n ``-` `1``):` `        ``print``(arr[i])`   `# Test 1` `arr1 ``=` `[``"d"``, ``"zddsaaz"``, ``"ds"``, ``"ddsaa"``, ``"dds"``]` `substringSort(arr1, ``len``(arr1))`   `# Test 2` `arr2 ``=` `[``"for"``, ``"rof"``]` `substringSort(arr2, ``len``(arr2))`

## C#

 `using` `System;` `using` `System.Linq;`   `public` `class` `Demo` `{` `    ``public` `static` `void` `SubstringSort(``string``[] arr, ``int` `n)` `    ``{` `        ``// sort the given array from shorter string to longer` `        ``Array.Sort(arr, (s1, s2) => s1.Length.CompareTo(s2.Length));`   `        ``// validate that each string is a substring of` `        ``// the following one'` `        ``for` `(``int` `i = 0; i < n - 1; i++)` `        ``{` `            ``if` `(!arr[i + 1].Contains(arr[i]))` `            ``{` `                ``// the array can't be sorted` `                ``Console.WriteLine(``"Cannot be sorted"``);` `                ``return``;` `            ``}` `        ``}`   `        ``// The array is valid and sorted` `        ``// print the strings in order` `        ``for` `(``int` `i = 0; i < n - 1; i++)` `        ``{` `            ``Console.WriteLine(arr[i]);` `        ``}` `    ``}`   `    ``public` `static` `void` `Main(``string``[] args)` `    ``{` `        ``// Test 1` `        ``string``[] arr1 = { ``"d"``, ``"zddsaaz"``, ``"ds"``, ``"ddsaa"``, ``"dds"` `};` `        ``SubstringSort(arr1, arr1.Length);`   `        ``// Test 2` `        ``string``[] arr2 = { ``"for"``, ``"rof"` `};` `        ``SubstringSort(arr2, arr2.Length);` `    ``}` `}`

## Javascript

 `// JavaScript code to sort substrings` `function` `substringSort(arr, n) {` `    ``// sort the given array from shorter string to longer` `    ``arr.sort(``function``(s1, s2) {` `    ``return` `s1.length - s2.length;` `    ``});`   `    ``// validate that each string is a substring of` `    ``// the following one` `        ``for` `(let i = 0; i < n - 1; i++) {` `        ``if` `(!arr[i + 1].includes(arr[i])) {`   `      ``// the array can't be sorted` `      ``console.log(``"Cannot be sorted"``);` `      ``return``;` `    ``}`   `    ``}`   `    ``// The array is valid and sorted` `    ``// print the strings in order` `    ``for` `(let i = 0; i < n - 1; i++) {` `    ``console.log(arr[i]);` `    ``}` `}`   `// Test 1` `let arr1 = [``"d"``, ``"zddsaaz"``, ``"ds"``, ``"ddsaa"``, ``"dds"``];` `substringSort(arr1, arr1.length);`   `// Test 2` `let arr2 = [``"for"``, ``"rof"``];` `substringSort(arr2, arr2.length);`

Output

```d
ds
dds
ddsaa
Cannot be sorted
```

Time Complexity: O(n log n), where n is the number of strings.

Alternative approach:

For better time complexity, we can use counting sort only if the maximum length of the strings is specified.

Suppose that ‘maxLen’ is the maximum length of the input strings. In this case, the solution is as follows:

1. Create array of length maxLen
2. Sort the input strings such that the string with length 1 is in the first place in the array
3. If there is two or more string has the same length they must be equal otherwise the strings cannot be sorted
4. Validate that each string is a substring of the next longer string

Implementation:

## C++

 `// C++ Program to sort substrings` `#include ` `using` `namespace` `std;`   `void` `substringSort(string arr[], ``int` `n, ``int` `maxLen)` `{`   `    ``int` `count[maxLen];` `    ``string sortedArr[maxLen];` `    ``for``(``int` `i = 0; i < maxLen; i++)` `    ``{` `        ``count[i] = 0;` `        ``sortedArr[i] = ``""``;` `    ``}`   `    ``// sort the input array` `    ``for` `(``int` `i = 0; i < n; i++)` `    ``{`   `        ``string s = arr[i];` `        ``int` `len = s.length();`   `        ``if` `(count[len - 1] == 0)` `        ``{` `            ``sortedArr[len - 1] = s;` `            ``count[len - 1] = 1;` `        ``}` `        ``else` `if` `(sortedArr[len - 1] == s)` `        ``{`   `            ``// repeated length should` `            ``// be the same string` `            ``count[len - 1]++;` `        ``}` `        ``else` `        ``{`   `            ``// two different strings with the same` `            ``// length input array cannot be sorted` `            ``cout << ``"Cannot be sorted"``;` `            ``return``;` `        ``}` `    ``}`   `    ``// validate that each string is a ` `    ``// substring of the following one` `    ``int` `index = 0;`   `    ``// get first element` `    ``while` `(count[index] == 0)` `        ``index++;`   `    ``int` `prev = index;` `    ``string prevString = sortedArr[prev];`   `    ``index++;`   `    ``for` `(; index < maxLen; index++)` `    ``{`   `        ``if` `(count[index] != 0)` `        ``{` `            ``string current = sortedArr[index];` `            ``if` `(current.find(prevString) != string::npos)` `            ``{` `                ``prev = index;` `                ``prevString = current;` `            ``}` `            ``else` `            ``{` `                ``cout << ``"Cannot be sorted"``;` `                ``return``;` `            ``}` `        ``}` `    ``}`   `    ``// The array is valid and sorted` `    ``// print the strings in order` `    ``for` `(``int` `i = 0; i < maxLen; i++)` `    ``{` `        ``string s = sortedArr[i];` `        ``for` `(``int` `j = 0; j < count[i]; j++)` `        ``{` `            ``cout << s << endl;` `        ``}` `    ``}` `}`   `// Driver code` `int` `main()` `{` `    ``int` `maxLen = 100;` ` `  `    ``// Test 1` `    ``string arr1[] = { ``"d"``, ``"zddsaaz"``, ``"ds"``, ``"ddsaa"``,` `                                   ``"dds"``, ``"dds"` `};` `    ``substringSort(arr1, ``sizeof``(arr1)/``sizeof``(arr1[0]), maxLen);`   `    ``// Test 2` `    ``string arr2[] = { ``"for"``, ``"rof"` `};` `    ``substringSort(arr2, ``sizeof``(arr2)/``sizeof``(arr2[0]), maxLen);`   `    ``return` `0;` `}`   `// This code is contributed by rameshtravel07.`

## Java

 `// Alternative code to sort substrings` `import` `java.util.Arrays;`   `public` `class` `Demo {`   `    ``public` `static` `void` `substringSort(String[] arr, ``int` `n, ``int` `maxLen)` `    ``{`   `        ``int` `count[] = ``new` `int``[maxLen];` `        ``String[] sortedArr = ``new` `String[maxLen];`   `        ``Arrays.fill(count, ``0``);` `        ``Arrays.fill(sortedArr, ``""``);`   `        ``// sort the input array` `        ``for` `(``int` `i = ``0``; i < n; i++) {`   `            ``String s = arr[i];` `            ``int` `len = s.length();`   `            ``if` `(count[len - ``1``] == ``0``) {` `                ``sortedArr[len - ``1``] = s;` `                ``count[len - ``1``] = ``1``;` `            ``}` `            ``else` `if` `(sortedArr[len - ``1``].equals(s)) {`   `                ``// repeated length should be the same string` `                ``count[len - ``1``]++;` `            ``}` `            ``else` `{`   `                ``// two different strings with the same ` `                ``// length input array cannot be sorted` `                ``System.out.println(``"Cannot be sorted"``);` `                ``return``;` `            ``}` `        ``}`   `        ``// validate that each string is a substring ` `        ``// of the following one` `        ``int` `index = ``0``;`   `        ``// get first element` `        ``while` `(count[index] == ``0``)` `            ``index++;`   `        ``int` `prev = index;` `        ``String prevString = sortedArr[prev];`   `        ``index++;`   `        ``for` `(; index < maxLen; index++) {`   `            ``if` `(count[index] != ``0``) {` `                ``String current = sortedArr[index];` `                ``if` `(current.contains(prevString)) {` `                    ``prev = index;` `                    ``prevString = current;` `                ``}` `                ``else` `{` `                    ``System.out.println(``"Cannot be sorted"``);` `                    ``return``;` `                ``}` `            ``}` `        ``}`   `        ``// The array is valid and sorted` `        ``// print the strings in order` `        ``for` `(``int` `i = ``0``; i < maxLen; i++) {` `            ``String s = sortedArr[i];` `            ``for` `(``int` `j = ``0``; j < count[i]; j++) {` `                ``System.out.println(s);` `            ``}` `        ``}` `    ``}`   `    ``public` `static` `void` `main(String[] args)` `    ``{` `        ``int` `maxLen = ``100``;`   `        ``// Test 1` `        ``String[] arr1 = { ``"d"``, ``"zddsaaz"``, ``"ds"``, ``"ddsaa"``, ` `                                       ``"dds"``, ``"dds"` `};` `        ``substringSort(arr1, arr1.length, maxLen);`   `        ``// Test 2` `        ``String[] arr2 = { ``"for"``, ``"rof"` `};` `        ``substringSort(arr2, arr2.length, maxLen);` `    ``}` `}`

## Python3

 `# Alternative code to sort substrings` `def` `substringSort(arr, n, maxLen):`   `    ``count ``=` `[``0``]``*``(maxLen)` `    ``sortedArr ``=` `[""]``*``(maxLen)`   `    ``# sort the input array` `    ``for` `i ``in` `range``(n):`   `        ``s ``=` `arr[i]` `        ``Len` `=` `len``(s)`   `        ``if` `(count[``Len` `-` `1``] ``=``=` `0``) :` `            ``sortedArr[``Len` `-` `1``] ``=` `s` `            ``count[``Len` `-` `1``] ``=` `1` `        ``elif` `(sortedArr[``Len` `-` `1``] ``=``=` `s):` `            ``# repeated length should be the same string` `            ``count[``Len` `-` `1``]``+``=``1` `        ``else``:` `            ``# two different strings with the same` `            ``# length input array cannot be sorted` `            ``print``(``"Cannot be sorted"``)` `            ``return`   `    ``# validate that each string is a substring` `    ``# of the following one` `    ``index ``=` `0`   `    ``# get first element` `    ``while` `(count[index] ``=``=` `0``):` `        ``index``+``=``1`   `    ``prev ``=` `index` `    ``prevString ``=` `sortedArr[prev]`   `    ``index``+``=``1` `    `  `    ``while` `index < maxLen:` `        ``if` `(count[index] !``=` `0``) :` `            ``current ``=` `sortedArr[index]` `            ``if` `(prevString ``in` `current):` `                ``prev ``=` `index` `                ``prevString ``=` `current` `            ``else``:` `                ``print``(``"Cannot be sorted"``)` `                ``return` `        ``index``+``=``1`   `    ``# The array is valid and sorted` `    ``# print the strings in order` `    ``for` `i ``in` `range``(maxLen):` `        ``s ``=` `sortedArr[i]` `        ``for` `j ``in` `range``(count[i]):` `            ``print``(s)`   `maxLen ``=` `100` `  `  `# Test 1` `arr1 ``=` `[ ``"d"``, ``"zddsaaz"``, ``"ds"``, ``"ddsaa"``, ``"dds"``, ``"dds"` `]` `substringSort(arr1, ``len``(arr1), maxLen)`   `# Test 2` `arr2 ``=` `[ ``"for"``, ``"rof"` `]` `substringSort(arr2, ``len``(arr2), maxLen)`   `# This code is contributed by mukesh07.`

## C#

 `// C# Program to sort substrings` `using` `System;`   `class` `GFG` `{`   `    ``public` `static` `void` `substringSort(String[] arr,` `                                ``int` `n, ``int` `maxLen)` `    ``{`   `        ``int` `[]count = ``new` `int``[maxLen];` `        ``String[] sortedArr = ``new` `String[maxLen];` `        ``for``(``int` `i = 0; i < maxLen; i++)` `        ``{` `            ``count[i] = 0;` `            ``sortedArr[i] = ``""``;`   `        ``}`   `        ``// sort the input array` `        ``for` `(``int` `i = 0; i < n; i++) ` `        ``{`   `            ``String s = arr[i];` `            ``int` `len = s.Length;`   `            ``if` `(count[len - 1] == 0)` `            ``{` `                ``sortedArr[len - 1] = s;` `                ``count[len - 1] = 1;` `            ``}` `            ``else` `if` `(ReferenceEquals(s,sortedArr[len - 1]))` `            ``{`   `                ``// repeated length should ` `                ``// be the same string` `                ``count[len - 1]++;` `            ``}` `            ``else` `            ``{`   `                ``// two different strings with the same ` `                ``// length input array cannot be sorted` `                ``Console.WriteLine(``"Cannot be sorted"``);` `                ``return``;` `            ``}` `        ``}`   `        ``// validate that each string is a  ` `        ``// substring of the following one` `        ``int` `index = 0;`   `        ``// get first element` `        ``while` `(count[index] == 0)` `            ``index++;`   `        ``int` `prev = index;` `        ``String prevString = sortedArr[prev];`   `        ``index++;`   `        ``for` `(; index < maxLen; index++) ` `        ``{`   `            ``if` `(count[index] != 0) ` `            ``{` `                ``String current = sortedArr[index];` `                ``if` `(current.Contains(prevString)) ` `                ``{` `                    ``prev = index;` `                    ``prevString = current;` `                ``}` `                ``else` `                ``{` `                    ``Console.WriteLine(``"Cannot be sorted"``);` `                    ``return``;` `                ``}` `            ``}` `        ``}`   `        ``// The array is valid and sorted` `        ``// print the strings in order` `        ``for` `(``int` `i = 0; i < maxLen; i++) ` `        ``{` `            ``String s = sortedArr[i];` `            ``for` `(``int` `j = 0; j < count[i]; j++)` `            ``{` `                ``Console.WriteLine(s);` `            ``}` `        ``}` `    ``}`   `    ``public` `static` `void` `Main(String[] args)` `    ``{` `        ``int` `maxLen = 100;`   `        ``// Test 1` `        ``String[] arr1 = { ``"d"``, ``"zddsaaz"``, ``"ds"``, ``"ddsaa"``, ` `                                    ``"dds"``, ``"dds"` `};` `        ``substringSort(arr1, arr1.Length, maxLen);`   `        ``// Test 2` `        ``String[] arr2 = { ``"for"``, ``"rof"` `};` `        ``substringSort(arr2, arr2.Length, maxLen);` `    ``}` `}`   `// This code is contributed by PrinciRaj1992`

## Javascript

 ``

Output

```d
ds
dds
dds
ddsaa
zddsaaz
Cannot be sorted```

My Personal Notes arrow_drop_up
Related Articles