我使用带有元组键的字典实现了一个算法,算法有效,但速度非常慢。我有一组字符串。我试图实现一个关联矩阵,其中A["abc","bcde"]
= 2,两个字符串的重叠量。 L中的元组是A中的键.L是排序数组=> A [L [i]]< A [L [I + 1]]
我将两个字符串合并到集合中最大的重叠,然后我更新"矩阵"和L列表。我在循环中执行它,直到该集合只有1个元素。我的问题是,使用字典算法太慢了。有没有更有效的方法来做到这一点?这是我的代码:
List<string> words = new List<string>(wordsFromFile);
Dictionary<Tuple<string, string>, int> A = new Dictionary<Tuple<string, string>, int>();
List<Tuple<string, string>> L = new List<Tuple<string,string>>();
(我使用计数排序来制作L.在刷新矩阵之后,列表非常耗时:)
while (words.Count > 1)
{
string LastItem1 = L.Last().Item1;
string LastItem2 = L.Last().Item2;
words.Remove(LastItem1);
words.Remove(LastItem2);
string newElement = merge(LastItem1, LastItem2);
words.Add(newElement);
for (int i = 0; i < words.Count; ++i)
{
if (words[i] == newElement)
{
Tuple<string, string> tmp = new Tuple<string, string>(newElement, newElement);
A[tmp] = 0;
}
else
{
Tuple<string, string> tmp = new Tuple<string, string>(newElement, words[i]);
A[tmp] = A[new Tuple<string, string>(LastItem2, words[i])];
tmp = new Tuple<string, string>(words[i], newElement);
A[tmp] = A[new Tuple<string, string>(words[i], LastItem1)];
}
}
var itemsToRemove = A.Where(f => f.Key.Item1 == LastItem1 || f.Key.Item1 == LastItem2 || f.Key.Item2 == LastItem1 || f.Key.Item2 == LastItem2).ToArray();
foreach (var item in itemsToRemove)
A.Remove(item.Key);
L.Remove(L.Last());
for (int i = 0; i < L.Count(); ++i)
{
if (L[i].Item1 == LastItem2 && L[i].Item2 != LastItem1 && L[i].Item2 != newElement && L[i].Item2 != LastItem2) L[i] = new Tuple<string, string>(newElement, L[i].Item2);
else if (L[i].Item2 == LastItem1 && L[i].Item1 != LastItem1 && L[i].Item1 != newElement && L[i].Item1 != LastItem2) L[i] = new Tuple<string, string>(L[i].Item1, newElement);
}
var listitemsToRemove = L.Where(f => f.Item1 == LastItem1 || f.Item2 == LastItem2 || f.Item1 == LastItem2 || f.Item2 == LastItem1).ToArray();
foreach (var item in listitemsToRemove) L.Remove(item);
listitemsToRemove = L.Where(f => f.Item2 == LastItem2).ToArray();
}
答案 0 :(得分:0)
难以阅读高度混淆的代码,但有一件事突然出现在我身上:
L [I] .Item1
与字典相比,这是次优的。我想你可能想要保留订购,在这种情况下你可以使用OrderedDictionary&lt;&gt;
您使用的for循环可以在您的案例中通过foreach循环进行优化。确实,for循环的原始性能更快,但不是你使用它的方式。你在L上做了大约12次查找,这是一个列表。它不是一个数组,它是一个列表,因此在列表中间挑选项目会随着时间的推移而失去速度。 Foreach针对这种特定情况进行了优化,如果迭代一个列表,则会更快速地进行头对头(除非你引入一个int计数器,在这种情况下循环更快)。
单词[i]正在进行3次查找(与foreach循环相比效率低下),它会查找一次