web-dev-qa-db-ja.com

母音のサブシーケンス

私は面接の練習をしていて、ウェブサイトでこの質問に出くわしました。

文字列Sの魔法のサブシーケンスは、5つの母音すべてを順番に含むSのサブシーケンスです。文字列Sの最大の魔法のサブシーケンスの長さを見つけます。

たとえば、if S = aeeiooua、次にaeiouaeeioouは魔法のサブシーケンスですが、aeioaeeiouaはそうではありません。

私は動的計画法の初心者であり、このための再帰的な式を思い付くのは難しいと感じています。

6
Arun

私は再帰的なアプローチではなく、反復的なアプローチでそれを行いました。 LIS(Longest Increasing Subsequence)と同様のソリューションの構築を開始し、それをO(n)まで最適化しました。

#include<iostream>
#include<string>
#include<vector>
using namespace std;

string vowel = "aeiou";

int vpos(char c)
{
    for (int i = 0; i < 5; ++i)
        if (c == vowel[i])
            return i;
    return -1;
}

int magical(string s)
{
    int l = s.length();
    int previndex[5] = {-1, -1, -1, -1, -1};    // for each vowel
    vector<int> len (l, 0);
    int i = 0, maxlen = 0;

    // finding first 'a'
    while (s[i] != 'a')
    {
        ++i;
        if (i == l)
            return 0;
    }

    previndex[0] = i;       //prev index of 'a'
    len[i] = 1;

    for ( ++i; i < l; ++i)
    {
        if (vpos(s[i]) >= 0)    // a vowel
        {
            /* Need to append to longest subsequence on its left, only for this vowel (for any vowels) and 
             * its previous vowel (if it is not 'a')
                This important observation makes it O(n) -- differnet from typical LIS
            */
            if (previndex[vpos(s[i])] >= 0)
                len[i] = 1+len[previndex[vpos(s[i])]];

            previndex[vpos(s[i])] = i;

            if (s[i] != 'a')
            {
                if (previndex[vpos(s[i])-1] >= 0)
                    len[i] = max(len[i], 1+len[previndex[vpos(s[i])-1]]);
            }

            maxlen = max(maxlen, len[i]);
        }
    }
    return maxlen;
}

int main()
{
    string s = "aaejkioou";
    cout << magical(s);
    return 0;
}
5
Gaurav Singh

O(入力文字列の長さ)ランタイムインポートJava.util。*;

public class Main {
    /*
        algo:
        keep map of runningLongestSubsequence that ends in each letter. loop through String s. for each char, try appending
        to runningLongestSubsequence for that char, as well as to runningLongestSubsequence for preceding char.
        update map with whichever results in longer subsequence.

        for String s = "ieaeiouiaooeeeaaeiou", final map is:
        terminal letter in longest running subsequence-> longest running subsequence
        a -> aaaa
        e -> aeeeee
        i -> aeeeeei
        o -> aeeeeeio
        u -> aeeeeeiou

        naming:
        precCharMap - precedingCharMap
        runningLongestSubMap - runningLongestSubsequenceMap
     */

    public static int longestSubsequence(String s) {

        if (s.length() <= 0) throw new IllegalArgumentException();

        Map<Character, Character> precCharMap = new HashMap<>();
        precCharMap.put('u', 'o');
        precCharMap.put('o', 'i');
        precCharMap.put('i', 'e');
        precCharMap.put('e', 'a');

        Map<Character, String> runningLongestSubMap = new HashMap<>();

        for (char currChar : s.toCharArray()) {
            //get longest subs
            String currCharLongestSub;
            String precCharLongestSub = null;
            if (currChar == 'a') {
                currCharLongestSub = runningLongestSubMap.getOrDefault(currChar, "");
            } else {
                currCharLongestSub = runningLongestSubMap.get(currChar);
                char precChar = precCharMap.get(currChar);
                precCharLongestSub = runningLongestSubMap.get(precChar);
            }

            //update running longest subsequence map
            if (precCharLongestSub == null && currCharLongestSub != null) {
                updateRunningLongestSubMap(currCharLongestSub, currChar, runningLongestSubMap);
            } else if (currCharLongestSub == null && precCharLongestSub != null) {
                updateRunningLongestSubMap(precCharLongestSub, currChar, runningLongestSubMap);
            } else if (currCharLongestSub != null && precCharLongestSub != null) {
                //pick longer
                if (currCharLongestSub.length() < precCharLongestSub.length()) {
                    updateRunningLongestSubMap(precCharLongestSub, currChar, runningLongestSubMap);
                } else {
                    updateRunningLongestSubMap(currCharLongestSub, currChar, runningLongestSubMap);
                }
            }
        }

        if (runningLongestSubMap.get('u') == null) {
            return 0;
        }
        return runningLongestSubMap.get('u').length();
    }

