对于这个问题,是否有更好的数据结构和算法选择
Is there a better selection of datastructures and algorithms for this problem?
对于以下问题,请建议更好的解决方案(根据时间复杂性(。我最后解释了我的方法。
有一个文件具有以下格式的记录:-RecordType;象征价格id;parentId
示例文件看起来像-
RecordType;Symbol;price;id;parentId
- A;BANK_X;20;2345;0
- A;BANK_Y;30;2346;0
- A;BANK_Z;40;2347;0
- M;BANK_X;50;2348;2345
- M;BANK_Y;10;2349;2346
- A;BANK_X;20;2350;0
- A;BANK_E;40;2351;0
- M;BANK_X;45;2352;2345
- M;BANK_X;20;2353;2350
这样的文件包含数百万条记录。目标是编写一个高效的C++程序,将文件拆分为多个文件,使每个较小的文件包含Y个记录,其中Y是作为输入提供的整数。
需要记住的要点:
- 每个记录都有唯一的id(即记录中倒数第二个字段(
- 对于匹配的符号,a和M记录应在同一个较小的文件中
例如,如果示例文件被拆分为至少包含2行的文件,那么以下记录应该在一个文件中:
- A;BANK_X;20;2345;0
- M;BANK_X;50;2348;2345
- M;BANK_X;45;2352;2345
我解决问题的方法:
使用的数据结构:
- 队列:这将有一些对象,其中键将是id(这些是父对象(,对象中的值将是一个向量,该向量将有子对象列表
- Unordered_map 1:键:id(即最后一个字段中记录值为0的id(,值:字符串(即从文件中读取的该id的记录(
- Unordered_map 2:Key:id(即其记录在最后一个字段中具有NON 0值的id(,value:string(即从文件中读取该id的记录(
算法:
- 逐行读取文件
- 分析记录的最后2个字段
- 检查id是否为父项(即记录的最后一个字段是否为0(如果是:创建放入队列中的对象{id,vactor<int>}将id和字符串记录添加到无序映射1如果否:在队列中搜索父id,并在向量中添加子id(这可以进行恒定时间搜索(将id和字符串记录添加到无序映射2
- 执行以上步骤直到文件结束
- 现在开始弹出队列,并为每个id(即父id(从Unordered_map 1获取记录字符串,此外,对于它的子级(在矢量中可用(,从Unordered_map 2中获取记录字符串,写入文件。在这里,我将检查最小行数
- 根据Y的值,从unsorted_map中获取id(父级(和子级的记录,并写入新文件
如果我考虑语句中提到的示例文件,在应用我的算法后,数据结构将具有以下值:-
Queue< int, std::vector < int> >: [ {2345, <2348, 2352>}, {2346, <2349>}, {2347, <empty>}, {2350, <2353>}, {2351, <empty>}]
Unordered_map 1 < int, std::string >: [{2345, "A;BANK_X;20;2345;0"}, {2346, "A;BANK_Y;30;2346;0"}, {2347, "A;BANK_Z;40;2347;0"}, {2350, "A;BANK_X;20;2350;0"}, {2351, "A;BANK_E;40;2351;0"}]
Unordered_map 2 < int, std::string >: [{2348, "M;BANK_X;50;2348;2345"}, {2349, "M;BANK_Y;10;2349;2346"}, {2352, "M;BANK_X;45;2352;2345"}, {2353, "M;BANK_X;20;2353;2350"}]
您的问题中的以下陈述:
"这样的文件包含数百万条记录。">
。。断言我建议您使用SQL数据库。这样,您可以将所有内容都保存在一个文件中,以便于访问。您可以在未来有效地select, insert, update, delete
,而不会失去从第一天起获得的灵活性。
SQLite确实是一个轻量级的替代方案。
您可以使用向量和映射来完成此操作。声明一个向量[SIZE_OF_SYMBLE]。用整数映射符号。然后每次获得条目时,首先从映射中获取符号的映射int值,并将条目推送到该向量。
struct record{string recordType;char symbol;double price;int id;};
map<char,int> symbmol_to_int;
vector<record> piles[SIZE_OF_SYMBOL];
更新:
我想出了一个更好的解决方案。由于看起来id是按排序的,所以您可以在处理完每一行之后立即写入文件。对于每个子记录,只需写入其父记录所在的文件即可。只需记住将父记录写入哪个文件即可。
unordered_map<int, int> id_to_file_id;
实际上,你不需要将整个字符串存储在地图中,你只需要存储它在哪一行。这将节省一半的空间。
使用这样的数据结构:
unordered_map<int, int> id_to_line;
map<int, vector<int>> groups; // map<parent_id, vector<child_id>>
相关文章:
- 链表,反向函数,数据结构
- 如何知道用于实现标准代码段的确切数据结构和算法,例如在C++STL中?
- 学习数据结构和算法的简单方法
- 对于这个问题,是否有更好的数据结构和算法选择
- 在现有数据结构上使用BGL算法需要什么(边和顶点作为矢量<对象*>)?
- 最短路径的dijkstra算法的时间复杂度是否取决于所使用的数据结构?
- 哪种数据结构和算法适用于此
- 用于创建、可视化和算法操作数据结构的C++库
- C++ 数据结构的排序算法
- 对一组数字进行排序的最快数据结构(和排序算法)是什么
- 最快的数据结构或算法,可快速查找 2 个键
- Hadoop FairScheduler的高级内部数据结构和算法
- 设计PRIM算法最有效的数据结构是什么
- 快速的数据结构或算法来找到图像堆栈中每个像素的平均值
- 压缩2D曲线的最佳数据结构/算法是什么?
- 数据结构/算法,可以跟踪结构(x和y)和值,避免重复
- 为什么我们不能在算法和数据结构中使用参考呢
- 递归排列,Ellis Horowitz算法和数据结构混淆
- 数据结构-C++映射:需要智能算法
- 数据结构+算法为ipv4存储高效搜索前缀