因为您正在接收要以流式方式搜索的文本正文,所以“预处理”文本以进行更有效的搜索是没有意义的。这是 C# 中的一个有效实现,它以流方式处理要搜索的文本。
static IEnumerable<int> Search(string text, string query)
{
var D = new Dictionary<int, int>();
//Loop invariant: D[i] == j iff text[i..(i+j)] == query[0..j]
// for all pairs (i,j) in D
for (int i = 0; i < text.Length; i++)
{
foreach (var k in D.Keys.ToList())
{
D[k] = D[k] + 1;
if (D[k] == query.Length)
{
yield return k;
D.Remove(k);
}
else if (text[i] != query[D[k]])
{
D.Remove(k);
}
}
if (text[i] == query[0])
D.Add(i, 0);
}
foreach (var k in D.Keys)
{
if (D[k] == query.Length)
yield return k;
}
}
基于流的版本可以如下实现。我认为可能无法正确处理流结束的情况,但是您应该能够使该想法适应即使在这种边缘情况下也有效的东西。
class SearcherState
{
public Dictionary<int, int> D = new Dictionary<int, int>();
public int i = 0;
}
static Func<char, int?> Searcher(string query)
{
var state = new SearcherState();
return c =>
{
int? result = null;
foreach (var k in state.D.Keys.ToList())
{
state.D[k] = state.D[k] + 1;
if (state.D[k] == query.Length)
{
result = k;
state.D.Remove(k);
}
else if (c != query[state.D[k]])
{
state.D.Remove(k);
}
}
if (c == query[0])
state.D.Add(state.i, 0);
state.i++;
return result;
};
}