【问题标题】:Faster way to initialize array with text file C++使用文本文件 C++ 初始化数组的更快方法
【发布时间】:2013-12-12 16:44:06
【问题描述】:

所以我有一个相当大的文本文件,其中包含 2 列数字,我希望能够在我作为二维数组编写的程序中使用它。这是每次启动程序时都需要访问的数据,我觉得每次启动程序时都必须使用文件读取器读取数据太慢/效率低下。

所以我想知道是否有一种更简单/更有效的方式来访问数据,而无需以传统方式(ifstream 等)读取数据?我相信我曾经见过类似以下的事情:

float array[]{
    #include "myfile.txt"
}

但我什至不确定这是否有效,而且我找不到任何相关信息。

【问题讨论】:

  • 如果您的数据被格式化为创建合法的数组初始化,那么就可以这样做。当然,每次数据变化时都需要重新编译。您是否尝试过在启动时读取文件? “相当大”有多大?
  • 如果myfile.txt不遵循c++语法,编译错误。
  • myfile.txt 需要什么样的语法?现在它只是 2 个垂直的数字列,用空格分隔列,但没有其他标点符号
  • @me.deeiip 使用这个技巧的人通常会构造他们的数据,以便它确实遵循 C++ 语法。生成错误代码是没有意义的。
  • 如果您还没有尝试在运行时读取文件,我建议您尝试一下,如果只是为了了解它确实需要多长时间。你可能会感到惊讶。用那位伟大的圣人 Don Knuth 的话来说,“过早的优化是万恶之源。”

标签: c++ arrays file optimization multidimensional-array


【解决方案1】:

首先,您必须考虑如何声明和初始化二维数组。 简单;

int x[5][2] = {
    {1, 1},     
    {2, 2},     
    {3, 3},     
    {4, 4},     
    {5, 5}
};

如果数组元素来自文件,您必须完全像创建文件; 在file.txt;

{1, 1},     
{2, 2},     
{3, 3},     
{4, 4},     
{5, 5}

遵循 C++ 包含文件预处理器指令的规则,您可以像这样简单地编写代码; Source.cpp文件;

#include <iostream>
using namespace std;

int x[5][2] = {
    #include "file.txt"
};

int main(int argc, char* argv[])
{   
    for(int i = 0; i < 5; ++i)
    {
        for(int j = 0; j < 2; j++)          
        {
            cout << "x[" << i + 1 << "][" << j + 1 << "] = " << x[i][j] << " , ";
        }
        cout << endl;
    }

    return 0;
}

【讨论】:

    【解决方案2】:

    如果你坚持在包含文件中嵌入数据的方式,你可以使用宏:

    1. 将数据写入包含的文件(示例中为“myfile.txt”,或“myfile.h”)。
    2. 按照以下格式写入数据:

      #define DATA 1,2,3,4,5
      

      (你可以把它分成几行,但保持逗号分隔的格式)。

    3. 在源文件的顶部包含“myfile.h”。

    4. 使用 DATA 代替 #include 语句:

      float array[] {
          DATA
      };
      

    【讨论】:

    • 使用#define DATA 而不是直接在所需位置包含文件有什么意义?对我来说,这似乎更复杂
    • 我的建议只是尽量保持现有的代码约定,以使代码更具可读性。也许我错了,但我认为普通程序员可能会对在源文件中间看到“包含”语句感到困惑。
    • 但就我而言,我同样会对代表多个值的定义感到困惑。我最终不得不进行两次查找(首先是宏定义,然后是文件内部)来找出那里发生了什么,而不是如果只有包含
    【解决方案3】:

    要完成这项工作,您应该以遵循 C++ 语法的方式格式化您的文本文件。您可以按照教程的数量来查看很好的示例以及正在发生的事情的描述。

    这是一个简短的例子:

    • 对于一维数组,只需像这样键入带逗号的数字

    1.0, 3.4, 3.14, 5.56

    • 对于二维和更多维度,将每一行括在大括号 {} 中,用这样的逗号分隔每一列

    {1.0, 3.14}, {4.1, 5.674}

    以上假设您遵循自己的示例

    float array[] = {
        #include "textFile.txt"
    };
    

    【讨论】:

      【解决方案4】:

      如果您不介意在数据更改时重新编译,那么您的做法是正确的。 当然,数据必须有逗号,因为它必须是有效的 C/C++ 语法。 #include 所做的只是将文件的内容粘贴到您的源代码中。

      OTOH,如果您介意在数据更改时重新编译,那么您需要在程序启动时动态分配内存并在数据文件中解析。 您需要在这里克服的问题是您不一定事先知道数组有多大,如果您使用动态扩展数组,您可能会在内存分配和删除上浪费大量时间,因为它会增加数组. 像往常一样,我的解决方案是违反直觉的。 我只是读取了两次文件,一次是为了计算其中有多少个数字,然后分配内存,然后再次读取文件,将数字解析到内存中。 (如果读取一次不需要很长时间,读取两次也不会,特别是因为它已经在系统缓存中。)

      您说数据是二维的,但您可以将其作为一维放入数组中,然后在二维中访问它,如下所示:

      #define A(row,col) array[(row)*2 + (col)]
      

      【讨论】:

        猜你喜欢
        • 2018-04-05
        • 2022-01-13
        • 1970-01-01
        • 2012-08-08
        • 1970-01-01
        • 2014-11-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多