Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用lambda表达式计算C中字符串中超过x个字符的单词_C#_Linq_Lambda - Fatal编程技术网

C# 使用lambda表达式计算C中字符串中超过x个字符的单词

C# 使用lambda表达式计算C中字符串中超过x个字符的单词,c#,linq,lambda,C#,Linq,Lambda,我写了一个程序来计算一个句子中有x个匹配字符的单词。输入字符串是多行字符串,我只需要根据给定的标准考虑备用行。同样在那些过滤的行中,我需要进一步选择其他单词,然后检查这些过滤的单词是否与相交字符匹配 例如,假设我有一个输入字符串,如下所示,需要查找包含2个或更多元音的单词: string myString = "1.In order to get a Disneyland ticket 2.that includes the new Star Wars land 3.you must stay

我写了一个程序来计算一个句子中有x个匹配字符的单词。输入字符串是多行字符串,我只需要根据给定的标准考虑备用行。同样在那些过滤的行中,我需要进一步选择其他单词,然后检查这些过滤的单词是否与相交字符匹配

例如,假设我有一个输入字符串,如下所示,需要查找包含2个或更多元音的单词:

string myString = "1.In order to get a Disneyland ticket
2.that includes the new Star Wars land
3.you must stay at a Disney hotel 
4.the night of or night before your visit. 
5.Day passes without a hotel 
6.reservation will be available after June 23";
现在让我们假设我需要计算每2行中的每3个单词,并计算这些过滤的单词中是否有2个或更多元音。如果此条件匹配,则返回包含这些条件的匹配字数和总行数 匹配词

例如,根据选择第二行的标准,过滤后的行将为{2,4,6}。类似地,这些过滤行中的每三个字将是第2行:{the,Wars},对于第4行:{of,before},对于第6行:{be,after}

对于这些过滤后的单词,匹配有2个或更多元音的单词将在第4行中为{before},在第6行中为{after}。因此,最终输出将是wordCount=2,因为这些单词来自第4行和第6行,所以总行数=2

我使用嵌套for循环编写了下面的代码,该循环生成所需的输出

public static void Main(string[] args)
    {
        int vowelCount = 2; // match words with 2 or more vowels
        int skipWord = 3; // Consider every 3rd word only
        int skipLine = 2; // Consider every 2nd line only
        int wordCount = 0;
        int lineCount = 0;

        string myString = @"1.In order to get a Disneyland ticket
2.that includes the new Star Wars land
3.you must stay at a Disney hotel 
4.the night of or night before your visit. 
5.Day passes without a hotel 
6.reservation will be available after June 23";";

        List<string> myList = myString.Split(Environment.NewLine).ToList();
        List<string> lineWords = new List<string>();
        char[] vowels = {'a', 'e', 'i', 'o', 'u'};

        for (int i = skipLine; i <= myList.Count; i += skipLine)
        {
            int origWordCount = wordCount;
            lineWords = myList[i - 1].Split(' ').ToList();
            for (int j = skipWord; j <= lineWords.Count; j += skipWord)
            {
                char[] wordArr = lineWords[j-1].ToLower().ToCharArray();
                int match = vowels.Intersect(wordArr).Count();
                if (match >= vowelCount)
                    wordCount++;                 
            }
            if (wordCount > origWordCount)
                lineCount++;
        }

        Console.WriteLine("WordCount : {0}, LineCount : {1}", wordCount, lineCount);
上面的代码工作得很好,但不知道是否有一种不用嵌套循环的方法。我读过linq和lambda表达式,但不知道如何在这里使用它们


感谢所有评论。

首先使用像这样的“where”子句中的“predicate”筛选行,以获得每2行:

List<string> lines = myString.Split(Environment.NewLine).Where((l,index) => index % 2 != 0).ToList();

将所有内容放在一个大型LINQ查询中是否明智?这将使理解代码、测试代码、实现更改或重用部分代码变得更加困难

考虑编写单独的类似LINQ的函数,这些函数只执行部分代码。这称为扩展方法。看

我需要计算每第二行中的每三个单词,并计算这些过滤单词中是否有两个或更多元音。如果此条件匹配,则返回包含这些匹配字的匹配字计数和总行计数

因此,创建函数:

输入:一个字符串;输出:按行序列分割的字符串 输入:一系列行;输出:每2行或每n行的顺序 输入:一行;输出:行中的单词 输入:一系列单词;输出:序列中的第三个字或每n个字 输入:一个单词;输出:单词中元音的数量 其中大多数都很简单:

IEnumerable<string> ToLines(this text)
{
    // TODO: check text not null
    using (var reader = new StringReader(text))
    {
        var line = reader.ReadLine();
        while (line != null)
        {
            yield return line;
            line = reader.ReadLine();
        }
    }
}

IEnumerable<string> KeepEvery2ndLine(this IEnumerable<string> lines)
{
    // TODO: check lines not null
    int lineNr = 0;
    foreach (var line in lines
    {
        ++lineNr;
        if (lineNr%2 == 0)
            yield return line;
    }
}

IEnumerable<string> ToWords(this string line)
{
    // TODO: check line not null
    // when is a word a word? do you need to consider tabs? semicolons?
    // is a number like 12 a word?
}
IEnumerable<string> ToLines(this text)
{
    // TODO: check text not null
    using (var reader = new StringReader(text))
    {
        var line = reader.ReadLine();
        while (line != null)
        {
            yield return line;
            line = reader.ReadLine();
        }
    }
}

IEnumerable<string> KeepEvery2ndLine(this IEnumerable<string> lines)
{
    // TODO: check lines not null
    int lineNr = 0;
    foreach (var line in lines
    {
        ++lineNr;
        if (lineNr%2 == 0)
            yield return line;
    }
}

IEnumerable<string> ToWords(this string line)
{
    // TODO: check line not null
    // when is a word a word? do you need to consider tabs? semicolons?
    // is a number like 12 a word?
}
var result = inputText.ToLines()
                      .KeepEvery2ndLine()
                      .ToWords()
                      .KeepEvery3rdWord()
                      .CountVowels();