簡體   English   中英

給定一個字符串,找到具有相同元音和輔音數量的最長子字符串?

[英]Given a string, find the longest substring with the same number of vowels and consonants?

給定一個字符串,找到具有相同元音和輔音數量的最長子字符串。

澄清:我不確定,我們是否可以生成一個新字符串,或者子字符串必須是原始字符串的一部分? 到目前為止我有這個,

代碼片段:

    Scanner scanner = new Scanner(System.in);
    String string = new String(scanner.next());
    int lengthOfString = string.length();
    int vowelCount = 0;
    int consCount = 0;

    for (int i = 0; i < lengthOfString; i++) {
        if (string.charAt(i) == 'u' || string.charAt(i) == 'e'  || string.charAt(i) == 'i'
                || string.charAt(i) == 'o' || string.charAt(i) == 'a' ) {
            vowelCount++;


        } else {

            consCount++;
        }

    }

    System.out.println(vowelCount);

編輯我得到了計數工作,但我如何創建子字符串?

這可以使用此答案計算的“凈”值結合以下觀察在O(n)時間和空間中求解:

  • 當且僅當net [1 .. i-1] = net [1 .. j]時,子串s [i ... j]具有相同數量的輔音和元音,其中net [i ... j]是總和位置i和j之間的每個字符的“凈”值(對於元音為1,對於輔音為-1),包括在內。

要看到這一點,請注意告訴我們子串s [i .. j]是我們正在尋找的那種條件是

net[i .. j] = 0.

將net [1 .. i-1]添加到此等式的兩邊給出

net[1 .. i-1] + net[i .. j] = net[1 .. i-1]

與LHS然后簡化到公正

net[1 .. j] = net[1 .. i-1]

算法

這意味着我們可以創建一個包含兩個條目的表(第一個看到的位置和看到的最后一個位置),我們可以在計算凈值的運行總和時得到每個可能的不同值。 這個運行總數的范圍可以低至-n(如果每個字符都是輔音)或高至n(如果每個字符都是元音),那么總共最多有2n + 1個不同的總和,所以我們將在我們的表中需要很多行。 然后,我們從左到右遍歷字符串,計算一個運行的總凈值,並更新表中對應於當前運行總計的對,注意每當此更新產生一個新的最大長度子字符串時。 在偽代碼中,使用從零開始的數組索引並使用單獨的數組來保存每對中的元素:

  1. 創建2個長度為2n + 1,first []和last []的數組,最初包含所有-2,除了first [n]為-1。 (需要使用-2作為哨兵,因為-1實際上是一個有效值!)
  2. 設置bestFirst = bestLast = bestLen = -1。
  3. 設置運行總數t = n。 (n“表示”0;使用此偏差意味着我們可以將運行總計直接用作數組中的非負值索引,而無需重復向其添加偏移量。)
  4. 對於從0到n-1的i:
    • 如果s [i]是元音,則遞增t,否則遞減t。
    • 如果first [t]是-2:
      • 首先設置[t] = i。
    • 除此以外:
      • 設置last [t] = i。
      • 如果last [t] - first [t]> bestLen:
        • 設置bestLen = last [t] - first [t]。
        • 設置bestFirst = first [t] + 1。
        • 設置bestLast = last [t]。

最大長度范圍將在(bestFirst,bestLast)中返回,或者如果不存在這樣的范圍,則這些變量都將為-1。

我記得看到這個解決方案,或一個非常相似的解決方案,在某個地方的某個地方 - 如果有人能找到它,我很樂意鏈接到它。

要找到輔音和元音數相等的最長子串,請開始查找最大長度的子串,並穩定地減少所需的長度,直到找到符合條件的子串。

這將允許您短路操作。

public static String findLongestSubstring(String str) {
    for (int len = str.length(); len >= 2; len--) {
        for (int i = 0; i <= str.length() - len; i++) {
            String substr = str.substring(i, i + len);
            int vowels = countVowels(substr);
            int consonants = len - vowels;
            if (vowels == consonants) {
                return substr;
            }
        }
    }
    return "";
}

private static int countVowels(String str) {
    return str.replaceAll("[^AEIOUaeiou]+", "").length(); 
}

