java 给定一个字符串,找出元音和辅音个数相同的最长子串?

00jrzges  于 2023-05-27  发布在  Java
关注(0)|答案(6)|浏览(177)

给定一个字符串,找出具有相同数量元音和辅音的最长子串。

**CLARIFICATION:**我不确定,是否可以生成一个新的字符串,或者子字符串必须是原始字符串的一部分?到目前为止我有这个
代码段:

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);

EDIT我让count工作了,但我如何创建一个子串?

plicqrtu

plicqrtu1#

这可以在O(n)时间和空间中使用this answer计算的“净”值结合以下观察来解决:

  • 子字符串s[i. j]具有相同数量的辅音和元音当且仅当net[1.. i-1] =净[1.. j],其中net[i.. j]是位置i和j(包括i和j)之间的每个字符的“净”值之和(元音为1,辅音为-1)。

要看到这一点,请观察告诉我们子串s[i..我们要找的是

net[i .. j] = 0.

正在添加网络[1.. i-1],则该等式的两边给出

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

然后简化为

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

算法

这意味着我们可以创建一个表,其中包含两个条目(第一个位置和最后一个位置),用于计算净值的运行和时可以获得的每个可能的不同值。这个运行总和的范围可以低至-n(如果每个字符都是辅音)或高至n(如果每个字符都是元音),因此总共最多有2n+1个不同的总和,因此我们需要在表中有那么多行。然后,我们从左到右遍历字符串,计算一个运行总净值,并更新表中与当前运行总值对应的对,注意每次更新都会产生一个新的最大长度的子串。在伪代码中,使用从零开始的数组索引,并使用单独的数组来保存每对中的元素:
1.创建2个长度为2n+1的数组,first[]和last[],最初包含所有的-2,除了first[n]是-1。(需要使用-2作为标记,因为-1实际上是一个有效值!)
1.设置bestFirst = bestLast = bestLen =-1。
1.设置运行总计t = n。(n)“表示”0;使用这种偏差意味着我们可以直接使用运行总和作为数组的非负值索引,而不必重复地向其添加偏移量。

  • 对于从0到n-1的i:
  • 如果s[i]是元音,则递增t,否则递减t。
  • 如果first[t]是-2:
  • 设置first[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。
我记得在SO上看到过这个解决方案,或者一个非常类似的解决方案--如果有人能找到它,我很乐意链接到它。

gblwokeq

gblwokeq2#

这里是我原来的答案的更新版本,运行时间为O(n^2)。它通过使用一个技巧来实现这一点,即跟踪一个单一的变量(称为“net”),该变量跟踪元音和辅音数量之间的差异。当这个数字为零时,给定的子串是平衡的。
在最坏的情况下,需要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;
}
nvbavucw

nvbavucw3#

要查找辅音和元音数量相等的最长子串,请从最大长度开始查找子串,然后逐渐减小所需的长度,直到找到符合条件的子串。
这将允许您短路操作。

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(); 
}
ejk8hzay

ejk8hzay4#

我认为这可能是你的任务的决定(对于不太长的输入字符串):

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);
    }
}
nfg76nw0

nfg76nw05#

当然,这里的要求非常模糊。它没有提到输入中是否包含数字或其他键。我假设起始索引为零,因为在该点计数相等。

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.");
    }
brgchamk

brgchamk6#

我用C#写的(我的错,对不起),但我认为你可以得到的想法:

public string Foo(string stg)
{   
    var result = "";
    var sum = 0;
    var dictionary = new Dictionary<int, int>();

    for (var index = 0; index < stg.Length; index++)
    {
        if ("AEIOUaeiou".Contains((stg[index].ToString()))) { sum += 1; }
        else { sum -= 1; }

        if (sum == 0)
        {
            result = stg.Substring(0, index + 1);
        }

        if (dictionary.ContainsKey(sum))
        {
            if (result.Length < index - dictionary[sum])
            {
                result = stg.Substring(dictionary[sum], index - dictionary[sum] + 1);
            }
        }
        else
        {
            dictionary.Add(sum, index);
        }
    }

    return result;
}

相关问题