我很难找到以下谜题的算法 - 如果一个字符串连续有3个元音,或者连续有5个辅音,或者两者都有,则称为丑陋。如果字符串不丑,则称其为nice。给你一个字符串s,由大写字母('A' - 'Z')和问号('?')组成。 你能找到一个算法,通过用字母替换问号来判断字符串是否可以变好吗?
示例 -
“EE?FFFF” - 不能做得很好。插入辅音或元音会使它变得难看。
“H 22 LOWOR ??” - 可以做得很好。
答案 0 :(得分:12)
请注意,唯一可能丑陋的字符串是由于给定字母或仅包含单例问号而已经丑陋的字符串。这是证明的草图:
所以,我们留下了两个简单的案例。
答案 1 :(得分:5)
Haskell中的解决方案:
import System (getArgs)
nicePart :: Int -> Int -> String -> Bool
nicePart 3 _ _ = False
nicePart _ 5 _ = False
nicePart _ _ "" = True
nicePart v c ('?':as) = nicePart (v+1) 0 as || nicePart 0 (c+1) as
nicePart v c (a:as)
| a `elem` "AEIOU" = nicePart (v+1) 0 as
| otherwise = nicePart 0 (c+1) as
nice :: String -> Bool
nice as = nicePart 0 0 as
main = getArgs >>= print . nice . unwords
该函数记录到当前点已经看到多少个连续元音和辅音。如果有太多,则返回False
。如果找到问号,则进行两次递归调用,一次将问号计为元音,一次作为辅音,检查这些变化是否合适。
答案 2 :(得分:3)
这是关键:从丑陋到美好的可转换性取决于一定长度的辅音或元音。因此,如果将一个块转换为nice将必然预测另一个块的丑陋,则无法完成。
对于懒得做自己的家庭作业的人来说,实施是一种练习。 : - )
答案 3 :(得分:2)
您可以做的是迭代每个问号,并测试插入元音或问号的每种可能组合。
例如(V =>元音,C =>辅音)
答案 4 :(得分:2)
有一个与丑陋相匹配的正则表达式:
[aeiouAEIOU]{3}|[a-zA-Z&&[^aeiouAEIOU]]{5}
现在,如果在元音序列中发生?
,您可以将其变成辅音。如果它发生在一系列辅音内,你可以把它变成一个元音。如果问号出现在边界上,则会出现问题:
[aeiouAEIOU]{2}\?[a-zA-Z&&[^aeiouAEIOU]]{4}
[a-zA-Z&&[^aeiouAEIOU]]{4}\?[aeiouAEIOU]{2}
在每种情况下,都没有解决方案。现在,如果有两个问号,一个接一个,如果序列是:
,就会出现问题[aeiouAEIOU]{2}\?\?[aeiouAEIOU]{2}
[a-zA-Z&&[^aeiouAEIOU]]{4}\?\?[a-zA-Z&&[^aeiouAEIOU]]{4}
这些也没有解决方案。如果有两个以上的问号,那么你可以解决它。
所以,搜索那些模式,加上“纯粹的”丑陋模式。如果它们中的任何一个发生,你就无法改变。否则,没关系。
答案 5 :(得分:0)
您是否尝试过迭代整个字母表并尝试每种组合以查看它是否“丑陋”?
尝试用字母替换每个问号然后检查有效性,这是最简单,最不理想的方式。例如:
EEF?d?
我会开始填写?这些组合:
AAA AAB AAC AAD
等
编辑:不,你不必遍历整个字母表,只需A和B即可。或者真的,只是任何元音和任何辅音。
答案 6 :(得分:0)
正如已经指出的那样,有一种蛮力,效率极低的方法可行。有趣的是增加效率,减少可能性。
首先,在原来的字符串之前做一个快速的“丑陋的正则表达式”匹配吗?代换。如果你得到一个匹配,那么这个字符串显然不能很好。
接下来寻找单身?机会,那些?那两边都是没有其他的?四个职位。看看这些中的任何一个是否必须固定为V或C,或者它们是否完全取消了该字符串的资格(如OP的例子1中所示)。如果它们必须固定为V或C,请执行此操作并继续。
后续策略更多参与:双倍?细分涉及左右检查?根据各自的左/右侧翼字符等的V / C要求
答案 7 :(得分:0)
这是C#中的解决方案,似乎可以从我投入的一些测试用例中解决。 [正则表达式的部分内容来自之前的回答者。]
public static bool IsWordNiceable(string word, int maxVowels, int maxConsonants)
{
if (IsUgly(word, maxVowels, maxConsonants)) return false;
int i = 0;
while ((i = word.IndexOf('?', i)) != -1)
{
string newWord = word.Substring(0, i) + "a" + word.Substring(i+1);
bool vowelMakesNice = IsWordNiceable(newWord, maxVowels, maxConsonants);
newWord = word.Substring(0, i) + "b" + word.Substring(i + 1);
bool consonantMakesNice = IsWordNiceable(newWord, maxVowels, maxConsonants);
if (!(vowelMakesNice || consonantMakesNice)) return false;
i++;
}
return true;
}
private static bool IsUgly(string word, int maxVowels, int maxConsonants)
{
string consonants = "bcdfghjklmnpqrstvwxyz";
string vowels = "aeiou";
string uglyRegex = string.Format("([{0}]{{{1},{1}}})|([{2}]{{{3},{3}}})", vowels, maxVowels, consonants, maxConsonants);
Match match = Regex.Match(word.ToLower(), uglyRegex);
return match.Success;
}
这首先测试给定的单词是否是丑陋的(包括问号,如果有的话)。然后它循环通过单词,替换第一个“?”同时使用元音和辅音,并使用新单词调用自身。如果元音和辅音替换都不能使它变好,那么该分支返回false(丑陋)。