句子的英语到 PigLatin 翻译
English to PigLatin Conversion of a Sentence
我正在制作一个将英语转换为 PigLatin 的程序。但是,我的解决方案似乎只适用于一个词。如果我输入了多个单词,则只翻译最后一个。
testing one translation
只会输出:
translationway
我看过一些解决方案,但大多数与我的方式相同,或者使用超出我知识范围的“简化”解决方案。
代码:
static void Main(string[] args)
{
Console.WriteLine("Enter a sentence to convert to PigLatin:");
string sentence = Console.ReadLine();
string pigLatin = ToPigLatin(sentence);
Console.WriteLine(pigLatin);
}
static string ToPigLatin (string sentence)
{
string firstLetter,
restOfWord,
vowels = "AEIOUaeio";
int currentLetter;
foreach (string word in sentence.Split())
{
firstLetter = sentence.Substring(0, 1);
restOfWord = sentence.Substring(1, sentence.Length - 1);
currentLetter = vowels.IndexOf(firstLetter);
if (currentLetter == -1)
{
sentence = restOfWord + firstLetter + "ay";
}
else
{
sentence = word + "way";
}
}
return sentence;
非常感谢所有帮助!
编辑
感谢大家的反馈,我更新了我的代码:
static string ToPigLatin (string sentence)
{
const string vowels = "AEIOUaeio";
List<string> pigWords = new List<string>();
foreach (string word in sentence.Split(' '))
{
string firstLetter = word.Substring(0, 1);
string restOfWord = word.Substring(1, word.Length - 1);
int currentLetter = vowels.IndexOf(firstLetter);
if (currentLetter == -1)
{
pigWords.Add(restOfWord + firstLetter + "ay");
}
else
{
pigWords.Add(word + "way");
}
}
return string.Join(" ", pigWords);
}
调整此代码以处理辅音簇会不会很复杂?
例如,现在 测试一个翻译 打印为:
estingtay oneway ranslationtay
虽然,据我了解 PigLatin 规则,它应该是:
estingtay oneway anslationtray
只需在此处放置 +=
而不是 =
:
if (currentLetter == -1)
{
sentence += restOfWord + firstLetter + "ay";
}
else
{
sentence += word + "way";
}
在您的版本中,您在循环的每次迭代中都覆盖了句子
编辑
我对代码做了很多修改:
public static string ToPigLatin(string sentence)
{
const string vowels = "AEIOUaeio";
List<string> newWords = new List<string>();
foreach (string word in sentence.Split(' '))
{
string firstLetter = word.Substring(0, 1);
string restOfWord = word.Substring(1, word.Length - 1);
int currentLetter = vowels.IndexOf(firstLetter);
if (currentLetter == -1)
{
newWords.Add(restOfWord + firstLetter + "ay");
}
else
{
newWords.Add(word + "way");
}
}
return string.Join(" ", newWords);
}
正如 Panagiotis-Kanavos 所说,他是对的,不要将输出 建立在 你的输入上,而是 使用 你的输入输入。因此,我添加了 newWords
列表(有些人可能更喜欢 StringBuilder,但我不喜欢)。
您在循环中滥用变量,尤其是在 Substrings
调用中,现在已修复。
如果您对此有任何疑问,请不要犹豫。
private static void Main(string[] args)
{
Console.WriteLine("Enter a sentence to convert to PigLatin:");
string sentence = Console.ReadLine();
var pigLatin = GetSentenceInPigLatin(sentence);
Console.WriteLine(pigLatin);
Console.ReadLine();
}
private static string GetSentenceInPigLatin(string sentence)
{
const string vowels = "AEIOUaeio";
var returnSentence = "";
foreach (var word in sentence.Split())
{
var firstLetter = word.Substring(0, 1);
var restOfWord = word.Substring(1, word.Length - 1);
var currentLetter = vowels.IndexOf(firstLetter, StringComparison.Ordinal);
if (currentLetter == -1)
{
returnSentence += restOfWord + firstLetter + "ay ";
}
else
{
returnSentence += word + "way ";
}
}
return returnSentence;
}
我为此想出了一个简短的 LINQ 实现:
string.Join(" ", "testing one translation".Split(' ')
.Select(word => "aeiouy".Contains(word[0])
? word.Skip(1).Concat(word.Take(1))
: word.ToCharArray())
.Select(word => word.Concat("way".ToCharArray()))
.Select(word => string.Concat(word)));
输出:"testingway neoway translationway"
当然,我可能会将其重构为如下形式:
"testing one translation"
.Split(' ')
.Select(word => word.ToCharsWithStartingVowelLast())
.Select(word => word.WithEnding("way"))
.Select(word => string.Concat(word))
.Join(' ');
static class Extensions {
public static IEnumerable<char> ToCharsWithStartingVowelLast(this string word)
{
return "aeiouy".Contains(word[0])
? word.Skip(1).Concat(word.Take(1))
: word.ToCharArray();
}
public static IEnumerable<char> WithEnding(this IEnumerable<char> word, string ending)
{
return word.Concat(ending.ToCharArray())
}
public static string Join(this IEnumerable<IEnumerable<char>> words, char separator)
{
return string.Join(separator, words.Select(word => string.Concat(word)));
}
}
更新:
在您的编辑中,您询问了辅音簇。我喜欢使用 LINQ 执行此操作的其中一件事是,只需更新管道的那部分并使其全部正常工作就非常简单:
public static IEnumerable<char> ToCharsWithStartingConsonantsLast(this string word)
{
return word.SkipWhile(c => c.IsConsonant()).Concat(word.TakeWhile(c => c.IsConsonant()));
}
public static bool IsConsonant(this char c)
{
return !"aeiouy".Contains(c);
}
整个管道,没有重构为扩展方法,现在看起来像这样:
string.Join(" ", "testing one translation".Split(' ')
.Select(word => word.SkipWhile(c => !"aeiouy".Contains(c)).Concat(word.TakeWhile(c => !"aeiou".Contains(c))))
.Select(word => word.Concat("way".ToCharArray()))
.Select(word => string.Concat(word)))
并输出 "estingtway oneway anslationtrway"
.
更新二:
我注意到我没有正确处理词尾。这是一个更新,当单词(没有结尾)以元音结尾时,只将 w
添加到结尾:
string.Join(" ", "testing one translation".Split(' ')
.Select(word => word.SkipWhile(c => !"aeiouy".Contains(c)).Concat(word.TakeWhile(c => !"aeiou".Contains(c))))
.Select(word =>
{
var ending = "aeiouy".Contains(word.Last()) ? "way" : "ay";
return word.Concat(ending.ToCharArray());
})
.Select(word => string.Concat(word)))
输出:"estingtay oneway anslationtray"
。请注意,仅处理添加已更改结尾的步骤 - 算法的所有其他部分均未更改。
考虑到现在这很简单,我可能只使用两种扩展方法:Join(this IEnumerable<IEnumerable<char>> words, char separator)
和 IsConsonant(this char c)
(根据上面的代码示例,后者的实现应该很容易)。这会产生以下最终实现:
"testing one translation"
.Split(' ')
.Select(word => word.SkipWhile(c => !c.IsVowel()).Concat(word.TakeWhile(c => c.IsVowel())))
.Select(word => word.Concat((word.Last().IsVowel() ? "way" : "ay").ToCharArray()))
.Select(word => string.Concat(word))
.Join(" ")
在这里也很容易看到我们翻译的内容:
- 将句子拆分成单词
- 将任何辅音随机排列到单词的末尾(诚然,乍一看并不明显,但我找不到更简单的方式来表达它,除非将其包装在扩展方法中)
- 添加结尾
- 将
IEnumerable<char>
s 转换为 string
s
- 将单词重新组合成一个句子
我正在制作一个将英语转换为 PigLatin 的程序。但是,我的解决方案似乎只适用于一个词。如果我输入了多个单词,则只翻译最后一个。
testing one translation
只会输出:
translationway
我看过一些解决方案,但大多数与我的方式相同,或者使用超出我知识范围的“简化”解决方案。
代码:
static void Main(string[] args)
{
Console.WriteLine("Enter a sentence to convert to PigLatin:");
string sentence = Console.ReadLine();
string pigLatin = ToPigLatin(sentence);
Console.WriteLine(pigLatin);
}
static string ToPigLatin (string sentence)
{
string firstLetter,
restOfWord,
vowels = "AEIOUaeio";
int currentLetter;
foreach (string word in sentence.Split())
{
firstLetter = sentence.Substring(0, 1);
restOfWord = sentence.Substring(1, sentence.Length - 1);
currentLetter = vowels.IndexOf(firstLetter);
if (currentLetter == -1)
{
sentence = restOfWord + firstLetter + "ay";
}
else
{
sentence = word + "way";
}
}
return sentence;
非常感谢所有帮助!
编辑
感谢大家的反馈,我更新了我的代码:
static string ToPigLatin (string sentence)
{
const string vowels = "AEIOUaeio";
List<string> pigWords = new List<string>();
foreach (string word in sentence.Split(' '))
{
string firstLetter = word.Substring(0, 1);
string restOfWord = word.Substring(1, word.Length - 1);
int currentLetter = vowels.IndexOf(firstLetter);
if (currentLetter == -1)
{
pigWords.Add(restOfWord + firstLetter + "ay");
}
else
{
pigWords.Add(word + "way");
}
}
return string.Join(" ", pigWords);
}
调整此代码以处理辅音簇会不会很复杂?
例如,现在 测试一个翻译 打印为:
estingtay oneway ranslationtay
虽然,据我了解 PigLatin 规则,它应该是:
estingtay oneway anslationtray
只需在此处放置 +=
而不是 =
:
if (currentLetter == -1)
{
sentence += restOfWord + firstLetter + "ay";
}
else
{
sentence += word + "way";
}
在您的版本中,您在循环的每次迭代中都覆盖了句子
编辑
我对代码做了很多修改:
public static string ToPigLatin(string sentence)
{
const string vowels = "AEIOUaeio";
List<string> newWords = new List<string>();
foreach (string word in sentence.Split(' '))
{
string firstLetter = word.Substring(0, 1);
string restOfWord = word.Substring(1, word.Length - 1);
int currentLetter = vowels.IndexOf(firstLetter);
if (currentLetter == -1)
{
newWords.Add(restOfWord + firstLetter + "ay");
}
else
{
newWords.Add(word + "way");
}
}
return string.Join(" ", newWords);
}
正如 Panagiotis-Kanavos 所说,他是对的,不要将输出 建立在 你的输入上,而是 使用 你的输入输入。因此,我添加了 newWords
列表(有些人可能更喜欢 StringBuilder,但我不喜欢)。
您在循环中滥用变量,尤其是在 Substrings
调用中,现在已修复。
如果您对此有任何疑问,请不要犹豫。
private static void Main(string[] args)
{
Console.WriteLine("Enter a sentence to convert to PigLatin:");
string sentence = Console.ReadLine();
var pigLatin = GetSentenceInPigLatin(sentence);
Console.WriteLine(pigLatin);
Console.ReadLine();
}
private static string GetSentenceInPigLatin(string sentence)
{
const string vowels = "AEIOUaeio";
var returnSentence = "";
foreach (var word in sentence.Split())
{
var firstLetter = word.Substring(0, 1);
var restOfWord = word.Substring(1, word.Length - 1);
var currentLetter = vowels.IndexOf(firstLetter, StringComparison.Ordinal);
if (currentLetter == -1)
{
returnSentence += restOfWord + firstLetter + "ay ";
}
else
{
returnSentence += word + "way ";
}
}
return returnSentence;
}
我为此想出了一个简短的 LINQ 实现:
string.Join(" ", "testing one translation".Split(' ')
.Select(word => "aeiouy".Contains(word[0])
? word.Skip(1).Concat(word.Take(1))
: word.ToCharArray())
.Select(word => word.Concat("way".ToCharArray()))
.Select(word => string.Concat(word)));
输出:"testingway neoway translationway"
当然,我可能会将其重构为如下形式:
"testing one translation"
.Split(' ')
.Select(word => word.ToCharsWithStartingVowelLast())
.Select(word => word.WithEnding("way"))
.Select(word => string.Concat(word))
.Join(' ');
static class Extensions {
public static IEnumerable<char> ToCharsWithStartingVowelLast(this string word)
{
return "aeiouy".Contains(word[0])
? word.Skip(1).Concat(word.Take(1))
: word.ToCharArray();
}
public static IEnumerable<char> WithEnding(this IEnumerable<char> word, string ending)
{
return word.Concat(ending.ToCharArray())
}
public static string Join(this IEnumerable<IEnumerable<char>> words, char separator)
{
return string.Join(separator, words.Select(word => string.Concat(word)));
}
}
更新:
在您的编辑中,您询问了辅音簇。我喜欢使用 LINQ 执行此操作的其中一件事是,只需更新管道的那部分并使其全部正常工作就非常简单:
public static IEnumerable<char> ToCharsWithStartingConsonantsLast(this string word)
{
return word.SkipWhile(c => c.IsConsonant()).Concat(word.TakeWhile(c => c.IsConsonant()));
}
public static bool IsConsonant(this char c)
{
return !"aeiouy".Contains(c);
}
整个管道,没有重构为扩展方法,现在看起来像这样:
string.Join(" ", "testing one translation".Split(' ')
.Select(word => word.SkipWhile(c => !"aeiouy".Contains(c)).Concat(word.TakeWhile(c => !"aeiou".Contains(c))))
.Select(word => word.Concat("way".ToCharArray()))
.Select(word => string.Concat(word)))
并输出 "estingtway oneway anslationtrway"
.
更新二:
我注意到我没有正确处理词尾。这是一个更新,当单词(没有结尾)以元音结尾时,只将 w
添加到结尾:
string.Join(" ", "testing one translation".Split(' ')
.Select(word => word.SkipWhile(c => !"aeiouy".Contains(c)).Concat(word.TakeWhile(c => !"aeiou".Contains(c))))
.Select(word =>
{
var ending = "aeiouy".Contains(word.Last()) ? "way" : "ay";
return word.Concat(ending.ToCharArray());
})
.Select(word => string.Concat(word)))
输出:"estingtay oneway anslationtray"
。请注意,仅处理添加已更改结尾的步骤 - 算法的所有其他部分均未更改。
考虑到现在这很简单,我可能只使用两种扩展方法:Join(this IEnumerable<IEnumerable<char>> words, char separator)
和 IsConsonant(this char c)
(根据上面的代码示例,后者的实现应该很容易)。这会产生以下最终实现:
"testing one translation"
.Split(' ')
.Select(word => word.SkipWhile(c => !c.IsVowel()).Concat(word.TakeWhile(c => c.IsVowel())))
.Select(word => word.Concat((word.Last().IsVowel() ? "way" : "ay").ToCharArray()))
.Select(word => string.Concat(word))
.Join(" ")
在这里也很容易看到我们翻译的内容:
- 将句子拆分成单词
- 将任何辅音随机排列到单词的末尾(诚然,乍一看并不明显,但我找不到更简单的方式来表达它,除非将其包装在扩展方法中)
- 添加结尾
- 将
IEnumerable<char>
s 转换为string
s - 将单词重新组合成一个句子