简体   繁体   中英

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 ).

For example:

Original String: "abcdefgabfabc"

Expected output: "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...

  1. Create a Dictionary of letters and the # of occurrences of each letter
  2. Create a StringBuilder to store the output
  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
  6. If a letter is already in the dictionary, increase the value by 1 and append the value to the output string

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.

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.

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. The right solution is really what D Stanley and I hinted to. 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();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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