如何进行游程编码' EEDDDNE'到' 2E3DNE'?

时间:2018-01-31 15:50:21

标签: c# loops replace

说明:任务本身就是我们有13个字符串(存储在sor []数组中),如标题中的字符串或' EEENKDDDDKKKNNKDK' 我们必须以这样一种方式缩短它,即如果两个或两个以上相同的字母相邻,那么我们必须以' NumberoflettersLetter'

因此,根据此规则,' EEENKDDDDKKKNNKDK' 将变为' 3ENK4D3K2NKDK'

using System;

public class Program
{
    public static void Main(string[] args)
    {
        string[] sor = new string[] { "EEENKDDDDKKKNNKDK", "'EEDDDNE'" };

        char holder;
        int counter = 0;
        string temporary;
        int indexholder;
        for (int i = 0; i < sor.Length; i++)
        {
            for (int q = 0; q < sor[i].Length; q++)
            {
                holder = sor[i][q];
                indexholder = q;
                counter = 0;
                while (sor[i][q] == holder)
                {
                    q++;
                    counter++;
                }
                if (counter > 1)
                {
                    temporary = Convert.ToString(counter) + holder;
                    sor[i].Replace(sor[i].Substring(indexholder, q), temporary); // EX here
                }
            }
        }

        Console.ReadLine();
    }
}

抱歉,我没有明确错误,它说:

  

"The value of index and length has to represent a place inside the string (System.ArgumentOutOfRangeException) - name of parameter: length"

...但我不知道它有什么问题,也许这是一个小小的错误,也许整个事情搞砸了,所以这就是为什么我喜欢某个人帮我这个D: (Ps&#39; indexholder&#39;因为我需要它进行另一项练习)

修改

&#39; SOR&#39;是包含这些字符串的字符串数组(其中有13个),如标题或示例中提到的那样

2 个答案:

答案 0 :(得分:3)

在使用char迭代旧的char时,缩短相同的字符串就更难以构建新的字符串。如果您计划迭代添加到字符串,最好使用StringBuilder - 类而不是直接添加到字符串(性能原因)。

您可以使用IEnumerable.Aggregate函数简化您的方法,自动对您执行迭代:

using System; 
using System.Linq;
using System.Text;

public class Program
{ 
    public static string RunLengthEncode(string s)
    {
        if (string.IsNullOrEmpty(s)) // avoid null ref ex and do simple case
            return "";

        // we need a "state" between the differenc chars of s that we store here:
        char curr_c = s[0];  // our current char, we start with the 1st one
        int count = 0;       // our char counter, we start with 0 as it will be 
                             // incremented as soon as it is processed by Aggregate 
                             // ( and then incremented to 1)

        var agg = s.Aggregate(new StringBuilder(), (acc, c) =>   // StringBuilder
            // performs better for multiple string-"additions" then string itself 
        {
            if (c == curr_c)
                count++;  // same char, increment
            else
            {
                // other char
                if (count > 1) // store count if  > 1
                    acc.AppendFormat("{0}", count);
                acc.Append(curr_c); // store char

                curr_c = c; // set current char to new one
                count = 1; // startcount now is 1
            }
            return acc;
        });
        // add last things
        if (count > 1) // store count if  > 1
            agg.AppendFormat("{0}", count);
        agg.Append(curr_c); // store char

        return agg.ToString(); // return the "simple" string
    }

使用

进行测试
    public static void Main(string[] args)
    {
        Console.WriteLine(RunLengthEncode("'EEENKDDDDKKKNNKDK' ")); 

        Console.ReadLine();
    }
} 

"'EEENKDDDDKKKNNKDK' "的输出:

'3ENK4D3K2NKDK'

你的方法没有使用相同的字符串更像是这样:

var data = "'EEENKDDDDKKKNNKDK' ";
char curr_c = '\x0';           // avoid unasssinged warning 
int count = 0;                 // counter for the curr_c occurences in row
string result = string.Empty;  // resulting string

foreach (var c in data)        // process every character of data in order     
{
    if (c != curr_c)           // new character found
    {
        if (count > 1)         // more then 1, add count as string and the char
            result += Convert.ToString(count) + curr_c;
        else if (count > 0)    // avoid initial `\x0` being put into string
             result += curr_c;

        curr_c = c;            // remember new character
        count = 1;             // so far we found this one 
    }
    else
        count++;               // not new, increment counter
}

// add the last counted char as well
if (count > 1)
    result += Convert.ToString(count) + curr_c;
else
    result += curr_c;

// output
Console.WriteLine(data + " ==> " + result);

输出:

'EEENKDDDDKKKNNKDK'  ==>  '3ENK4D3K2NKDK'

不是在你的字符串上使用索引操作符[]而是必须全力以赴地使用索引,我使用foreach c in "sometext" ...,它将通过字符串进行char-wise - 更不用说了。

如果您需要对字符串的数组/列表(sor)进行行程编码,只需将代码应用于每个字符串(最好使用foreach s in yourStringList ...

答案 1 :(得分:2)

您可以使用正则表达式:

Regex.Replace("EEENKDDDDKKKNNKDK", @"(.)\1+", m => $"{m.Length}{m.Groups[1].Value}")

说明:

  • (.)匹配任何字符并将其放入组#1
  • \1+可以多次匹配组#1