    private static void updateRunningLongestSubMap(String longestSub, char currChar,
                                                   Map<Character, String> runningLongestSubMap) {
        String currCharLongestSub = longestSub + currChar;
        runningLongestSubMap.put(currChar, currCharLongestSub);
    }

    public static void main(String[] args) {
        //String s = "aeeiooua"; //7
        //String s = "aeiaaioooaauuaeiou"; //10
        String s = "ieaeiouiaooeeeaaeiou"; //9
        //String s = "ieaeou"; //0
        //String s = "ieaeoooo"; //0
        //String s = "aeiou"; //5
        //if u have String s beginning in "ao", it'll do nothing with o and 
        //continue on to index 2.

        System.out.println(longestSubsequence(s));
    }
}
2
Modelday
int findsubwithcontinuousvowel(string str){
    int curr=0;
    int start=0,len=0,maxlen=0,i=0;
    for(i=0;i<str.size();i++){
        if(str[i]=='u' && (current[curr]=='u' ||  (curr+1<5 && current[curr+1]=='u'))){
           //len++;
           maxlen=max(len+1,maxlen);
        }

        if(str[i]==current[curr]){
            len++;
        }
        else if(curr+1<5 && str[i]==current[curr+1]){
            len++;
            curr++;
        }
        else{
            len=0;
            curr=0;
            if(str[i]=='a'){
                len=1;
            }
        }
    }
    return maxlen;
}
0
Satyendra Kumar
int func( char *p)
{
    char *temp = p;
    char ae[] = {'a','e','i','o','u'};

    int size = strlen(p), i = 0;
    int chari = 0, count_aeiou=0;
    for (i=0;i<=size; i++){
        if (temp[i] == ae[chari]) {
            count_aeiou++;
        }
        else if ( temp[i] == ae[chari+1]) {
            count_aeiou++;
            chari++;
        }
    }
    if (chari == 4 ) {
        printf ("Final count : %d ", count_aeiou);
    } else {
        count_aeiou = 0;
    }
    return count_aeiou;
}

ハッカーランクチャレンジに従ってVOWELSカウントを返すソリューション。

0
goodies

母音がisInSequenceで順番に使用できるかどうかを確認し、結果をprocessorで処理します。

public class one {

private char[] chars = {'a','e','i','o','u'};
private int a = 0;

private boolean isInSequence(char c){
    // check if char is repeating
    if (c == chars[a]){
        return true;
    }
    // if vowels are in sequence and just passed by 'a' and so on...
    if (c == 'e' && a == 0){
        a++;
        return true;
    }
    if (c == 'i' && a == 1){
        a++;
        return true;
    }
    if (c == 'o' && a == 2){
        a++;
        return true;
    }
    if (c == 'u' && a == 3){
        a++;
        return true;
    }
    return false;
}

private char[] processor(char[] arr){
    int length = arr.length-1;
    int start = 0;
    // In case if all chars are vowels, keeping length == arr
    char array[] = new char[length];

    for (char a : arr){
        if (isInSequence(a)){
            array[start] = a;
            start++;
        }
    }
    return array;
}

public static void main(String args[]){
    char[] arr = {'m','a','e','l','x','o','i','o','u','a'};
    one o = new one();
    System.out.print(o.processor(arr));
 }
}
0
W4R10CK
#include <bits/stdc++.h>
#define ios ios::sync_with_stdio(NULL);cin.tie(NULL);cout.tie(NULL);
#define ll unsigned long long
using namespace std;

