[英]how to take input in 2d array without knowing dimension
I have a C++ programming assignment which i have to read from a text file and store the input in a 2d array.我有一个 C++ 编程作业,我必须从文本文件中读取并将输入存储在二维数组中。 But text file only contains the matrix, stores no information about rows and columns.
但是文本文件只包含矩阵,不存储有关行和列的信息。 My program will be tested with several inputs so the 2d array shouldn't have a fixed size.
我的程序将使用多个输入进行测试,因此二维数组不应具有固定大小。 But this matrix doesnot guaranteed to be a square one.
但是这个矩阵并不能保证是方阵。 So how can i store this matrix in a 2d array which has dynamic dimensions when tested with several input files?
那么,当使用多个输入文件进行测试时,如何将此矩阵存储在具有动态维度的二维数组中?
In C programs, we could often find plain arrays, with one or more dimensions.在 C 程序中,我们经常可以找到一维或多维的普通数组。 The disadvantage of those plain arrays ist, that the dimensions (the number of elements) must be a compile time constant.
这些普通数组的缺点是,维度(元素数量)必须是编译时常量。 It needs to be predetermined at compile time and cannot grow.
它需要在编译时预先确定,不能增长。
This is not very helpful and often leads to errors like "out of bounds".这不是很有帮助,并且经常导致诸如“越界”之类的错误。 And people oftern reserved some buffer, to be on the safe side.
为了安全起见,人们通常会保留一些缓冲区。 So you will find often in legacy code arrays like the following:
因此,您经常会在遗留代码数组中找到如下所示:
int i = 3;
char buf[100]; /* Make array big enough to hold int string in any case */
sprintf(buf,"%d",i);
All this is not very nice.这一切都不是很好。 But fortunately, in C++ we have in the STL containers that fullfill all our requirements.
但幸运的是,在 C++ 中,我们拥有满足我们所有要求的 STL 容器。 One example is std::vector.
一个例子是 std::vector。 It can be initialzed dynamically and can grow.
它可以动态初始化并且可以增长。 The index operator works like in plain old arrays.
索引运算符的工作方式类似于普通的旧数组。 Fine.
美好的。
But the next question is, how to add more dimenensions?但下一个问题是,如何添加更多维度? The answer is to use vectors of vectors.
答案是使用向量的向量。 For each dimension, we will add a new vector inside the other vector.
对于每个维度,我们将在另一个向量内添加一个新向量。 For the case of a 2 dimensional matrix, this means:
对于二维矩阵,这意味着:
std::vector<int> columns;
std::vector<std::vector<int>> matrix;
This is maybe a little bit hard to read.这可能有点难以阅读。 "Typedef" or "using" will it make more readable for us:
"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;
Now back to your question现在回到你的问题
how to take input in 2d array without knowing dimension
如何在不知道维度的情况下在二维数组中输入
We will use the above mechanism.我们将使用上述机制。 A vector of vectors.
向量的向量。 Both vectors will grow as needed.
两个向量都将根据需要增长。 And if we want to read strings from a file with columns and rows (whatever the number will be), it can be implemented with this method.
如果我们想从包含列和行的文件中读取字符串(无论数字是多少),都可以使用此方法来实现。
Look at a possible input file "input.txt"查看一个可能的输入文件“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
If we see everything as string in the input file, then we will used a std::vector<std::vector<std::string>>
如果我们将输入文件中的所有内容都视为字符串,那么我们将使用
std::vector<std::vector<std::string>>
One possible implementation for reading such a file and show some debug output is:读取此类文件并显示一些调试输出的一种可能实现是:
#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;
}
This program will give the following output for the above input:该程序将为上述输入提供以下输出:
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 _____ _____
Please note: Padding (filling the empty cells) is not necessary.请注意:不需要填充(填充空单元格)。 You could omit Steps 2. and 3. You would than read the whole input file with a one liner.
您可以省略第 2 步和第 3 步。您可以使用一行行读取整个输入文件。
But often people use later the matrix in a rectangular way with the index operator.但是通常人们后来以矩形方式使用带有索引运算符的矩阵。 For this, all colums should exist.
为此,所有列都应该存在。
I hope this helps to get a better understanding .我希望这有助于更好地理解。 .
. .
.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.