GfG QA is closing soon... Please refer PRACTICE or GfG now on wards !!

Ask a Question

 

Start Coding Today

   

GeeksQuiz

GeeksforGeeksIDE

Data Structures

Algorithms

Interview Experiences

C Programming

C++ Programming

Java Programming

GATE CS

Books

String subsequence[Adobe Written Round Question]

Consider a string, s = "abc". An alphabetically-ordered sequence of substrings of s would be {"a", "ab", "abc", "b", "bc", "c"}. If we reduce this sequence to only those substrings that start with a vowel and end with a consonant, we're left with {"ab", "abc"}. The alphabetically first element in this reduced list is "ab", and the alphabetically last element is "abc". As a reminder:
Vowels: a, e, i, o, and u.
Consonants: b, c, d, f, g, h, j, k, l, m, n, p, q, r, s, t, v, w, x, y, and z.

Complete the findSubstrings function in your editor. It has 1 parameter: a string, s, consisting of lowercase English letters (a − z). The function must find the substrings of s that start with a vowel and end with a consonant, then print the alphabetically first and alphabetically last of these substrings.

Input Format
The locked stub code in your editor reads a single string, s, from stdin and passes it to your function.

Constraints
3 ≤ length of s ≤ 5 × 10^5

Output Format
Your function must print two lines of output denoting the alphabetically first and last substrings of s that start with a vowel and end with a consonant. Print the alphabetically first qualifying substring on the first line, and the alphabetically last qualifying substring on the second line.

Sample Input 1
aba

Sample Output 1
ab
ab

Explanation 1
"ab" is the only possible substring which starts with a vowel (a) and ends with a consonant (b). Because we only have 1 qualifying substring, "ab" is both the alphabetically first and last qualifying substring and we print it as our first and second lines of output.

Sample Input 2
aab

Sample Output 2
aab
ab

Explanation 2
There are 2 possible substrings which start with a vowel and end with a consonant: "aab" and "ab". When ordered alphabetically, "aab" comes before "ab". This means that we print "aab" (the alphabetically first qualifying substring) as our first line of output, and we print "ab" (the alphabetically last qualifying substring) as our second line of output.

Sample Input 3
rejhiuecumovsutyrulqaeuouiecodjlmjeaummaoqkexylwaaopnfvlbiiiidyckzfhe

Sample Output 3
aaop
utyrulqaeuouiecodjlmjeaummaoqkexylwaaopnfvlbiiiidyckzfh

Explanation 3
There are 4830 substrings of s, but only 676 of them start with a vowel and end with a consonant. When ordered alphabetically, the first substring is "aaop" and the last substring is "utyrulqaeuouiecodjlmjeaummaoqkexylwaaopnfvlbiiiidyckzfh".

asked Mar 13 by Goku
edited Mar 14 by Goku

1 Answer

#include<iostream>
#include<algorithm>
#include <cstring>
using namespace std;

struct suffix
{
    int index;
    int rank[2];
};
int cmp(struct suffix a, struct suffix b)
{
    return (a.rank[0] == b.rank[0])? (a.rank[1] < b.rank[1] ?1: 0):
               (a.rank[0] < b.rank[0] ?1: 0);
}

int *buildSuffixArray(char *txt, int n)
{
    struct suffix suffixes[n];

    for (int i = 0; i < n; i++)
    {
        suffixes[i].index = i;
        suffixes[i].rank[0] = txt[i] - 'a';
        suffixes[i].rank[1] = ((i+1) < n)? (txt[i + 1] - 'a'): -1;
    }

    sort(suffixes, suffixes+n, cmp);

    int ind[n];
    for (int k = 4; k < 2*n; k = k*2)
    {
        int rank = 0;
        int prev_rank = suffixes[0].rank[0];
        suffixes[0].rank[0] = rank;
        ind[suffixes[0].index] = 0;

        for (int i = 1; i < n; i++)
        {
            if (suffixes[i].rank[0] == prev_rank &&
                    suffixes[i].rank[1] == suffixes[i-1].rank[1])
            {
                prev_rank = suffixes[i].rank[0];
                suffixes[i].rank[0] = rank;
            }
            else
            {
                prev_rank = suffixes[i].rank[0];
                suffixes[i].rank[0] = ++rank;
            }
            ind[suffixes[i].index] = i;
        }

        for (int i = 0; i < n; i++)
        {
            int nextindex = suffixes[i].index + k/2;
            suffixes[i].rank[1] = (nextindex < n)?
                                  suffixes[ind[nextindex]].rank[0]: -1;
        }

        sort(suffixes, suffixes+n, cmp);
    }

    int *suffixArr = new int[n];
    for (int i = 0; i < n; i++)
        suffixArr[i] = suffixes[i].index;

    return  suffixArr;
}
bool isVowel(char ch) {
    if(ch == 'a' ||ch == 'e' ||ch == 'i' ||ch == 'o' ||ch == 'u')
        return true;
    return false;
}
void printArr(int arr[], int n)
{
    for (int i = 0; i < n; i++)
        cout << arr[i] << " ";
    cout << endl;
}
int main(){
    char txt[] = "aab";

    int n = strlen(txt);
    int len = n;
    //trim trailing vowels as thwy wont contribute
    while(isVowel(txt[len - 1])) {
        len--;
    }
    char newtxt[len];
    memcpy( newtxt, &txt[0], len );
    int *suffixArr = buildSuffixArray(newtxt,  n);
    //cout << "Following is suffix array for " << newtxt << endl;
    //printArr(suffixArr, n);
    bool exit = false;
    for(int i = 0; i < len && !exit; i++) {
        //take the suffix array from increasing order.
        if(isVowel(newtxt[suffixArr[i]])) {
            //Trim upto first consonant
            int temp = 0;
            for(int j = suffixArr[i];j < len;j++){
                if(isVowel(newtxt[j]))
                    temp++;
                else {
                    temp++;
                    exit = true;
                    break;
                }
            }
            char temptext[temp];
            memcpy( temptext, &newtxt[suffixArr[i]], temp);
            cout<<temptext<<endl;
        }
    }
    for(int i = n-1;i>=0;i--) {
        if(isVowel(newtxt[suffixArr[i]])) {
            for(int j = suffixArr[i];j < len; j++)
                cout<<newtxt[j];
            break;
        }
    }
    return 0;
}

answered May 15 by Deepak Kushwah
...