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
- Sort all the string from the shorter to the longer
- 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++
#include <bits/stdc++.h>
using namespace std;
bool compare(string s1, string s2)
{
return s1.length() < s2.length();
}
void substringSort(string arr[], int n)
{
sort(arr, arr + n, compare);
for ( int i = 0; i < n - 1; i++) {
if (arr[i + 1].find(arr[i]) == string::npos) {
cout << "Cannot be sorted" ;
return ;
}
}
for ( int i = 0; i < n-1; i++) {
cout << arr[i] << endl;
}
}
int main()
{
string arr1[]
= { "d" , "zddsaaz" , "ds" , "ddsaa" , "dds" };
substringSort(arr1,
sizeof (arr1) / sizeof (arr1[0]));
string arr2[] = { "for" , "rof" };
substringSort(arr2, sizeof (arr2) / sizeof (arr2[0]));
return 0;
}
|
Java
import java.util.Arrays;
import java.util.Comparator;
public class Demo {
public static void substringSort(String[] arr, int n)
{
Arrays.sort(arr, new Comparator<String>() {
public int compare(String s1, String s2)
{
return Integer.compare(s1.length(), s2.length());
}
});
for ( int i = 0 ; i < n - 1 ; i++) {
if (!arr[i + 1 ].contains(arr[i])) {
System.out.println( "Cannot be sorted" );
return ;
}
}
for ( int i = 0 ; i < n - 1 ; i++) {
System.out.println(arr[i]);
}
}
public static void main(String[] args)
{
String[] arr1 = { "d" , "zddsaaz" , "ds" , "ddsaa" , "dds" };
substringSort(arr1, arr1.length);
String[] arr2 = { "for" , "rof" };
substringSort(arr2, arr2.length);
}
}
|
Python3
import functools
def substringSort(arr, n):
arr.sort(key = len )
for i in range (n - 1 ):
if not arr[i + 1 ].find(arr[i]) ! = - 1 :
print ( "Cannot be sorted" )
return
for i in range (n - 1 ):
print (arr[i])
arr1 = [ "d" , "zddsaaz" , "ds" , "ddsaa" , "dds" ]
substringSort(arr1, len (arr1))
arr2 = [ "for" , "rof" ]
substringSort(arr2, len (arr2))
|
C#
using System;
using System.Linq;
public class Demo
{
public static void SubstringSort( string [] arr, int n)
{
Array.Sort(arr, (s1, s2) => s1.Length.CompareTo(s2.Length));
for ( int i = 0; i < n - 1; i++)
{
if (!arr[i + 1].Contains(arr[i]))
{
Console.WriteLine( "Cannot be sorted" );
return ;
}
}
for ( int i = 0; i < n - 1; i++)
{
Console.WriteLine(arr[i]);
}
}
public static void Main( string [] args)
{
string [] arr1 = { "d" , "zddsaaz" , "ds" , "ddsaa" , "dds" };
SubstringSort(arr1, arr1.Length);
string [] arr2 = { "for" , "rof" };
SubstringSort(arr2, arr2.Length);
}
}
|
Javascript
function substringSort(arr, n) {
arr.sort( function (s1, s2) {
return s1.length - s2.length;
});
for (let i = 0; i < n - 1; i++) {
if (!arr[i + 1].includes(arr[i])) {
console.log( "Cannot be sorted" );
return ;
}
}
for (let i = 0; i < n - 1; i++) {
console.log(arr[i]);
}
}
let arr1 = [ "d" , "zddsaaz" , "ds" , "ddsaa" , "dds" ];
substringSort(arr1, arr1.length);
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.
Space Complexity: O(1) as no extra space has been taken.
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:
- Create array of length maxLen
- Sort the input strings such that the string with length 1 is in the first place in the array
- If there is two or more string has the same length they must be equal otherwise the strings cannot be sorted
- Validate that each string is a substring of the next longer string
Implementation:
C++
#include <bits/stdc++.h>
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] = "" ;
}
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)
{
count[len - 1]++;
}
else
{
cout << "Cannot be sorted" ;
return ;
}
}
int index = 0;
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 ;
}
}
}
for ( int i = 0; i < maxLen; i++)
{
string s = sortedArr[i];
for ( int j = 0; j < count[i]; j++)
{
cout << s << endl;
}
}
}
int main()
{
int maxLen = 100;
string arr1[] = { "d" , "zddsaaz" , "ds" , "ddsaa" ,
"dds" , "dds" };
substringSort(arr1, sizeof (arr1)/ sizeof (arr1[0]), maxLen);
string arr2[] = { "for" , "rof" };
substringSort(arr2, sizeof (arr2)/ sizeof (arr2[0]), maxLen);
return 0;
}
|
Java
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, "" );
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)) {
count[len - 1 ]++;
}
else {
System.out.println( "Cannot be sorted" );
return ;
}
}
int index = 0 ;
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 ;
}
}
}
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 ;
String[] arr1 = { "d" , "zddsaaz" , "ds" , "ddsaa" ,
"dds" , "dds" };
substringSort(arr1, arr1.length, maxLen);
String[] arr2 = { "for" , "rof" };
substringSort(arr2, arr2.length, maxLen);
}
}
|
Python3
def substringSort(arr, n, maxLen):
count = [ 0 ] * (maxLen)
sortedArr = [""] * (maxLen)
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):
count[ Len - 1 ] + = 1
else :
print ( "Cannot be sorted" )
return
index = 0
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
for i in range (maxLen):
s = sortedArr[i]
for j in range (count[i]):
print (s)
maxLen = 100
arr1 = [ "d" , "zddsaaz" , "ds" , "ddsaa" , "dds" , "dds" ]
substringSort(arr1, len (arr1), maxLen)
arr2 = [ "for" , "rof" ]
substringSort(arr2, len (arr2), maxLen)
|
C#
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] = "" ;
}
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]))
{
count[len - 1]++;
}
else
{
Console.WriteLine( "Cannot be sorted" );
return ;
}
}
int index = 0;
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 ;
}
}
}
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;
String[] arr1 = { "d" , "zddsaaz" , "ds" , "ddsaa" ,
"dds" , "dds" };
substringSort(arr1, arr1.Length, maxLen);
String[] arr2 = { "for" , "rof" };
substringSort(arr2, arr2.Length, maxLen);
}
}
|
Javascript
<script>
function substringSort(arr, n, maxLen)
{
let count = new Array(maxLen);
let sortedArr = new Array(maxLen);
count.fill(0);
for (let i = 0; i < maxLen; i++)
{
sortedArr[i] = "" ;
}
for (let i = 0; i < n; i++) {
let s = arr[i];
let len = s.length;
if (count[len - 1] == 0) {
sortedArr[len - 1] = s;
count[len - 1] = 1;
}
else if (sortedArr[len - 1] == s) {
count[len - 1]++;
}
else {
document.write( "Cannot be sorted" + "</br>" );
return ;
}
}
let index = 0;
while (count[index] == 0)
index++;
let prev = index;
let prevString = sortedArr[prev];
index++;
for (; index < maxLen; index++) {
if (count[index] != 0) {
let current = sortedArr[index];
if (current.includes(prevString)) {
prev = index;
prevString = current;
}
else {
document.write( "Cannot be sorted" );
return ;
}
}
}
for (let i = 0; i < maxLen; i++) {
let s = sortedArr[i];
for (let j = 0; j < count[i]; j++) {
document.write(s + "</br>" );
}
}
}
let maxLen = 100;
let arr1 = [ "d" , "zddsaaz" , "ds" , "ddsaa" ,
"dds" , "dds" ];
substringSort(arr1, arr1.length, maxLen);
let arr2 = [ "for" , "rof" ];
substringSort(arr2, arr2.length, maxLen);
</script>
|
Output
d
ds
dds
dds
ddsaa
zddsaaz
Cannot be sorted
Last Updated :
06 Apr, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...