【问题标题】:C++ newbie: writing a function for extracting i vectors from a file. How do I get i/unkown number of vectors out of the function?C++ 新手:编写一个从文件中提取 i 个向量的函数。如何从函数中获取 i/unkown 数量的向量?
【发布时间】:2011-11-22 20:18:16
【问题描述】:

我正在编写一个函数,用于从文件中获取数据集并将它们放入向量中。然后将数据集用于计算。在该文件中,用户将每个数据集写在像“Dataset1”这样的标题下的一行上。结果是函数完成执行时的 i 个向量。该功能工作得很好。

问题是我不知道如何从函数中取出向量! (1) 我想我只能从一个函数返回一个实体。所以我不能返回 i 向量。另外,(2)我不能将向量/数据集写为函数参数并通过引用返回它们,因为每个计算的向量/数据集的数量是不同的。如果还有其他可能性,我不知道。

我确定这是一个愚蠢的问题,但我在这里遗漏了什么吗?我将非常感谢任何建议。到目前为止,我还没有将向量/数据集提取代码放入函数中;我将它保存在我的主文件中,它运行良好。我现在想通过将所有数据提取代码放入它自己的函数来清理我的代码。

对于每次计算,我都知道函数将在文件中找到的向量/数据集的数量,因为我将这些信息写入文件并可以提取它。有什么方法可以使用这些信息吗?

【问题讨论】:

  • 诸如“数据集”或“向量”如何写入文件(在“行”上)的确切方式尚不清楚。您可能应该将一些示例数据粘贴到问题中,以便更清楚地了解它的组织方式以及您的“向量”到底是什么。
  • 听起来您可能将向量存储在普通数组中。这是真的吗?
  • 谢谢。向量类似于:std::vector dataset1。每个元素都是一个数字(双)。在文件中,数据显示为:'1.0' '2.0' 3.2' 等,每个元素由 '' 之间的数字组成。

标签: c++ file-io vector parameter-passing argument-passing


【解决方案1】:

如果每个向量都属于同一类型,则可以返回一个 std::vector<std::vector<datatype> >

这看起来像:

std::vector<std::vector<datatype> > function(arguments) {  
    std::vector<std::vector<datatype> > return_vector;
    for(int i =0; i < rows; ++i) {
       \\ do processing
       return_vector.push_back(resulting_vector);
    }
    return return_vector;
} 

【讨论】:

  • 嗨,Serdalis。谢谢。它们属于同一类型。您是说您的解决方案将返回该类型的所有向量?
  • 它会返回该类型向量的向量,我相信这就是你想要的。
  • 谢谢伯努瓦。抱歉这个愚蠢的问题,但我必须先在函数中将向量变成向量的向量吗?
  • @Ant Benoit 是正确的,这将返回一个大小为 i 的向量,其中包含所有 i 向量,但此代码仅在 i 向量属于同一类型等情况下才有效.std::vector&lt;std::vector&lt;std::string&gt;&gt; 将返回一个字符串类型向量的向量。
  • 非常感谢。我没听说过。在函数中,我实际上正在获取其他数据以及我提到的数据集。这些其他数据与数据集的类型相同。但是我将通过在主函数中编写一个函数来将数据集与其他数据分开。我将从两者返回向量的向量。
【解决方案2】:

如前所述,您可以简单地使用向量的向量。

此外,您可能希望在其周围添加一个智能指针,以确保您没有复制矢量的内容(但这已经是一种改进。首先瞄准有效的东西)。

关于向量个数的信息,你可以通过调整全局向量到合适的值来使用。

【讨论】:

  • 谢谢 Benoit。通过“复制”,您是否意味着存在通过在某处复制向量来不必要地使用资源的风险?
  • 它将在短时间内不必要地使用两倍于所需大小的内存。这里真正的损失是将第一个版本的向量(向量)复制到第二个版本所用的时间。
【解决方案3】:

您的问题本质上是“我如何从函数中返回一堆 事物?”碰巧你的东西vector&lt;double&gt;,但这并不重要。重要的是你有一堆大小未知的东西。

您可以通过将一个问题重新表述为两个来完善您的想法:

  • 如何表示一堆东西
  • 如何从函数返回该表示?

至于第一个问题,这正是容器所做的。容器,正如您肯定知道的那样,因为您已经在使用容器,它包含任意数量的类似对象。示例包括 std::vector&lt;T&gt;std::list&lt;T&gt; 等。您选择使用哪个容器取决于您未提及的情况 - 例如,要复制的项目有多贵,您是否需要从堆中间删除一个项目等。

在您的具体情况下,知道我们所知甚少,看来您应该使用std::vector&lt;&gt;。如您所知,模板参数是您要存储的东西的类型。在您的情况下,恰好是(巧合)std::vector&lt;double&gt;。 (容器和它包含的对象恰好是相似的类型这一事实并不重要。如果你需要一堆 Blob 或 Widget,你说std::vector&lt;Blob&gt;std::vector&lt;Widget&gt;。因为你需要一堆vector&lt;double&gt;s ,你说vector&lt;vector&lt;double&gt; &gt;。)所以你会这样声明:

std::vector<std::vector<double > > myPile;

(注意&gt;&gt; 之间的空格。在以前的C++ 标准中需要这个空格。)

您可以像创建vector&lt;double&gt; 一样构建该向量——要么使用通用算法,要么调用push_back,或其他方式。因此,您的代码将如下所示:

void function( /* args */ ) {
    std::vector<std::vector<double> > myPile;
    while( /* some condition */ ) {
        std::vector<double> oneLineOfData;
        /* code to read in one vector */
        myPile.push_back(oneLineOfData);
    }
}

通过这种方式,您将所有传入数据收集到一个结构中,myPile

关于第二个问题,如何返回数据。嗯,这很简单——使用return 语句。

std::vector<std::vector<double> > function( /* args */ ) {
    std::vector<std::vector<double> > myPile;
    /* All of the useful code goes here*/
    return myPile;
}

当然,您也可以通过传入的向量引用返回信息:

void function( /* args */, std::vector<std::vector<double> >& myPile)
{
    /* code goes here. including: */
    myPile.push_back(oneLineOfData);
}

或者通过传入的指向你的向量的指针:

void function( /* args */, std::vector<std::vector<double> >* myPile)
{
    /* code goes here. */
    myPile->push_back(oneLineOfData);
}

在这两种情况下,调用者必须在调用您的函数之前创建双向量向量。首选第一种 (return) 方式,但如果您的程序设计要求,您可以使用其他方式。

【讨论】:

  • 非常感谢 Rob 的精彩解释。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-02-21
  • 2017-08-10
  • 1970-01-01
  • 1970-01-01
  • 2018-02-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多