在C#中有没有更有效的方法来计算关联矩阵?
我使用带元组键的字典实现了一个算法,该算法工作正常,但速度非常慢。我有一套弦。我试图实现一个关联矩阵,其中在C#中有没有更有效的方法来计算关联矩阵?,c#,algorithm,matrix,C#,Algorithm,Matrix,我使用带元组键的字典实现了一个算法,该算法工作正常,但速度非常慢。我有一套弦。我试图实现一个关联矩阵,其中A[“abc”,“bcde”]=2,两个字符串的重叠量。L中的元组是A中的键。L是排序数组=>A[L[i]]1) { 字符串LastItem1=L.Last().Item1; 字符串LastItem2=L.Last().Item2; 删除(最后一项1); 删除(最后一项2); 字符串newElement=merge(LastItem1,LastItem2); 添加(新元素); for(int
A[“abc”,“bcde”]
=2,两个字符串的重叠量。L中的元组是A中的键。L是排序数组=>A[L[i]]
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>>();
List words=新列表(wordsFromFile);
字典A=新字典();
列表L=新列表();
(我使用计数排序生成L。之后刷新矩阵和列表非常耗时:)
while(words.Count>1)
{
字符串LastItem1=L.Last().Item1;
字符串LastItem2=L.Last().Item2;
删除(最后一项1);
删除(最后一项2);
字符串newElement=merge(LastItem1,LastItem2);
添加(新元素);
for(int i=0;if.Key.Item1==LastItem1 | | f.Key.Item1==LastItem2 | | f.Key.Item2==LastItem1 | | f.Key.Item2==LastItem2.ToArray();
foreach(itemsToRemove中的变量项)
A.移除(项.键);
L.删除(L.Last());
对于(int i=0;if.Item1==LastItem1 | | f.Item2==LastItem2 | | f.Item1==LastItem2 | | f.Item2==LastItem1.ToArray();
foreach(listitemsToRemove中的var项)L.Remove(项);
listitemsToRemove=L.Where(f=>f.Item2==LastItem2.ToArray();
}
字典速度惊人,这不是你的问题。你真的应该发布一个。字典速度惊人,这不是你的问题。你真的应该发布一个。
列表基本上是一个数组,也许你把它与链接列表
混淆了?特别是因为你谈到“通过记忆跟踪linkedlist”。这里没有。您的bullet#2似乎也在讨论链表,尽管它没有按名称这样说。它不是,它指的是循环性能。我将尝试找到一个链接添加到它。从研究中发现,对于基于索引的查找,数组似乎比c#中的列表更快,这意味着不需要多次将其作为数组进行查找,也可以缓存该结果(会有一些小的改进)。Foreach有助于实现这一点,但代价是额外增加2个运行时变量。如果您使用这些额外的变量,那么它可能是冒险的(有时)。计数不同(这里的是直接调度(实际上是内联的)的System.Collections.Generic.List.Count
属性,链接的是System.Linq.Enumerable.Count()
扩展方法,多态调度)列表
基本上是一个数组,可能您有点困惑
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();
}