как заменить повторяющиеся символы

К примеру юзер вводит "esyyy hgrrk", а заменить нужно на подобный формат:"esy2 hgr1k". Я предпринимал попытки вводимый текст в string форматировать в char array, а уже в нём проводить итерации с помощью цикла for, в котором происходила проверка: если прошлыйСимвол == настоящийСимвол, то число итератора присваивалось в целочисленный массив как позиция повторяющегося символа. Но так не работает. Подскажите, каким образом можно реализовать замену символа на цифру?

private void button1_Click(object sender, EventArgs e)
{
    char[] tmparr = new char[textBox1.Text.Length];
    int[] tmpp = new int[5];
    tmparr = textBox1.Text.ToCharArray();
    int j = 0;
    for (i = 2; i < textBox1.Text.Length; i++)
    {
        char prev = tmparr[i - 1];
        if (tmparr[i] == prev)
        {
            tmpp[j] = i;
            j++;
        }

        i++;
    }
    textBox2.Text = String.Concat<int>(tmpp);
}

Ответы (5 шт):

Автор решения: motpfofs

Попробуйте воспользоваться этим кодом:

var testString = "qjjjjfeeeefqpvnrrr";
char[] charArray = testString.ToCharArray();

StringBuilder sb = new StringBuilder();

for (int i = 0; i < charArray.Length; i++)
{
    sb.Append(charArray[i]);

    int j = 1;
    while (i + j< charArray.Length && charArray[i] == charArray[i + j])
    {
        j++;
    }
    if (j > 1)
    {
        sb.Append(j.ToString());
        i = i + j - 1;
    }
}
→ Ссылка
Автор решения: aepot

Можно реализовать с помощью StringBuilder

private void button1_Click(object sender, EventArgs e)
{
    StringBuilder sb = new StringBuilder();
    int repeatCounter = 0;
    char lastChar = default(char);
    foreach (char c in textBox1.Text)
    {
        if (lastChar == c)
            repeatCounter++;
        else
        {
            if (repeatCounter > 0)
            {
                sb.Append(repeatCounter);
                repeatCounter = 0;
            }
            sb.Append(c);
            lastChar = c;
        }
    }
    textBox2.Text = sb.ToString();
}
→ Ссылка
Автор решения: bocman THN

Не понял зачем инкрементировать итератор в цикле. Тип такого можно использовать.

string repeatChars = "ddeeeeccciiiiiiiisioooon"; string noRepeatChars = repeatChars[0].ToString();

  for (int i = 1; i < repeatChars.Length; i++)
    if (repeatChars[i] == repeatChars[i - 1])
      continue;
    else
      noRepeatChars += repeatChars[i];

  Console.WriteLine($"Было: {repeatChars} \r\nСтало:{noRepeatChars}");
→ Ссылка
Автор решения: tym32167

Просто еще один вариант в копилку

var str = "esyyy hgrrk";
var start = 0;
var sb = new StringBuilder();

while(start < str.Length)
{
    var end = start; 
    while(end < str.Length && str[end] == str[start]) end++;
    int count = end - start;        
    sb.Append(str[start]);
    if (count > 1) sb.Append(count-1);
    start = end;        
}

Console.WriteLine(sb.ToString());
→ Ссылка
Автор решения: tym32167

Не самый изящный Linq вариант :)

var str = "esyyy hgrrk";

var ret = str.Aggregate(new Stack<(char c, int count)>(), (s, c) => {
    if (s.Count == 0 || s.Peek().c!=c) s.Push((c,1));
    else s.Push((c, s.Pop().count+1));
    return s;
})
.Reverse()  
.Aggregate(new StringBuilder(), (s, pair) => {
    s.Append(pair.c);
    if (pair.count > 1) s.Append(pair.count-1);
    return s;
});

Console.WriteLine(ret.ToString());
→ Ссылка