Find the longest string that can be made up of other strings from the array

Given an array of strings arr[], the task is to find the largest string in the array which is made up of the other strings from the array after concatenating one after another. If no such string exists then print -1.

Examples:

Input: arr[] = {“geeks”, “for”, “geeksfor”, “geeksforgeeks”}
Output: geeksforgeeks
“geeksforgeeks” is made up of (“geeks” + “for” + “geeks”).
Even though “geeksfor” is also made up of other strings
but it is not the largest string.

Input: arr[] = {“Hey”, “you”, “stop”, “right”, “there”}
Output : -1

Approach:

  1. Sort all the strings based on their lengths in decreasing order.
  2. Now, starting from the longest string. Check for all possible prefix of the string whether it is present in the given array and for the remaining part of the string, recursively check whether it can be made up from other strings from the array.
  3. Map can be used to check whether a string exists in the array or not. The first string which satisfies the above conditions is the answer.
  4. If no such string exists then print -1.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
  
// Comparator to sort the string by
// their lengths in decreasing order
bool compare(string s1, string s2)
{
    return s1.size() > s2.size();
}
  
// Function that returns true if string s can be
// made up of by other two string from the array
// after concatenating one after another
bool canbuildword(string& s, bool isoriginalword,
                  map<string, bool>& mp)
{
  
    // If current string has been processed before
    if (mp.find(s) != mp.end() && mp[s] == 0)
        return false;
  
    // If current string is found in the map and
    // it is not the string under consideration
    if (mp.find(s) != mp.end() && mp[s] == 1
        && isoriginalword == 0) {
        return true;
    }
  
    for (int i = 1; i < s.length(); i++) {
  
        // Split the string into two
        // contiguous sub-strings
        string left = s.substr(0, i);
        string right = s.substr(i);
  
        // If left sub-string is found in the map and
        // the right sub-string can be made from
        // the strings from the given array
        if (mp.find(left) != mp.end() && mp[left] == 1
            && canbuildword(right, 0, mp)) {
            return true;
        }
    }
  
    // If everything failed, we return false
    mp[s] = 0;
    return false;
}
  
// Function to return the longest string
// that can made be made up from the
// other string of the given array
string printlongestword(vector<string> listofwords)
{
  
    // Put all the strings in the map
    map<string, bool> mp;
    for (string s : listofwords) {
        mp[s] = 1;
    }
  
    // Sort the string in decreasing
    // order of their lengths
    sort(listofwords.begin(), listofwords.end(), compare);
  
    // Starting from the longest string
    for (string s : listofwords) {
  
        // If current string can be made
        // up from other strings
        if (canbuildword(s, 1, mp))
            return s;
    }
  
    return "-1";
}
  
// Driver code
int main()
{
    vector<string> listofwords = { "geeks", "for", "geeksfor",
                                   "geeksforgeeks" };
    cout << printlongestword(listofwords);
  
    return 0;
}

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python implementation of the approach
  
# Function that returns true if string s can be
# made up of by other two string from the array
# after concatenating one after another
def canbuildword(s, isoriginalword, mp):
  
    # If current string has been processed before
    if s in mp and mp[s] == 0:
        return False
  
    # If current string is found in the map and
    # it is not the string under consideration
    if s in mp and mp[s] == 1 and isoriginalword == 0:
        return True
  
    for i in range(1, len(s)):
  
        # Split the string into two
        # contiguous sub-strings
        left = s[:i]
        right = s[i:]
  
        # If left sub-string is found in the map and
        # the right sub-string can be made from
        # the strings from the given array
        if left in mp and mp[left] == 1 and canbuildword(right, 0, mp):
            return True
  
    # If everything failed, we return false
    mp[s] = 0
    return False
  
# Function to return the longest string
# that can made be made up from the
# other string of the given array
def printlongestword(listofwords):
  
    # Put all the strings in the map
    mp = dict()
    for i in listofwords:
        mp[i] = 1
  
    # Sort the string in decreasing
    # order of their lengths
    listofwords.sort(key=lambda x: len(x), reverse=True)
  
    # Starting from the longest string
    for i in listofwords:
  
        # If current string can be made
        # up from other strings
        if canbuildword(i, 1, mp):
            return i
  
    return "-1"
  
# Driver code
if __name__ == "__main__":
    listofwords = ["geeks", "for", "geeksfor",
                "geeksforgeeks"]
  
    print(printlongestword(listofwords))
  
# This code is contributed by
# sanjeev2552

chevron_right


Output:

geeksforgeeks


My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : sanjeev2552