我已经实现了我的快速版本(no Regex
、no Split
、no Substring
、noReplace
和其他字符串操作方法)。要复制字符串,我正在使用String.CopyTo
它将符号复制到普通char
数组。
此代码完全支持嵌套 Spintaxes(可能无限深度)。一个限制是每个 Spintax 的最大选项数,目前是 100,但可以更改为 1000 或更多...另一个限制是输入字符串的最大长度,现在是 100000,但也可以增加。
关于性能 - 我的测试表明,此代码比任何优化的 Regex 解决方案(包括 Jim Mischel 的解决方案)快 15 倍以上,比使用 Substring 和其他字符串操作方法的版本快约 5 倍。我已经在 VS 2012 中使用优化代码设置在发布模式下对此进行了测试。
static int[] partIndices = new int[100];
static int[] depth = new int[100];
static char[] symbolsOfTextProcessed = new char[100000];
public static String SpinEvenMoreFaster(String text)
{
int cur = SpinEvenMoreFasterInner(text, 0, text.Length, 0);
return new String(symbolsOfTextProcessed, 0, cur);
}
public static int SpinEvenMoreFasterInner(String text, int start, int end, int symbolIndex)
{
int last = start;
for (int i = start; i < end; i++)
{
if (text[i] == '{')
{
int k = 1;
int j = i + 1;
int index = 0;
partIndices[0] = i;
depth[0] = 1;
for (; j < end && k > 0; j++)
{
if (text[j] == '{')
k++;
else if (text[j] == '}')
k--;
else if (text[j] == '|')
{
if (k == 1)
{
partIndices[++index] = j;
depth[index] = 1;
}
else
depth[index] = k;
}
}
if (k == 0)
{
partIndices[++index] = j - 1;
int part = rand.Next(index);
text.CopyTo(last, symbolsOfTextProcessed, symbolIndex, i - last);
symbolIndex += i - last;
if (depth[part] == 1)
{
text.CopyTo(partIndices[part] + 1, symbolsOfTextProcessed, symbolIndex, partIndices[part + 1] - partIndices[part] - 1);
symbolIndex += partIndices[part + 1] - partIndices[part] - 1;
}
else
{
symbolIndex = SpinEvenMoreFasterInner(text, partIndices[part] + 1, partIndices[part + 1], symbolIndex);
}
i = j - 1;
last = j;
}
}
}
text.CopyTo(last, symbolsOfTextProcessed, symbolIndex, end - last);
return symbolIndex + end - last;
}