我想构建一个分析句子的程序,然后针对出现在句子单词中的每个字符/数字/符号,记录该字符出现在哪个单词中。(大写/小写忽略,并重复一个单词中的字符条目将被忽略)。
所以如果我有一句话“我像牛一样孤独地流浪”。
这将在c#中进行。我考虑过2d数组,即26(对于字母)x 20(句子中的单词。这里的问题是我的数组将是稀疏的,并且还要努力跟踪哪个元素是下一个对每个字母备用。我希望我的字母a数组为[2,4,5]而不是[0,2,0,4,5]或[0,0,2,0,4, 5],由于还要迎合其他符号而变得复杂,因此26个将迅速变大,其中的第三个数组是“很明显”如何编程的数组,但却是最不优雅的解决方案。
static void Main(string[] args)
{
string[] sentence = new string[6] { "i", "wandered", "lonely", "as", "a", "cow" };
string alphabet = "abcdefghijklmnopqrstuvwxyz";
int[,] letterInWord= new int[26, 7];
for (int letterIndex = 0; letterIndex < alphabet.Length; letterIndex++)
{
for (int wordIndex = 0; wordIndex < sentence.Length; wordIndex++)
{
if(sentence[wordIndex].IndexOf(alphabet[letterIndex]) >= 0)
{
letterInWord[letterIndex, wordIndex+1] = wordIndex+1;
}
}
}
// then analyse or just print out (adding 1 to get counting base 1)
for (int letterIndex = 0; letterIndex < alphabet.Length; letterIndex++)
{
Console.Write(alphabet[letterIndex]+ " is in word(s) " );
for (int wordIndex = 1; wordIndex <= sentence.Length; wordIndex++)
{
if (letterInWord[letterIndex, wordIndex] > 0)
{
Console.Write(letterInWord[letterIndex, wordIndex] + " ");
}
}
Console.WriteLine();
}
}
那行得通,但我只是不喜欢它。
理想情况下,我想要一个名为“ senceList”的句子的列表,然后为我找到的每个字母(例如z)寻找一个名为“ listForZ”的列表,如果找不到,我会创建一个名为listForZ的新列表,将单词编号添加到列表中,然后将listForZ添加到句子列表中。
但是,这需要从我刚刚在单词中找到的变量以编程方式创建列表的名称,而我一直在努力理解其工作方式。我想我可以使用一种工厂方法模式,该模式知道我可以拥有的所有列表名称并适当地创建它们,但是同样,对于我想要的名称来说,这似乎有些过分。
有建议的路线吗?
答案 0 :(得分:0)
借助正则表达式(我们必须匹配单词)和 Linq 来查询这些单词,您可以实现以下内容:
string sentence = "I wandered lonely as a cow";
var result = string.Join("; ", Regex
.Matches(sentence, "[A-Za-z]+") // Word is a sequence of A..Z a..z letters
.OfType<Match>()
.Select((match, index) => new {
word = match.Value.ToLower(), // So we have word, e.g. "lonely"
index + 1 // and its index, e.g. "3"
})
.SelectMany(item => item.word.Select(c => new {
character = c, // for each character
wordNumber = item.index // we have a index of the word(s) where it appears
}))
.GroupBy(item => item.character, item => item.wordNumber) // grouping by character
.Select(chunk => $"{chunk.Key} - {string.Join(",", chunk.Distinct().OrderBy(n => n))}"));
// Let's have a look at the results
Console.Write(result);
结果:
i - 1; w - 2,6; a - 2,4,5; n - 2,3; d - 2; e - 2,3; r - 2; l - 3; o - 3,6; y - 3; s - 4; c - 6
答案 1 :(得分:0)
使用正则表达式:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace ConsoleApplication108
{
class Program
{
static void Main(string[] args)
{
string input = "I wandered lonely as a cow";
string pattern = @"(?'word'\w+)\s*";
string[] words = Regex.Matches(input, pattern).Cast<Match>().Select(x => x.Groups["word"].Value).ToArray();
var results = words
.Select(x => new { word = x, characters = x.ToCharArray().Select((y, i) => new { ch = y, index = i }).GroupBy(y => y.ch).Select(y => y.First()).ToList() }).ToList();
}
}
}
答案 2 :(得分:0)
但这需要以编程方式从以下位置创建列表的名称 我刚刚在单词中找到的变量,我一直在努力 了解这将如何工作。
使用Dictionary,您可以将键与值关联。在您的情况下,单词中的字符是键,单词出现的位置是值:
Dictionary<char, List<int>> occurrences = new Dictionary<char, List<int>>();
string sentence = "I wandered lonely as a cow";
string[] words = sentence.ToLower().Split(" ".ToCharArray());
for(int i = 0; i < words.Length; i++)
{
foreach(char c in words[i].ToCharArray().Distinct())
{
if (!occurrences.ContainsKey(c))
{
occurrences.Add(c, new List<int>());
}
occurrences[c].Add(i + 1);
}
}
foreach(KeyValuePair<char, List<int>> kvp in occurrences)
{
Console.WriteLine(kvp.Key.ToString() + " - " + String.Join(",", kvp.Value.ToArray()));
}
生成的输出:
i - 1
w - 2,6
a - 2,4,5
n - 2,3
d - 2
e - 2,3
r - 2
l - 3
o - 3,6
y - 3
s - 4
c - 6