繁体   English   中英

查找字符串行中出现时间最长的字符

[英]Find the first longest char occurrence in string lines

    int lines = File.ReadAllLines(Path).Length; // count lines index

    public string input = "";
    public string mtd() // This method should return the first long occurrence index (ry) and the longest occurrence of the char (rx)
    {
        Dictionary<char, int> dict = new Dictionary<char, int>();

        int max = 0;

        foreach (char c in input)
        {
            int i;
            dict.TryGetValue(c, out i);
            i++;
            if (i > max)
            {
                max = i;
            }
            dict[c] = i;
        }
        string rx = "";
        string ry = "";
        foreach (KeyValuePair<char, int> chars in dict)
        {

            string x = chars.Key.ToString();
            string y = chars.Value.ToString();
            if (chars.Value == max)
            {
                rx = x;
                ry = y;
            }
        }

        return rx;

       }

我的目标是:

使用一个按钮,使用FileFile.txt(具有更多文本行),使用OpenFileDialog美国。另一个按钮在richTextBox中显示每行的第一个最长子串(char出现)和第一个最长的chars索引(从零开始) 。

这是我的意思的一个例子。

在文本文件中,我有3行:

AAABB

ccddddd

efffggggg

结果应为:

AAA级,0

DDDDD,1

GGGGG,4

我已经看到了有关此问题的其他问题,但没有找到解决方案。 任何想法?

因此,这与其他方法稍有不同,但是您可以尝试使用正则表达式。 以下表达式将匹配重复字符的模式:

(.)(\1+)

(。)匹配换行符以外的任何字符,并且(\\ 1+)匹配先前匹配的1个或多个重复。

如果需要,您可以为第一个匹配组使用(。)以外的名称。 这取决于您关心的重复类型。 例如,如果您只关心重复的“ a”,则可以改用(a)。

这种方法为您提供了很大的灵活性,因为(。)组可以由字符串变量定义,而不必进行硬编码。

算法:

  1. 您将一次从文件中提取一行。
  2. 然后使用此正则表达式在该行上搜索匹配项。
  3. 每次找到匹配项时,都将其及其偏移量存储起来。
  4. 完成该行后,从数组中选择最长的字符串。
  5. 将其信息打印到您的结果字符串中。
  6. 继续输入的下一行。

有一个用于正则表达式的系统C#程序集。

https://msdn.microsoft.com/en-us/library/system.text.regularexpressions.regex(v=vs.110).aspx

你可以这样做:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace ConsoleApplication1
{
    public class Program
    {
        public static void Main()
        {
            //var lines = File.ReadAllLines("C:\\text.txt");
            var lines = new List<string> { "aaabb", "ccddddd", "efffggggg" };

            var result = (
                from line in lines
                let matches = Regex.Matches(line, "(.)\\1+").Cast<Match>()
                let maxLen = matches.Max(match => match.Length)
                let maxMatch = matches.First(match => match.Length == maxLen)
                let index = line.IndexOf(maxMatch.Value)
                select string.Format("{0},{1}", maxMatch.Value, index)
            ).ToList();

            result.ForEach(Console.WriteLine);
        }
    }
}

以下内容将为您提供所需的结果,并在O(n)时间内运行。

var lines = new List<string> { "aaabb", "ccddddd", "efffggggg" };

foreach (var line in lines)
{
    if (string.IsNullOrEmpty(line)) // if the line is null or empty then skip it.
    {
        Console.WriteLine("Empty or Null string.");
        continue;
    }

    char prev = line[0]; // The previous character seen starts with the first character
    int maxSeen = 0; // The maximum number of consecutive chars seen
    int maxSeenIndex = -1; // The index of the maximum seen chars.
    int currentSeen = 1; // The current number of consecutive chars seen.
    int currentSeenIndex = 0; // The index of the current chars seen.
    for (int i = 1; i < line.Length; i++) // Start at 1 to skip the first character.
    {
        if (prev == line[i]) // If the current character is the same as the previous
        {
            currentSeen++; // increment the number of current chars seen.
        }
        else // If the current character is different
        {
            if (currentSeen > maxSeen) // Check if the current Seen is more than max
            {
                maxSeen = currentSeen;
                maxSeenIndex = currentSeenIndex;
            }

            currentSeen = 1; // reset the current seen to 1
            currentSeenIndex = i; // set the current seen index to the current index
        }

        prev = line[i]; // set the current char to the previous
    }

    if (currentSeen > maxSeen) // Have to do this check again 
    {
        maxSeen = currentSeen;
        maxSeenIndex = currentSeenIndex;
    }

    Console.WriteLine(line.Substring(maxSeenIndex, maxSeen) + ", " + maxSeenIndex);
}

下面是对给定行执行所需操作的函数:

 public static string GetCharacterRepetitionAndPosition(string s)
    {
        if (string.IsNullOrWhiteSpace(s))
            return s;

        var result = (from ch in s
                      group ch by ch into g
                      select new { Cnt = g.Count(), Ch = g.Key });
        var maxCnt = -1;
        char theMaxChar =char.MinValue;
        int howManyCharacters;
        foreach (var item in result)
        {
            if (item.Cnt > maxCnt)
            {
                maxCnt = item.Cnt;
                theMaxChar = item.Ch;
                howManyCharacters = item.Cnt;
            }
        }


        var idx = s.IndexOf(theMaxChar);
        return new string(theMaxChar,maxCnt) + "," + idx;
    }

用法是:

 using (var fileStream = new FileStream(Path, FileMode.Open, FileAccess.Read))
        {
            using (var streamReader = new StreamReader(fileStream))
            {
                var line = streamReader.ReadLine();
                var res = GetCharacterRepetitionAndPosition(line);

                // do whatever you want with this output
                Console.WriteLine(res);
            }
        }

算法复杂度分析:

1)groupby的选择为O(N)

2)结果的foreach也为O(N)

3)IndexOf()调用为O(N)

因此总复杂度(大O)为O(N)

这是怎么回事:

1)我们首先按照角色的外貌对所有角色进行分组,然后计算一组中有多少字符。

2)我们对这个结果进行迭代,并且记住角色的最大分配数以及角色是什么

3)我们返回一个字符串(具有最高幻影的字符)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM