【问题标题】:erroneous character fixing of strings in c#c#中字符串的错误字符修复
【发布时间】:2012-03-21 12:47:51
【问题描述】:

我有五个字符串,如下所示,

ABBCCD

ABBDCD

ABBDCD

ABBECD

ABBDCD

除了第四个字符外,所有字符串基本相同。但只有出现时间最长的角色才会出现。例如这里 D 被放置在第四位 3 次。因此,最后的字符串将是 ABBDCD。我编写了以下代码,但在时间方面似乎效率较低。因为这个函数可以被调用百万次。我应该怎么做才能提高性能?

这里 changedString 是要与其他 5 个字符串匹配的字符串。如果更改字符串的任何位置与其他四个不匹配,则最大出现的字符将放置在 changedString 上。

len 是字符串的长度,所有字符串都相同。

for (int i = 0; i < len;i++ )
{
    String findDuplicate = string.Empty + changedString[i] + overlapStr[0][i] + overlapStr[1][i] + overlapStr[2][i] +
                           overlapStr[3][i] + overlapStr[4][i];

    char c = findDuplicate.GroupBy(x => x).OrderByDescending(x => x.Count()).First().Key;
    if(c!=changedString[i])
    {
        if (i > 0)
        {
            changedString = changedString.Substring(0, i) + c +
                            changedString.Substring(i + 1, changedString.Length - i - 1);
        }
        else
        {
            changedString = c + changedString.Substring(i + 1, changedString.Length - 1);
        }
    }
    //string cleanString = new string(findDuplicate.ToCharArray().Distinct().ToArray());
}

【问题讨论】:

  • 我正在修复中,我该如何给出标题,好吧,我已经简短了。
  • 不,我正在做一个项目,为此我需要使用此功能。但是要花很多时间。
  • 首先,字符串连接很昂贵。请改用 StringBuilder。
  • 如果字符串是固定长度的,char[] 会更快。
  • @BryceWagner:这是一个很好的观点。如果我了解他们试图对子字符串部分做什么,我认为他们实际上不需要整个子字符串,只需要一个字符。

标签: c# string performance


【解决方案1】:

我不太确定你要做什么,但如果是关于按第 n 个字符对字符串进行排序,那么最好的方法是使用计数排序 http://en.wikipedia.org/wiki/Counting_sort 它用于对小数组进行排序整数,对于字符来说非常好。它具有线性 O(n) 时间。主要思想是,如果您知道所有可能的元素(看起来它们在这里只能是 A-Z),那么您可以创建一个额外的数组并计算它们。对于您的示例,如果我们将 0 用于“A”,将 1 用于“B”等等,它将是 {0, 0, 1 ,3 , 1, 0,...}。

【讨论】:

    【解决方案2】:

    有一个功能可能有助于提高性能,因为它的运行速度提高了五倍。这个想法是使用字典自己计算出现次数,将字符转换为位置到计数数组,在该位置增加值并检查它是否大于以前的最高出现次数。如果是,则当前字符位于顶部并作为结果存储。这对overlapStr 中的每个字符串和字符串中的每个位置重复。请阅读 cmets inside code 以查看详细信息。

    string HighestOccurrenceByPosition(string[] overlapStr)
    {
        int len = overlapStr[0].Length;
        //  Dictionary transforms character to offset into counting array
        Dictionary<char, int> char2offset = new Dictionary<char, int>();
        //  Counting array. Each character has an entry here
        int[] counters = new int[overlapStr.Length];
        //  Highest occurrence characters found so far
        char[] topChars = new char[len];
    
        for (int i = 0; i < len; ++i)
        {
            char2offset.Clear();
            //  faster! char2offset = new Dictionary<char, int>();
            //  Highest number of occurrences at the moment
            int highestCount = 0;
            //  Allocation of counters - as previously unseen character arrives 
            //  it is given a slot at this offset
            int lastOffset = 0;
            //  Current offset into "counters"
            int offset = 0;
            //  Small optimization. As your data seems very similar, this helps
            //  to reduce number of expensive calls to TryGetValue
            //  You might need to remove this optimization if you don't have 
            //  unused value of char in your dataset
            char lastChar = (char)0;
    
            for (int j = 0; j < overlapStr.Length; ++ j)
            {
                char thisChar = overlapStr[j][i];
                //  If this is the same character as last one
                //  Offset already points to correct cell in "counters"
                if (lastChar != thisChar)
                {
                    //  Get offset
                    if (!char2offset.TryGetValue(thisChar, out offset))
                    {
                        //  First time seen - allocate & initialize cell
                        offset = lastOffset;
                        counters[offset] = 0;
                        //  Map character to this cell
                        char2offset[thisChar] = lastOffset++;
                    }
                    //  This is now last character
                    lastChar = thisChar;
                }
                //  increment and get count for character
                int charCount = ++counters[offset];
                //  This is now highestCount.
                //  TopChars receives current character
                if (charCount > highestCount)
                {
                    highestCount = charCount;
                    topChars[i] = thisChar;
                }
            }
        }
        return new string(topChars);
    }
    

    附:这当然不是最好的解决方案。但由于它比原来的要快得多,我想我应该帮忙。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-08-29
      • 1970-01-01
      • 2019-01-25
      • 2023-03-30
      • 2010-10-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多