我目前正试图解决一个标题大写问题。我有一个方法,接受一个句子,把它分割成单词,比较单词和检查列表中的单词。
根据这个检查列表,如果单词在列表中,我会将它们小写。大写所有不在列表中的单词。第一个单词和最后一个单词总是大写的。
以下是我的方法:
public string TitleCase(string title)
{
LinkedList<string> wordsList = new LinkedList<string>();
string[] listToCheck = { "a", "the", "to", "in", "with", "and", "but", "or" };
string[] words = title.Split(null);
var last = words.Length - 1;
var firstWord = CapitalizeWord(words[0]);
var lastWord = CapitalizeWord(words[last]);
wordsList.AddFirst(firstWord);
for (var i = 1; i <= last - 1; i++)
{
foreach (var s in listToCheck)
{
if (words[i].Equals(s))
{
wordsList.AddLast(LowercaseWord(words[i]));
}
else
{
wordsList.AddLast(CapitalizeWord(words[i]));
}
}
}
wordsList.AddLast(lastWord);
var sentence = string.Join(" ", wordsList);
return sentence;
}使用该示例运行此操作,并期望得到结果:
var result = TitleCase("i love solving problems and it is fun"); Assert.AreEqual("I Love Solving Problems and It Is Fun", result);
我得到的却是:
"I Love Love Love Love Love Love Love Love Solving Solving Solving Solving Solving Solving Solving Solving Problems Problems Problems Problems Problems Problems Problems Problems And And And And And and And And It It It It It It It It Is Is Is Is Is Is Is Is Fun"如果你仔细看一下,一个and就会降低。我怎么解决这个问题有什么建议吗?
发布于 2017-05-04 17:14:13
当您遍历每个要检查的单词时,您正在执行一些额外的循环操作,并且在找到匹配项后就不会立即退出循环(因此您将单词添加到每个检查中)。若要在特定代码中解决此问题,请执行以下操作:
for (var i = 1; i <= last - 1; i++)
{
bool foundMatch = false;
foreach (var s in listToCheck)
{
if (words[i].Equals(s))
{
foundMatch = true;
break;
}
}
if (foundMatch)
{
wordsList.AddLast(LowercaseWord(words[i]));
}
else
{
wordsList.AddLast(CapitalizeWord(words[i]));
}
}然而,有一个更容易的方法,其他答案提供了。但我想指出另外几件事:
LinkedList。您已经有了可以在words数组中操作的单词列表,所以只需使用它就可以节省一些内存。A单词的字符串,它将不会被转换为小写,因为默认情况下,Equals方法(或其他答案,Contains方法)会进行区分大小写的比较。因此,您可能希望将一个不区分大小写的比较器传递给该方法。if语句即可。所以,我会这样做:
public static string TitleCase(string title)
{
var listToCheck = new[]{ "a", "the", "to", "in", "with", "and", "but", "or" };
var words = title.Split(null);
// Loop through all words in the array
for (int i = 0; i < words.Length; i++)
{
// If we're on the first or last index, or if
// the word is not in our list, Capitalize it
if (i == 0 || i == (words.Length - 1) ||
!listToCheck.Contains(words[i], StringComparer.OrdinalIgnoreCase))
{
words[i] = CapitalizeWord(words[i]);
}
else
{
words[i] = LowercaseWord(words[i]);
}
}
return string.Join(" ", words);
}发布于 2017-05-04 16:24:45
问题是在foreach循环中,您要对每个单词执行八次检查( listToCheck数组的长度),每次都将单词添加到列表中。我还建议使用Linq查询,因此应该如下所示:
for (var i = 1; i <= last - 1; i++) {
if(listToCheck.Contains(words[i]))
wordsList.AddLast(LowercaseWord(words[i]));
else
wordsList.AddLast(CapitalizeWord(words[i]));
}此外,第六‘和’被降低的原因是因为它是listToCheck数组中的第六个单词。在第六次围绕foreach循环时,它成功地完成了测试,并且用小写编写,其他的都失败了,因此它被大写了。
发布于 2017-05-04 16:25:04
在一个循环中有一个循环,这个循环会把事情搞砸,将代码简化为只有一个循环:
for (var i = 1; i <= last - 1; i++)
{
// No inner loop
// Use the .Contains() method to see if it's a key word
if (listToCheck.Contains(words[i]))
{
wordsList.AddLast(LowercaseWord(words[i]));
}
else
{
wordsList.AddLast(CapitalizeWord(words[i]));
}
}输出:
我喜欢解决问题,而且很有趣
https://stackoverflow.com/questions/43788056
复制相似问题