用数学形式替换连续的数字



我正在研究压缩算法,我想用它的数学形式替换所有连续数。它在数学上不是逻辑的,但我的算法会知道并将其转换为原始形式。
假设我有字符串:

string input = "732183900000000000002389288888888888888";

您是否看到它有00000000008888888888是主要的连续重复
现在我想把它们转换成:

//convert 000000000 to 0*9. Means 9 times 0.
//convert 888888888 to 8*9. Means 8 times 0.
string output = "7321839" +
"0*13"    +
"23892"   +
"8*14";
//or
string output = "7321839-0*13-23892-8*14";

需要考虑的要点:
窗口上运行的任何语言都将被接受。对我来说,最重要的是算法
请记住性能,因为它将用于文件。

老实说,这很简单:

  • 一次分析一个字符串
  • 检查上一个字符是否与当前字符相同
  • 如果相同,则递增计数器变量或将其重置为0
  • 当我们将计数器重置为0时,如果计数器值大于1,则在结果中添加*

Regex可能对此有点复杂,因为有破折号规则(尽管并非不可能(,

看起来,你想要以下

  1. 相同数量的组大于1的计数
  2. 无前缀破折号
  3. 无后缀破折号
  4. 没有双破折号(推测性(

这里有一个相当有效的带有StringBuilder的C#O(n(实现,它应该允许您使用最小分配处理超大字符串

给定

public static string Shorten(string value)
{
var sb = new StringBuilder(value.Length);
int i, last;
var isLastGroup = false;
void Write()
{
var isGroup = i - last > 1;
var getDash = last == 0 || isLastGroup ? "" : "-";
sb.Append(isGroup ? $"{getDash}{value[last]}*{i - last}{(i != value.Length ? "-" : "")}" : value[last].ToString());
isLastGroup = isGroup;
last = i;
}
for (i = 0, last = 0; i < value.Length; i++)
if (value[last] != value[i])
Write();
Write();
return sb.ToString();
}

测试

Console.WriteLine(Shorten("1"));
Console.WriteLine(Shorten("111"));
Console.WriteLine(Shorten("1112"));
Console.WriteLine(Shorten("1222"));
Console.WriteLine(Shorten("12233344445555512345"));

结果

1
13
1
3-23
1-2
2-33-44-5*5-12345

此处的完整演示

相关内容

  • 没有找到相关文章

最新更新