我想制作一个程序,用于计算段落中回文词的数量及其出现次数
规则和假设:
示例输入:
奥托想养一只狗。他走上街头,准备走进宠物 当他看到挂在门上的“踩下没有宠物”的标志时,便会存放。玫瑰油 在宠物商店看到很多动物。他看到了鸟儿。他看到了松鼠。他 看到变色龙。他看到了狗。 “这只狗多少钱?”奥托说。 “十美元,”男子说。奥托给了男人的女孩子。奥托买了狗。该 狗跟奥托一起走回家。现在奥托有一只狗。 “感谢上帝,我有一只狗,”他说 对自己说。示例输出: Otto = 7 A = 5 Sees = 6
我的代码是:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PalindromeProgram
{
class Program
{
static void Main(string[] args)
{
int i = 0;
Console.WriteLine("Enter a String");
string s = Console.ReadLine();
string words = s.ToLower();
string[] hasil = words.Split(' ');
foreach (string temp in hasil)
{
string str = string.Empty;
int x = temp.Length;
for (int y = x - 1; y >= 0; y--)
{
str = str + temp[y];
}
int count = 0;
if (str == temp)
{
count++;
Console.WriteLine(temp + " is palindrome = " + count);
}
i++;
}
}
}
}
和我的代码的输出结果,我把paragrapht:
奥托想养一只狗。当他看到门上挂着“踩着没有宠物”的牌子时,他走上街头,准备走进宠物商店。奥托在宠物商店看到了很多动物。他看到了鸟儿。他看到了松鼠。他看到了变色龙。他看到了狗。 “这只狗多少钱?”奥托说。 “十美元,”男子说。奥托给了男人的女孩子。奥托买了狗。狗跟奥托一起走回家。现在奥托有一只狗。 “现在感谢上帝,我有一只狗,”他对自己说。我的输出计划是:
otto是回文= 1 a是回文= 1 otto是回文= 1看是回文= 1
我想要我的输出程序:
单词Otto = 7,单词A = 5,单词Sees = 6
请修改我的输出结果......
答案 0 :(得分:4)
想象一下,您通过管道处理文本,步骤如下:
var s = @"<<< your input string here >>>";
var result = Regex.Matches(s, @"\w+").Cast<Match>() //1
.Select(m => m.Value.ToLower()) //1
.Where(w => String.Join("", w.Reverse()) == w) //2
.GroupBy(w => w) //3
.Select(g => new {Word = g.Key, Count = g.Count()}) //4
.ToList(); //5
result.ForEach(Console.WriteLine); //6
输出:
{ Word = otto, Count = 7 }
{ Word = a, Count = 5 }
{ Word = sees, Count = 6 }
不确定它是否会涵盖标点符号 - 需要调整reqular表达式。会让它给你。 :)我想唯一的例子是像I'll
这样的单词中的撇号。这种情况可以通过将正则表达式模式更改为\w|'+
来处理(这意味着任何字母或撇号,发生一次或多次)。
答案 1 :(得分:3)
有很多方法可以做到这一点。在我的脑海中,尝试将段落分成单词,删除重复项和每个结果单词,然后检查它是否是回文。
当然,有很多方法可以优化此算法。
查看您的代码,唯一的错误 - 可能是此问题中最复杂的问题 - 正确地拆分段落。您使用了string.Split(''),这意味着只有空格分隔的字符序列才会变成“单词”(数组中的项目)。但是,生成的数组可能包含带
的项目狗,”
这显然不是一个词。
有很多方法可以实现正确的分割。 the_joric答案使用了Regex,虽然功能强大,但它太复杂且难以理解,这可能导致错误。
(我不是说我不会用它来解决这个特殊的问题;我只是说这可能对C#newcomer来说太大了一步)。
所以我会尝试用其他方式编写解决方案:
让我们为我们特定的问题域定义什么是字,不是吗?对我来说,单词是一个只使用字母的一个或多个字符的序列。所以,“猜测”,“什么”和“asd”是一个词。但是,“123asd”或“a1s2d3”或“asd123”不是。
另一方面,也许是“asd”。是一段时间后的一个词。所以,让我们遵循启发式方法,除了字母以外的任何东西都是“分隔符”。因此,“123asd”将产生“asd”作为单词,“a1s2d3”将产生“a”,“b”和“c”。
const string validChars = "abcdefghijklmenopqrstuvwxyz";
List<string> GetAllWords(string inputSentence)
{
var list = new List<string>();
string word = string.Empty;
foreach (var c in inputSentence.ToLower())
{
if (validChars.IndexOf(c) >= 0)
{
word += c;
}
else if (word != string.Empty)
{
list.Add(word);
word = string.Empty;
}
}
return list;
}
上面的方法将返回我们的启发式后面的单词列表。正如我已经说过的那样,这并不完美,但考虑到格式良好的文本,它会起作用。用这个算法替换你的“string.Split(...)”,你就可以了。