用于搜索(大)未排序数组的索引(类型)
Index (type) for searching (large) unsorted array
我有一个程序可以将(有时)大型 CSV 文件加载到数组中。数据无法排序,不知道数据是文本还是数字。这取决于客户。
示例可以是
1;JOHN;DOE
2;JANE;DOE;
3;BOBBY;NOTABLES
但也可以是字符串
MB9384HJ;TEST1
B9284918;TEST2
行数可达几百万
我想在列中搜索特定值(提前知道哪个值,这是我的“关键索引列”)。假设这是唯一的。关键是找到这一列在哪一行。
目前代码正在从1..n开始遍历比较。这显然在最后变慢了。
我正在考虑这些选项:
- 一个带有键索引值和记录数的内存SQLite数据库
- 一个带键的TStringDictionary,记录为对
- 一个哈希字符串列表
我的想法是:不遍历数组,而是通过索引查询key(客户端提供要搜索的item,必须是随机访问的)。然后立马拿到数组的rownumber,就可以取数据了
哪一条(或其他,如果有的话)是更好的路径?
如果你只想搜索键,SQLite 可能太多了。如果您用 CSV 填充 SQLite table 并且不仅要对键而且还要对其他列进行复杂查询,那将会很有趣。
散列字符串列表可能更快,但存在散列冲突问题。
字典可能是您特定情况下的最佳解决方案。这很容易,因为 Delphi RTL 提供了所需的通用 class.
虽然较新的 Delphi (2009+) 内置了 TDictionary,这里(一种可能的)解决方案适用于较旧的 Delphi 版本。
这是使用 Delphi Fundamentals 5,它甚至可以为 D6 编译。
uses
flcDataStructs;
//...
var
thedict : TIntegerDictionary;
i : integer;
begin
thedict := TIntegerDictionary.Create;
thedicnr.DuplicatesAction := ddIgnore; // should there be duplicates in my key column
for i := 0 to length(dataarray)-1 do
begin
thedict.Add(dataarray[i], i);
end;
end;
// to use:
// rownumber := thedict['stringToSearch'];
我有一个程序可以将(有时)大型 CSV 文件加载到数组中。数据无法排序,不知道数据是文本还是数字。这取决于客户。
示例可以是
1;JOHN;DOE
2;JANE;DOE;
3;BOBBY;NOTABLES
但也可以是字符串
MB9384HJ;TEST1
B9284918;TEST2
行数可达几百万
我想在列中搜索特定值(提前知道哪个值,这是我的“关键索引列”)。假设这是唯一的。关键是找到这一列在哪一行。
目前代码正在从1..n开始遍历比较。这显然在最后变慢了。
我正在考虑这些选项:
- 一个带有键索引值和记录数的内存SQLite数据库
- 一个带键的TStringDictionary,记录为对
- 一个哈希字符串列表
我的想法是:不遍历数组,而是通过索引查询key(客户端提供要搜索的item,必须是随机访问的)。然后立马拿到数组的rownumber,就可以取数据了
哪一条(或其他,如果有的话)是更好的路径?
如果你只想搜索键,SQLite 可能太多了。如果您用 CSV 填充 SQLite table 并且不仅要对键而且还要对其他列进行复杂查询,那将会很有趣。
散列字符串列表可能更快,但存在散列冲突问题。
字典可能是您特定情况下的最佳解决方案。这很容易,因为 Delphi RTL 提供了所需的通用 class.
虽然较新的 Delphi (2009+) 内置了 TDictionary,这里(一种可能的)解决方案适用于较旧的 Delphi 版本。
这是使用 Delphi Fundamentals 5,它甚至可以为 D6 编译。
uses
flcDataStructs;
//...
var
thedict : TIntegerDictionary;
i : integer;
begin
thedict := TIntegerDictionary.Create;
thedicnr.DuplicatesAction := ddIgnore; // should there be duplicates in my key column
for i := 0 to length(dataarray)-1 do
begin
thedict.Add(dataarray[i], i);
end;
end;
// to use:
// rownumber := thedict['stringToSearch'];