如何在不知道尺寸的情况下以二维数组输入

时间:2019-06-15 13:11:16

标签: c++

我有一个C ++编程任务,我必须从文本文件中读取并将输入存储在2d数组中。但是文本文件仅包含矩阵,不存储有关行和列的信息。我的程序将通过几个输入进行测试,因此2d数组不应具有固定的大小。但是,此矩阵不能保证是平方的。那么,当用多个输入文件进行测试时,如何将这个矩阵存储在具有动态尺寸的二维数组中?

1 个答案:

答案 0 :(得分:0)

在C程序中,我们经常可以找到具有一个或多个维的纯数组。这些普通数组的缺点是,维数(元素数)必须是编译时间常数。它需要在编译时预先确定,并且不能增长。

这不是很有帮助,通常会导致诸如“越界”之类的错误。并且人们为安全起见保留了一些缓冲。因此,您经常会在旧式代码数组中找到以下内容:

int i = 3;
char buf[100]; /* Make array big enough to hold int string in any case */
sprintf(buf,"%d",i);

这不是很好。但是幸运的是,在C ++中,我们的STL容器可以满足我们的所有要求。一个示例是std :: vector。它可以动态初始化并可以增长。索引运算符的工作方式类似于普通的旧数组。很好

但是下一个问题是,如何添加更多尺寸?答案是使用向量的向量。对于每个维度,我们将在另一个向量内添加一个新向量。对于二维矩阵,这意味着:

  • 首先,我们有一个向量或列。
  • 第二,我们将获得一个行向量,其中包含上述列向量
std::vector<int> columns;
std::vector<std::vector<int>> matrix;

这可能有点难以理解。 “ Typedef”或“ using”将使我们更容易阅读:

using ElementsInColumns = std::vector<int>;  // This is one row with columns
using Rows = std::vector<ElementsInColumns>; // This is the matrix. Consisting of Rows (with columns)
constexpr size_t NumberOfRows = 4;
constexpr size_t NumberOfColumns = 7;
Rows matrix(NumberOfRows, ElementsInColumns(NumberOfColumns));
matrix[1][2] = 5;

现在回到您的问题

  

如何在不知道尺寸的情况下以2d数组输入输入

我们将使用上述机制。向量的向量。两个向量都将根据需要增长。而且,如果我们想从具有行和列的文件中读取字符串(无论数字是多少),都可以使用此方法来实现。

查看可能的输入文件“ input.txt”

Col_1  Col_2  Col_3  Col_4  Col_5  Col_6
Col_1  Col_2  Col_3 
Col_1  Col_2  Col_3  Col_4  Col_5  Col_6  Col_7
Col_1  Col_2  Col_3  Col_4  Col_5

如果我们在输入文件中将所有内容视为字符串,则将使用std::vector<std::vector<std::string>>

读取此类文件并显示一些调试输出的一种可能的实现方式是:

#include <vector>
#include <string>
#include <iostream>
#include <fstream>
#include <iterator>
#include <algorithm>
#include <sstream>

using ElementsInColumns = std::vector<std::string>;
using Rows = std::vector<ElementsInColumns>;

struct Line      // ! This is a proxy for the input_iterator ! 
{   // Input function. Read on line of text file and split it in columns
    friend std::istream& operator>>(std::istream& is, Line& line) {
        std::string wholeLine;  std::getline(is, wholeLine); std::istringstream iss{ wholeLine }; line.elementsInColumns.clear();
        std::copy(std::istream_iterator<std::string>(iss), std::istream_iterator<std::string>(), std::back_inserter(line.elementsInColumns));
        return is;
    }
    operator ElementsInColumns() const { return elementsInColumns; }  // cast to needed result
    ElementsInColumns elementsInColumns{};  // Local storage for all words in line
};


int main()
{
    std::ifstream inFileStream{ "r:\\input.txt" };      // Open input file. Will be closed by destructor
    if (!inFileStream) { // ! operator is overloaded
        std::cerr << "Could not open input file\n";
    }
    else {
        // 1. Read complete input file into memory and organize it in columns by rows
        Rows rows{ std::istream_iterator<Line>(inFileStream), std::istream_iterator<Line>() };

        // 2. Calculate number of columns for a rectangular matrix. You could also use "min_element"
        const size_t numberOfColumns{std::max_element(rows.begin(), rows.end(), [](const ElementsInColumns & eicLeft, const ElementsInColumns & eicRight) {return eicLeft.size() < eicRight.size(); })->size()};

        // 3. Make exact numberOfColumns entries for all rows. Do this, if you want to have a rectangular matrix.. Empty cols will be filled with _____ (or whatever you like)
        std::for_each(rows.begin(), rows.end(), [numberOfColumns](ElementsInColumns& eic) {eic.resize(numberOfColumns, "_____"); });

        // 4. Debug Output
        std::cout << "\nMatrix\n\nRows:    " << rows.size() << "\nColumns: " << numberOfColumns << "\n\n";
        // Copy matrix to std::cout
        std::for_each(rows.begin(), rows.end(), [](ElementsInColumns & eic) {std::copy(eic.begin(), eic.end(), std::ostream_iterator<std::string>(std::cout, "  ")); std::cout << '\n'; });
    }
    return 0;
}

该程序将为上述输入提供以下输出:


Matrix

Rows:    4
Columns: 7

Col_1  Col_2  Col_3  Col_4  Col_5  Col_6  _____
Col_1  Col_2  Col_3  _____  _____  _____  _____
Col_1  Col_2  Col_3  Col_4  Col_5  Col_6  Col_7
Col_1  Col_2  Col_3  Col_4  Col_5  _____  _____

请注意:不需要填充(填充空白单元格)。您可以省略第2步和第3步。您将只需要一个衬纸即可读取整个输入文件。

但是后来人们常常通过索引运算符以矩形方式使用矩阵。为此,所有列都应存在。

我希望这有助于更好地理解。 。