我预计这个算法会慢一些,以检查元音

时间:2011-01-24 03:22:20

标签: c# algorithm string search

以下算法的速度取决于发送单词中的单词数和每个单词中的字符数。我相信这是O(N ^ 2)?或者更糟。

private bool CheckForNoVowels(string sentence)
{
    foreach (string word in sentence.Split(' '))
        foreach (char c in word)
            if (!vowels.Contains(c))
                return true;
}

比尔盖茨是否隐藏了某些秘密string.HasVowel?有没有更好,更有效的方法来搜索它。谢谢。

意图
我试图确定字符串是公司还是名字,我假设如果有一个单词没有元音,它是缩写或缩写,它是一个公司。

7 个答案:

答案 0 :(得分:8)

Regex.IsMatch(sentence, "[aoeui]");

答案 1 :(得分:3)

不,这非常好。它将被视为输入中字符总数的O(N)。我无法想象这会是您应用中的性能瓶颈 - 但您应该使用性能分析来确定。

答案 2 :(得分:3)

我不确定它的内部实现是什么(它用[MethodImpl(MethodImplOptions.InternalCall)标记,并且它的算法似乎没有记录) ,但我会尝试string.IndexOfAny方法。

  

报告第一个索引   在任何这种情况下发生   指定数组中的字符   Unicode字符。回报价值:   第一个从零开始的索引位置   在这种情况下发生的任何地方   找到anyOf中的字符; -1如果没有   找到了anyOf中的字符。

请注意:

  

搜索anyOf是   区分大小写。这种方法执行   序数(文化不敏感)   搜索,角色所在的位置   被认为等同于另一个   字符只有他们的Unicode标量   价值是一样的。执行一个   文化敏感的搜索,使用   CompareInfo.IndexOf方法。

示例:

char[] vowels = { 'a', 'e', 'i', 'o', 'u' };
bool hasVowel = word.IndexOfAny(vowels) != -1;

偏离主题,我不明白为什么你的代码将句子分成单词,然后查看每个单词中每个单词的元音。这种分裂似乎并没有取得任何成就。

答案 3 :(得分:1)

如果您希望根据句子中的单词数和每个单词中的字符数确定时间复杂度,则需要两个变量:单词数和每个单词中的字符数。如果你说 W 是单词数,而 N 是最长单词中的字符数,那么你的算法是O(W * N),而不是O( N ^ 2)。

答案 4 :(得分:0)

为什么不删除外部foreach?这里最昂贵的东西似乎是sentence.Split(' '),消除它只会导致空格被检查vowels中的成员资格。否则,这看起来像是一段O(N)代码。

答案 5 :(得分:0)

^ 2来自哪里?

分裂是O(N)

foreach(word ...)foreach(c) - 完全一次遍历每个角色 - O(N)同时为“foreach”。

vowels.Contains是常数(如果元音的数量永远不会改变)或O(元音的数量)。

结果是O(N)或O(N *元音数)。

答案 6 :(得分:0)

您可以展平循环以避免不必要的拆分及其字符串分配,但在一天结束时您仍然需要检查每个字符是否为元音:

private static readonly char[] _vowels = "AEIOUaeiou".ToCharArray();
private bool CheckForVowels(string sentence)
{
    return sentence.IndexOfAny(_vowels) != -1;
}

(我不知道IndexOfAny的内部实现。我想象它必须执行这样的循环,但很有可能它会使用非托管执行和/或不安全的代码,所以至少和你自己写的任何东西一样快。)