這是我的原始答案的更新版本,在O(n^2)時間內運行。 它通過采用一種技巧來實現這一點,即跟蹤單個變量(稱為“網絡”),該變量跟蹤元音和輔音數量之間的差異 當此數字為零時,給定的子字符串是平衡的。

這需要O(n^2)遍歷在最壞的情況下每一個可能的子串,但它不會采取任何額外的時間檢查每個子字符串和元音,因為它保持了net最新的每個新的台階選擇子串。 因此,它將復雜度從O(n^3)O(n^2)

public String findLongestSubstring(String input) {
    String longest = "";

    for (int window = inputz.length(); window >=2; --window) {
        String substr = input.substring(0, window);
        String consonants = input.substring(0, window).toLowerCase()
                .replaceAll("[aeiou]", "");
        int vowelCount = input.substring(0, window).length() - consonants.length();
        int consonantCount = consonants.length();

        int net = vowelCount - consonantCount;

        for (int i=window; i <= input.length(); ++i) {
            if (net == 0) {
                longest = input.substring(i-window, i);
                return longest;
            }

            // no-op for last window
            if (i == input.length()) break;

            // update tally by removing high character
            if ("aeiou".indexOf(input.charAt(i)) != -1) {
                ++net;
            }
            else {
                --net;
            }
            // update tally by adding low character
            if ("aeiou".indexOf(input.charAt(i-window)) != -1) {
                --net;
            }
            else {
                ++net;
            }
        }
    }

    return longest;
}

我認為這可能是你的任務的決定(不是太長的輸入字符串):

import org.junit.Test;

/**
 * Created by smv on 19/09/16.
 */
public class MainTest {

    public static boolean isVowel(char c) {
        return "AEIOUaeiou".indexOf(c) != -1;
    }

    public int getVowelCount(String str) {
        int res = 0;
        for(int i=0; i < str.length(); i++){
            if(isVowel(str.charAt(i))) {
                res++;
            }
        }
        return res;
    }

    public int getConsonantCount(String str) {
        int res = 0;
        for(int i=0; i < str.length(); i++){
            if(!isVowel(str.charAt(i))) {
                res++;
            }
        }
        return res;
    }

    @Test
    public void run() throws Exception {
        String string = "aasdaasggsertcwevwertwe";
        int lengthOfString = string.length();
        String maxSub = "";
        int maxSubLength = 0;

        // find all substrings of given string
        for( int c = 0 ; c < lengthOfString ; c++ )
        {
            for( int i = 1 ; i <= lengthOfString - c ; i++ )
            {
                String sub = string.substring(c, c+i);

                // comparing count vowels and consonants 
                if (getVowelCount(sub) == getConsonantCount(sub)) {
                    if (sub.length() > maxSubLength) {
                        maxSub = sub;
                        maxSubLength = sub.length();
                    }
                }
            }
        }
        System.out.println(maxSub);
    }
}

當然,這里的要求非常模糊。 它沒有提到輸入中是否包含數字或其他鍵。 我假設起始指數為零,因為計數在該點相等。

    Scanner scanner = new Scanner(System.in);
    String string = new String(scanner.next());
    int lengthOfString = string.length();
    int vowelCount = 0;
    int consCount = 0;
    int maxIndex = -1;

    for(int i = 0; i < lengthOfString; i++) 
    {
        System.out.println("Char: " + string.charAt(i));

        if(string.charAt(i) == 'u' || string.charAt(i) == 'e' || string.charAt(i) == 'i'
            || string.charAt(i) == 'o' || string.charAt(i) == 'a') 
        {
            vowelCount++;
        } 
        else 
        {
            consCount++;
        }

        if(vowelCount == consCount)
        {
            System.out.println("count equal with: " + string.substring(0, (i + 1)));
            maxIndex = i + 1;
        }
    }

    if(maxIndex > 0)
    {
        System.out.println("Longest sub string with equal count of vowels and consonants is: " 
            + string.substring(0, maxIndex));
    }
    else
    {
        System.out.println("No substring existed with equal count of vowels and consonants.");
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM