简体   繁体   English

将重复的char替换为字符串中的其他内容

[英]Replace repeated char with something else in a string

I need help to figure out a logic: 我需要帮助来找出一个逻辑:

So, let's say I have a string, and whenever there is a Char repeated inside that string , I need to replace it with a ( Char + sequence of number ). 所以,假设我有一个字符串,每当在该string重复出现Char时,我需要将其替换为( Char + sequence of number )。

For example: 例如:

Original String: "abcdefgabfabc" 原始字符串: "abcdefgabfabc"

Expected output: "abcdefga2b2f2a3b3c2" 预期输出: "abcdefga2b2f2a3b3c2"

'a' occurs 3 times, so the first 'a' remains as 'a', but the second 'a' becomes 'a2', and the third 'a' becomes 'a3' and the same goes to other chars like b, b2, b3... 'a'出现3次,所以第一个'a'保持为'a',但第二个'a'变为'a2',第三个'a'变为'a3',同样的变为'b'等其他字符, b2,b3 ......

  1. Create a Dictionary of letters and the # of occurrences of each letter 创建字母Dictionary和每个字母的出现次数
  2. Create a StringBuilder to store the output 创建一个StringBuilder来存储输出
  3. Loop through the input string letter by letter 逐字循环输入字符串
  4. Output the letter to the new string 将字母输出到新字符串
  5. If a letter is not in the dictionary, add it as the key with a '1' as the value 如果字母不在字典中,请将其添加为键,并以“1”作为值
  6. If a letter is already in the dictionary, increase the value by 1 and append the value to the output string 如果字母已经在字典中,请将值增加1并将值附加到输出字符串

Try this: 试试这个:

var foundChars = new SortedDictionary<char, int>();
var stringBuilder = new StringBuilder();

foreach (var c in originalString)
{
    var count = 0;

    if (!foundChars.TryGetValue(c, out count)
    {
        foundChars.Add(c, 1);
    }
    else
    {
        count += 1;
        foundChars[c] = count;
    }

    stringBuilder.Append(c);
    if (count > 0) stringBuilder.Append(count);
}

Note that while less pretty this will be more performant than LINQ based solutions and be retrocompatible with .NET 2.0. 请注意,虽然不太漂亮,但它比基于LINQ的解决方案更具性能,并且与.NET 2.0具有后向兼容性。

var str = "abcdefgabfabc";
var chars = str.Select((c, index) =>
        {
            int count = str.Substring(0, index).Count(x => c == x);
            if (count > 0) return c.ToString() + (count+1);
            else return c.ToString();
        }).SelectMany(c => c).ToArray();
var result = new string(chars); // abcdefga2b2f2a3b3c2

I would use LINQ to iterate over each character, and then keep a counter of each one you encounter along the way. 我会使用LINQ迭代每个角色,然后保持你在路上遇到的每个角色的计数器。

For example.. 例如..

var count = new Dictionary<string, int>();
var string = "abcdefabcdef";
var result = "";

string.Select().Each(c => {
    if (count.ContainsKey(c)) 
        count.Add(c, 1);
    else
        count[c]++;
    result += count[c] > 1? c + count[c] : c;
});

Some of the other answers suffers from being O(n^2) ( Selman22 , Stumblor ) or O(n*log n) ( Chrono1981 ) even though a O(n) solution is simple. 一些其他答案的缺点O(n^2)Selman22Stumblor )或O(n*log n)Chrono1981 ),即使O(n)解决方案很简单。 The right solution is really what D Stanley and I hinted to. 正确的解决方案正是D Stanley和我所暗示的。 Here it goes: 在这里:

var input = "abcdefgabfabc";
var counts = new Dictionary<char, int>();

var sb = new StringBuilder();

foreach (var c in input)
{
    int count;
    counts.TryGetValue(c, out count);  // If "counts" doesn't have the key, then count will be 0
    counts[c] = ++count;

    sb.Append(c);

    if (count > 1)
        sb.Append(count);
}

var result = sb.ToString();

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

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