我知道该功能将包含大量数据处理,但我认为最终不会花费很多细节来处理。
有问题的函数被馈入一个锯齿状2D数组,该数组由“段落”>“句子”组成,该数组是由用户馈送的文本文件制成的,因此可能很大。它使用此数组,将每个句子彼此进行比较,并保存每个句子之间的分数,即常见单词的数量。
这需要永远,我坦白地认为不会。
我的主要测试文本只有181个句子,但这意味着在2D数组中得分为3.27万个值。
然后,该值矩阵用于从每个段落和其他内容中计算和选择最“相关”的句子。
181个句子的文本需要1分15秒来处理,只有70个句子的文本需要35秒,但这是基于句子的数量而不是单词,但是它给了您一个想法。我担心要花多长时间才能完成一份实际文件。
有问题的功能:
protected void Intersection2DArray()
{
mainSentenceCoord = -1;
for (int x1 = 0; x1 < results.Length; x1++)
{
for (int x2 = 0; x2 < results[x1].Length; x2++)
{
var mainSentencesWords = wordSplit(results[x1][x2]);
secondarySentenceCoord = -1;
mainSentenceCoord++;
for (int y1 = 0; y1 < results.Length; y1++)
{
for (int y2 = 0; y2 < results[y1].Length; y2++)
{
var secondarySentencesWords = wordSplit(results[y1][y2]);
int commonElements = mainSentencesWords.Intersect(secondarySentencesWords).ToList().Count();
secondarySentenceCoord++;
intersectionArray[mainSentenceCoord, secondarySentenceCoord] = commonElements;
}
}
}
}
}
wordSplit函数:
protected List<String> wordSplit(string sentence)
{
var symbols = "£$€#&%+-.";
var punctuationsChars = Enumerable.Range(char.MinValue, char.MaxValue - char.MinValue)
.Select(i => (char)i)
.Where(c => char.IsPunctuation(c))
.Except(symbols)
.ToArray();
var words = sentence.Split(punctuationsChars)
.SelectMany(x => x.Split())
.Where(x => !(x.Length == 1 && symbols.Contains(x[0])))
.Distinct()
.ToList();
return words;
}
我最初想使用一个Regex行进行此拆分,但不会弄清楚,这可能会使它更快。
这样循环选择彼此相对的每个句子,这是我最好的选择。如果可以大幅度提高速度,那么我总体上会很好。
编辑:使用Moby Disk建议在这里是我的新即时代码:
Word Split函数,该函数现在被调用一次并返回列表列表
public List<List<string>> createWordList()
{
List<List<string>> wordList = new List<List<string>>();
var symbols = "£$€#&%+-.";
var punctuationsChars = Enumerable.Range(char.MinValue, char.MaxValue - char.MinValue)
.Select(i => (char)i)
.Where(c => char.IsPunctuation(c))
.Except(symbols)
.ToArray();
for (int x1 = 0; x1 < results.Length; x1++)
{
for (int x2 = 0; x2 < results[x1].Length; x2++)
{
var words = results[x1][x2].Split(punctuationsChars)
.SelectMany(x => x.Split())
.Where(x => !(x.Length == 1 && symbols.Contains(x[0])))
.Distinct()
.ToList();
wordList.Add(words);
}
}
return wordList;
}
现在超薄的交叉口功能
protected void intersectionMatrix()
{
List<List<string>> wordList = createWordList();
mainSentenceCoord = -1;
for (var x = 0; x < wordList.Count; x++)
{
secondarySentenceCoord = -1;
mainSentenceCoord++;
for (var y = 0; y < wordList.Count; y++)
{
secondarySentenceCoord++;
intersectionArray[mainSentenceCoord, secondarySentenceCoord] = wordList[x].Intersect(wordList[y]).Count();
}
}
}
最佳答案
请参阅最后的更新:
这里有一些“低落的果实”,可以在不更改算法本身的情况下加快速度:
每次调用wordSplit()都会重新计算“标点符号”。一次做一次。
您正在为同一句子调用wordSplit()N ^ 2次而不是N次,因为它同时在外部(x1,x2)循环和内部(y1,y2)循环中。您只需要拆分181个句子,而无需拆分181 ^ 2个句子。因此,请遍历结果,在每个句子上调用一次wordSplit,然后存储该结果。如果这占用过多内存,请查看记忆(http://en.wikipedia.org/wiki/Memoization),尽管我认为您应该没问题,因为它只会导致多出大约1份文本。
您在Intersect()之后不需要ToList()。这将创建一个您不使用的列表。
我对mainSentenceCoord和secondarySentenceCoord的值感到困惑。结果交集数组的尺寸是多少?
我的天啊! #1是!这使速度提高了80倍。看这行:
Enumerable.Range(char.MinValue, char.MaxValue - char.MinValue)
char.MaxValue是65536。因此,如果N = 181,则循环181 x 181 x 65536!我只是运行了探查器来确认它:98.4%的CPU时间花费在wordSplit的ToArray()调用中。
关于c# - 嵌套循环功能需要几分钟才能运行,反正可以提高效率?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28221449/