Sho*_*oTo 7 c# arrays binary-search
我有一个包含大约200,000条记录的file.txt.
每条记录的格式为123456-99-Text.123456是唯一的帐号,99是我需要的位置代码(从01更改为99),文本无关紧要.这些帐号按顺序排序,并在每个交流的文件中有换行符(111111,11111,1111113等).
我制作了一个视觉工作室文本框和搜索按钮,让某人搜索帐号.帐号实际上是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秒钟,然后再转到"未找到号码"否则声明,或永远找到最后一条记录.
我的问题:
阅读二进制搜索我试图尝试一个没有太大成功.我似乎无法使数组或文件像合法的二进制搜索一样.有没有办法从textbox1中取出6位数的actnum,将它与6位数帐号的数组子串进行比较,然后从该特定行中获取子串99代码?
二进制搜索会有很大帮助!我可以拿555-555并将其与记录文件的上半部分或下半部分进行比较,然后继续搜索直到我对我需要的线路进行搜索,抓住整条线,然后将99输出.我遇到的问题是我似乎无法获得文件的正确整数转换,因为它包含数字和文本,因此我无法正确使用<,>,=符号.
任何有关这方面的帮助将不胜感激.我目前的程序实际上有效,但有时非常慢.
作为一种可能的解决方案(不一定是最好的),您可以将记录ID添加到Dictionary<string, int>(或者甚至是Dictionary<long, int>所有记录ID都是数字),其中每个键是一行的ID,每个值是行索引.当您需要查找特定记录时,只需查看字典(它将为您进行有效查找)并为您提供行号.如果该项目不存在(不存在的ID),您将无法在字典中找到它.
在这一点上,如果该文件中存在的记录的ID,你有一个行号 - 你可以将整个文件加载到内存(如果它不是太大),或只是寻求正确的路线,并与数据线读.
为此,您必须至少浏览一次该文件并从所有行收集所有记录ID并将其添加到字典中.您不必实现二进制搜索 - 字典将在内部为您执行查找.
编辑:
如果您不需要来自特定行的所有数据,只需要一位(如您提到的位置代码),您甚至不需要存储行号(因为您不需要返回行在文件中) - 只是将位置数据存储为字典中的值.
我个人仍然会存储行索引,因为根据我的经验,这些项目开始很小但最终收集功能,并且有一点你必须从文件中获取所有内容.如果您希望这种情况随着时间推移,只需将每行中的数据解析为数据结构并将其存储在字典中 - 它将使您的未来生活更加简单.如果您非常确定您将永远不需要比一位信息更多的数据,您可以将数据本身存储在字典中.
这是一个简单的例子(假设您的记录ID可以解析为a 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
// ...
Run Code Online (Sandbox Code Playgroud)
要查看记录ID是否存在,您只需调用TryGetValue():
LineData lineData;
if ( _dataMap.TryGetValue ( recordID, out lineData ) )
{
// record ID was found
}
Run Code Online (Sandbox Code Playgroud)
这种方法基本上将整个文件保存在内存中,但所有数据只被解析一次(在开始时,在构建字典期间).如果此方法使用了太多内存,只需将行索引存储在字典中,然后如果找到记录并返回该文件并动态解析该行.
虽然我没有找到更好的搜索方式,但我确实设法了解了嵌入式资源,这大大加快了程序的速度。扫描整个文件现在只需几分之一秒,而不是 5-10 秒。发布以下代码:
string searchfor = textBox1.Text
Assembly assm = Assembly.GetExecutingAssembly();
using (Stream datastream = assm.GetManifestResourceStream("WindowsFormsApplication2.Resources.file1.txt"))
using (StreamReader reader = new StreamReader(datastream))
{
string lines;
while ((lines = reader.ReadLine()) != null)
{
if (lines.StartsWith(searchfor))
{
label1.Text = "Found";
break;
}
else
{
label1.Text = "Not found";
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
526 次 |
| 最近记录: |