我有100,000个字符串,每个字符串都有一个固定的有序索引值,如下所示:
Index String Value
0 XXXXXXXXXXXXXXXXXXXXX
1 XXXXXXXXXX
2 (empty string)
3 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
4 XXXXX
5 XXXXXXXXX
6 XXXXXXXXXXXXXXX
7 (empty string)
8 XX
9 XXXXXXXXXX
10 XXXXXXXXXXXXXXXXXXXXXXXXXX
... ...
99999 XXXXXXXXXXXXXXXXXXX
我的数据结构必须包含100,000个有序条目,并且一些(或许多)字符串值可能为空,至少最初是这样。每个索引值都是唯一的(顺序整数),除空字符串外,每个字符串值也是唯一的。为了在我的UI中显示,我通常只填充我的数据结构,将列表框绑定到它(指定了DisplayMember和ValueMember)。但在这种情况下,我只想显示不为空的字符串。因此,我可能需要遍历我的数据结构,并以类似于此的方式将适用的项目添加到列表框中:
foreach (item in MyDataStructure)
{
if (item.StringValue != string.Empty)
{
listBox1.Items.Add(item);
}
}
对我来说,能够始终保持每个字符串与其索引值之间的关系非常重要。正如您所料,我的用户需要添加/编辑/删除字符串。从理论上讲,所有这三个操作都归结为同样的事情:更新特定索引处的字符串值。要添加一个新字符串,我需要首先遍历我的数据结构,并确保在某处有一个空字符串,以便我可以用新字符串替换它。如果不存在空字符串,我的用户将需要“编辑”现有字符串或首先“删除”另一个字符串,因为我们正在处理固定数量的总字符串(100k)。从程序角度来看,“删除”字符串也只是在我的数据结构中的适当索引处用空/空字符串替换它。
我可以预见,我需要一个能够轻松完成以下任务的数据结构:
考虑到这些事情,任何人都可以推荐适合该任务的特定数据结构吗?我最初想的是一个带有键/值对的字典来保存每个索引/字符串。然后有人建议只使用数组,因为总大小是固定的,数组索引本身也可以作为每个字符串值的索引值。
答案 0 :(得分:2)
看到您List
中有一定数量的项目,并且您需要为每个项目编制索引,您只需要查看数组。
string[] arr = new string[100000];
您也可以访问阵列的LINQ
,以便符合您的条件。
//1
arr.Where(x => !string.IsNullOrEmpty(x)).Select(str => new { value = Array.IndexOf(arr, str), display = str });
//2
string str = arr[index];
//3
arr.Any(x => x == "SomeString");
答案 1 :(得分:0)
我的第一个想法是dual-dictionary。基本上保留两个词典:
Dictionary<int, string> // index-->value
Dictionary<string, int> // value-->index
让字典保持同步还有一些工作要做,但是如果按照价值进行大量搜索,那可能是值得的。
每次搜索某个值时,使用数组都需要进行线性搜索,因此我认为它不会是性能最佳的。
此外,如果您不在任何字典中存储空白/空值,则可以直接绑定到它们而无需进行任何过滤。
答案 2 :(得分:0)
当然有很多方法可以做到这一点,但你可以创建一个集合类,而不是使用非空字符串封装SortedDictionary<int, string>
。
答案 3 :(得分:0)
我认为你是以错误的方式解决这个问题......你的内存限制为5mb,而你将使用整个持有空字符串的东西?这个数据结构也会在5mb中保存吗?这限制了您可以容纳的字符串数量。字符串如何在此内存中保留?某种数据库?我不知道这是用于什么,但你真的认为你的用户将使用所有100,000个字符串吗?我非常怀疑。
我还是不明白键如何与字符串值相关,但是对于我来说,拥有100,000个项目的列表真的没有意义,很可能很多都是空字符串。这是浪费内存,更不用说它将创建的搜索/插入/删除开销。在考虑速度时,保留当前使用的列表只会更有意义。
如果可能的话,我建议使用NoSQL
数据库。您可以插入用户创建的字符串,从而为您提供索引值,并可以随意更新字符串。如果用户将字符串删除/设置为空字符串,则可以将其从数据库中删除(或者,因为您真的非常喜欢这个想法,所以将其设置为数据库中的空字符串)。继续插入,直到达到100,000字符串限制。