int main() {
    // your code goes here
 ios
string s;
cin>>s;
int n=s.length();
int dp[n+1][5]={0};
for(int i=1;i<=n;i++)
{
    if(s[i-1]=='a')
    {
        dp[i][0]=1+dp[i-1][0];
        dp[i][1]=dp[i-1][1];
        dp[i][2]=dp[i-1][2];
        dp[i][3]=dp[i-1][3];
        dp[i][4]=dp[i-1][4];
    }
    else if(s[i-1]=='e')
    {dp[i][0]=dp[i-1][0];
    if(dp[i-1][0]>0)
        {dp[i][1]=1+max(dp[i-1][1],dp[i-1][0]);}
        else
        dp[i-1][1]=0;
        dp[i][2]=dp[i-1][2];
        dp[i][3]=dp[i-1][3];
        dp[i][4]=dp[i-1][4];
    }
     else if(s[i-1]=='i')
    {dp[i][0]=dp[i-1][0];
    if(dp[i-1][1]>0)
        {dp[i][2]=1+max(dp[i-1][1],dp[i-1][2]);}
        else
        dp[i-1][2]=0;
        dp[i][1]=dp[i-1][1];
        dp[i][3]=dp[i-1][3];
        dp[i][4]=dp[i-1][4];
    }
    else if(s[i-1]=='o')
    {dp[i][0]=dp[i-1][0];
    if(dp[i-1][2]>0)
        {dp[i][3]=1+max(dp[i-1][3],dp[i-1][2]);}
        else
        dp[i-1][3]=0;
        dp[i][2]=dp[i-1][2];
        dp[i][1]=dp[i-1][1];
        dp[i][4]=dp[i-1][4];
    }
    else if(s[i-1]=='u')
    {dp[i][0]=dp[i-1][0];
       if(dp[i-1][3]>0)
        {dp[i][4]=1+max(dp[i-1][4],dp[i-1][3]);}
        else
        dp[i-1][4]=0;
        dp[i][1]=dp[i-1][1];
        dp[i][3]=dp[i-1][3];
        dp[i][2]=dp[i-1][2];
    }
    else
    {
        dp[i][0]=dp[i-1][0];
        dp[i][1]=dp[i-1][1];
        dp[i][2]=dp[i-1][2];
        dp[i][3]=dp[i-1][3];
        dp[i][4]=dp[i-1][4];
    }


}
cout<<dp[n][4];


return 0;
}

