c# - 使用二进制搜索子字符串搜索数组字符串

标签 c# arrays binary-search

我有一个包含大约 200,000 条记录的 file.txt。

每条记录的格式为123456-99-Text。 123456 是唯一帐号,99 是我需要的位置代码(从 01 变为 99),文本无关紧要。这些帐号按顺序排序,并在文件中按 ac(111111、111112、111113 等)换行。

我制作了一个 visual studio 文本框和搜索按钮,让某人搜索帐号。帐号实际上有 11 位数字,但只有前 6 位数字。我把它写成字符串 actnum = textbox1.text.substring(0,6)

我写了一个 foreach (string x in file.readline('file.txt')) 和一个 if (x.contains(actnum)) 然后 string code = x.substring(8,2)) 语句。

该程序运行良好,但由于如果有人搜索不存在的帐号或列表底部的号码,会有太多记录,程序会锁定 10 秒,然后再转到“号码” not found"else 语句,或者花很长时间才能找到最后一条记录。

我的问题:

阅读有关二进制搜索的文章,我尝试尝试一种但没有成功。我似乎无法让数组或文件像合法的二进制搜索一样运行。有没有办法从 textbox1 中获取 6 位 actnum,将其与 6 位帐号的数组子字符串进行比较,然后从该特定行中获取子字符串 99 代码?

二分查找会有很大帮助!我可以取 555-555 并将其与记录文件的上半部分或下半部分进行比较,然后继续搜索直到我找到我需要的行,捕获整行,然后将 99 子串出来。我遇到的问题是我似乎无法对文件进行正确的整数转换,因为它同时包含数字和文本,因此我无法正确使用 <、>、= 符号。

如有任何帮助,我们将不胜感激。我目前使用的程序确实有效,但有时速度非常慢。

最佳答案

作为一种可能的解决方案(不一定是最好的),您可以将记录 ID 添加到 Dictionary<string, int> (如果所有记录 ID 都是数字,甚至是 Dictionary<long, int>),其中每个键是一行的 ID,每个值是行索引。当您需要查找特定记录时,只需查看字典(它会为您进行高效查找)并为您提供行号。如果该项不存在(不存在的 ID),您将无法在字典中找到它。

此时,如果记录 ID 存在于文件中,则您有一个行号 - 您可以将整个文件加载到内存中(如果它不是太大)或者只是查找正确的行并读入该行与数据。

为此,您必须至少遍历文件一次并收集所有行的所有记录 ID,并将它们添加到字典中。您不必实现二进制搜索 - 字典将在内部为您执行查找。

编辑:

如果您不需要特定行的所有数据,只需一位(如您提到的位置代码),您甚至不需要存储行号(因为您不需要返回到文件中的行)- 只需将位置数据存储为字典中的值。

我个人仍会存储行索引,因为根据我的经验,此类项目开始时规模较小,但最终会收集功能,并且在某个时刻您必须从文件中获取所有内容。如果您希望随着时间的推移会出现这种情况,只需将每一行的数据解析为一个数据结构并将其存储在字典中——这将使您 future 的生活更简单。如果您非常确定您永远不需要比一位信息更多的数据,您可以将数据本身存储在字典中。

这是一个简单的示例(假设您的记录 ID 可以解析为 long ):

public class LineData
{
    public int LineIndex { get; set; }

    public string LocationCode { get; set; }

    // other data from the line that you need
}

// ...

// declare your map
private Dictionary<long, LineData> _dataMap = new Dictionary<long, LineData> ();

// ...
// Read file, parse lines into LineData objects and put them in dictionary
// ...

要查看记录 ID 是否存在,您只需调用 TryGetValue() :

LineData lineData;

if ( _dataMap.TryGetValue ( recordID, out lineData ) )
{
    // record ID was found
}

这种方法本质上将整个文件保存在内存中,但所有数据只解析一次(在开始时,在构建字典期间)。如果此方法使用太多内存,只需将行索引存储在字典中,然后在找到记录并动态解析行时返回文件。

关于c# - 使用二进制搜索子字符串搜索数组字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27492460/

相关文章:

javascript - AngularJS - 在数组中单步执行数组

c - 二分查找输出错误

c# - 如何检查应用了哪些过滤器

c# - 需要一种方法来避免使用 BasicHttpBinding 的 wcf 服务中的响应消息

c - AVR gcc,奇怪的数组行为

c++ - 使用 boost::accumulators::statistics 查找数组的中位数

java - 使用二分查找查找数字的最大索引出现次数

c++ - 二进制搜索未收敛为 double

c# - DataObject.GetData() 无论如何都会返回 MemoryStream 类型的对象?

c# - 将文件(字节数组)的字符串表示形式转换回 C# 中的文件