优雅的解析模拟数据文件的方法

时间:2010-03-25 15:48:31

标签: c++ parsing data-structures simulation

我正在研究这个项目,我需要从.dat文件中读取大量数据并使用数据来执行模拟。我的.dat文件中的数据如下所示:

DeviceID  InteractingDeviceID InteractionStartTime InteractionEndTime
  1            2                  1101                1105

1,2 1101和1105是制表符分隔的,这意味着设备1在1101毫秒与设备2交互,并在1105毫秒结束交互。

我有一个跟踪数据集,可以编译成千上万的此类交互,我的工作就是分析这些交互。

第一步是解析文件。选择的语言是C ++。我想要采用的方法是读取文件,因为读取的每一行都创建了一个设备对象。 此Device对象将包含属性DeviceId和结构数组/向量,它将包含给定DeviceId在模拟过程中与之交互的所有设备的列表。结构将包含交互设备ID,交互开始时间和交互结束时间。

我有两个问题:

  1. 我的方法是否正确?

  2. 如果我走在正确的轨道上,如何使用C ++快速解析这些制表符分隔的数据文件并创建设备对象而不会产生过多的内存开销?

  3. 非常感谢正确推动。

    由于

4 个答案:

答案 0 :(得分:3)

根据您提供的信息,您的方法似乎是正确的。

我假设你要创建一个类似的东西:

class device {
  public:
    int id;
    vector<interaction> interactions;
    void add_interaction(interaction add_me); // uses vector::insert
};

typedef struct interaction_t {
    int other_device_id;
    int start_time;
    int end_time;
} interaction;

此时,您应该能够一次读取一行文件并提取数据。

device* pDev = NULL;
interaction new_interaction;
ifstream ifs( "data.dat" );
char temp[MAX_LINE_LENGTH+1];
int id, other_id, start, end;

while(ifs.getline(temp, MAX_LINE_LENGTH)) {
    sscanf(temp, "%i\t%i\t%i\t%i",
        &id,
        &new_interaction.other_device_id,
        &new_interaction.start_time,
        &new_interaction.end_time);
    pDev = find_device_by_id(id);
    pDev->add_interaction(new_interaction);
}

代码未经测试且仅用于说明目的,但您可以了解相关信息。诀窍是编写find_device_by_id函数(将返回指向具有匹配device字段的id对象的指针。这不应该要求每个输入线有太多的内存开销;如果您的输入文件很大,您可能无法将数据存储在内存中,而可能必须存储在数据库中。

答案 1 :(得分:2)

解决设计内存存储和链接的问题:

你还没告诉我们。数据的必要结构取决于您需要如何使用数据。

  • 如果您要按开始时间顺序遍历(全部或部分)数据,那么您是否应该能够按启动时间顺序访问事件?如果您打算跳到流的中间,有时候您不能通过starttime有效搜索。
  • 如果您想检查在特定时间间隔内活动的事件,您还需要能够在结束时间内有效搜索。
  • 如果您想检查单个设备的所有交互,您需要能够按设备选择事件(您建议的结构很好)
  • ......你有什么其他用例......

如果您不需要尽可能好的性能(即性能良好),关系数据库可能会有序。或者你可以建立具有你需要的所有特征的内存结构,但它们可能是中等复杂的......

答案 2 :(得分:1)

我与互动的人做了类似的事情。为了将来的可扩展性,我会做以下事情: 拥有一个包含id的Device类和一个指针Interaction对象的向量。可以将设备保存在易于查找的地图(或散列映射)中。交互类将包含文件中的其余信息。这将允许您创建多态设备和交互,以防您每个人都有多种设备或交互。您可能还希望为设备和交互设置工厂,以促进这一点。

答案 3 :(得分:0)

看看Boost.Spirit。这是一个不错的解析器框架。

编辑,修复链接