ここでは再帰的アプローチを使用できます(これは最大intまでの文字列長で機能するはずです(簡単に記憶を使用できます)

public class LMV {

static final int NOT_POSSIBLE = -1000000000;
// if out put is this i.e soln not possible 


static int longestSubsequence(String s, char[] c) {

    //exit conditions
    if(s.length() ==0 || c.length ==0){
        return 0;
    }

    if(s.length() < c.length){
        return NOT_POSSIBLE;
    }

    if(s.length() == c.length){
        for(int i=0; i<s.length(); i++){
            if(s.charAt(i) !=c [i]){
                return NOT_POSSIBLE;
            }
        }
        return s.length();
    }

    if(s.charAt(0) < c[0]){
        // ignore, go ahead with next item
        return longestSubsequence(s.substring(1), c);
    } else if (s.charAt(0) == c[0]){
        // <case 1> include item and start search for next item in chars
        // <case 2> include but search for same item again in chars
        // <case 3> don't include item

        return Math.max(
                Math.max(  ( 1+longestSubsequence(s.substring(1), Arrays.copyOfRange(c, 1, c.length) ) ),
                            ( 1+longestSubsequence(s.substring(1), c ) ) ),
                ( longestSubsequence(s.substring(1), c )) );
    } else {
        //ignore
        return longestSubsequence(s.substring(1), c);
    }
}



public static void main(String[] args) {

    char[] chars = {'a', 'e', 'i', 'o', 'u'};

    String s1 = "aeio";
    String s2 = "aaeeieou";
    String s3 = "aaeeeieiioiiouu";

    System.out.println(longestSubsequence(s1, chars));
    System.out.println(longestSubsequence(s2, chars));
    System.out.println(longestSubsequence(s3, chars));

}

}

0
Ravi Verma
#include <iostream>
#include<string>
#include<cstring>

using namespace std;
unsigned int getcount(string a, unsigned int l,unsigned int r );
int main()
{    
    std::string a("aaaaaeeeeaaaaiiioooeeeeuuuuuuiiiiiaaaaaaoo"
                 "oooeeeeiiioooouuuu");
    //std::string a("aaaaaeeeeaaaaiiioooeeeeuuuuuuiiiiiaaaaaaoooooeeeeiiioooo"); 
   //std::string a("aaaaaeeeeaaaaiiioooeeeeiiiiiaaaaaaoooooeeeeiiioooo"); //sol0
  //std::string a{"aeiou"};
  unsigned int len = a.length();
  unsigned int i=0,cnt =0,countmax =0;
  bool newstring = true;
  while(i<len)
  {
      if(a.at(i) == 'a' && newstring == true) 
      {
          newstring = false;
          cnt = getcount(a,i,len);
          if(cnt > countmax) 
          {
             countmax = cnt;
             cnt = 0;
          }
        } 
        else if(a.at(i)!='a')
        {
            newstring = true;
        }
        i++;
    }
    cout<<countmax;
    return 0;
}

unsigned int getcount(string a, unsigned int l,unsigned int r )
{
    std::string b("aeiou");
    unsigned int seq=0,cnt =0;
    unsigned int current =l;
    bool compstr = false;
    while(current<r)
    {
        if(a.at(current) == b.at(seq)) 
        {
            cnt++;
        }
        else if((seq <= (b.size()-2)) && (a.at(current) == b.at(seq+1)))
        {
            seq++; 
            cnt++;
            if (seq == 4) 
                compstr =true;
        }
        current++;
    }
    if (compstr == true) 
        return cnt;
   return 0;
}
0
Kiran

これがあなたの質問のpythonコードです。非再帰的アプローチを使用しました。

ここで私のリポジトリから選択: MagicVowels Madaditya

############################################################################
#
# Magical Subsequence of  Vowels
#       by Aditya Kothari (https://github.com/Madaditya/magivvowels)
#
#
############################################################################
import sys
import re

usage = '''
Error : Invalid no of arguments passed.
Usage :
python magicv.py string_to_check
eg: python magicv.py aaeeiiooadasduu
'''

def checkMagicVowel(input_string):
    #The Answer Variable 
    counter = 0

    #Check if all vowels exist
    if ('a' in input_string) and ('e' in input_string) and ('i' in input_string) and ('o' in input_string) and ('u' in input_string):

        vowel_string = 'aeiou'
        input_string_voweslOnly = ''

        #Keeping only vowels in the string i.e user string MINUS NON vowels
        for letter in input_string:
            if letter in 'aeiou':
                input_string_voweslOnly = input_string_voweslOnly + letter

        magic = ''
        index_on_vowel_string = 0
        current_vowel = vowel_string[index_on_vowel_string]
        #i is index on the current Character besing tested
        i = 0
        for current_char in input_string_voweslOnly:

            if current_char == current_vowel:
                counter = counter + 1
                magic = magic + current_char

            if (i < len(input_string_voweslOnly)-1):
                next_char = input_string_voweslOnly[i+1]

                if(index_on_vowel_string != 4):
                    next_vowel = vowel_string[index_on_vowel_string+1]
                else:
                    next_vowel = vowel_string[index_on_vowel_string]

                #next character should be the next new vowel only to count++
                if (current_char != next_char and next_char == next_vowel):
                        if(index_on_vowel_string != 4):
                            index_on_vowel_string = index_on_vowel_string + 1
                        current_vowel = vowel_string[index_on_vowel_string]

            i = i + 1
        #Uncomment next line to print the all magic sequences
        #print magic

        '''
        #Regex Method
        #magic = re.match('[a]+[e]+[i]+[o]+[u]+',input_string_voweslOnly)
        magic = re.match('[aeiou]+',input_string_voweslOnly)
        if magic is not None:
            ##print magic.group() 
            ##print len(magic.group())
        else:
            ##print(0)
        '''
    else:
        counter = 0
    return counter

if __name__ == "__main__":

    #checking arguments passed
    if(len(sys.argv) != 2):
        print usage
        sys.exit(0)
    input_string = sys.argv[1].lower()

    #get all possible substrings
    all_a_indices = [i for i, ltr in enumerate(input_string) if ltr == 'a']
    substrings = []
    for item in all_a_indices:
        substrings.append(input_string[item:])
    #print substrings

    #Pass each substring and find the longest magic one
    answer = []
    for each in substrings:
        answer.append(checkMagicVowel(each))
    print max(answer)
0
Madaditya