如何添加两个String类型的矩阵?用户将不会输入行数或列数。用户将仅输入阵列。例如,对于输入[5 4-1; 2 1 4] + [3 -5 2.5; 1 2 3]
,输出应为[8 -1 1.5; 3 3 7]
什么是stof函数和添加错误?
这是我的代码:
//define a stm fucntion to convert string to matrix
vector <vector <float> > stm(string mat1)
{
//now let us build the matrix1 by iterating over the string mat1
//we will break the string over the point where we ";"
vector <vector <float> > matrix1;
int index1 = 0;
for (float i = 0; i < mat1.length(); i++)
{
string temp = " ";
while (mat1[i] != ';')
{
temp += mat1[i];
//now the temp string contains the elements of first row
//now we will break this at point where we get " " (spaces)
for (float j = 0; j < temp.length(); j++)
{
string num1;
int index2 = 0;
while (temp[j] != ' ')
{
num1 += temp[j];
//ntf is number to be filled at that position
j++;
}
float ntf = stof(num1);
matrix1[index1][index2] = ntf;
index2++;
}
i++;
}
index1++;
}
return matrix1;
}
int main()
{
string mat1; cin >> mat1;
string mat2; cin >> mat2;
vector <vector <float> > matrix1, matrix2;
matrix1 = stm(mat1);
matrix2 = stm(mat2);
//now let us write a code to add the two matrices;
vector <float> add;
for (float i = 0; i < matrix1.size(); i++)
{
for (float j = 0; j < matrix1[0].size(); j++)
{
add[i][j] = matrix1[i][j] + matrix2[i][j];
}
}
for (float i = 0; i < add.size(); i++)
{
for (float j = 0; j < add[0].size(); j++)
{
cout << add[i][j] << " ";
}
cout << endl;
}
return 0;
这是一个例子 输入
[5 4 -1;3 2 1]+[1 2 3;5 4 8]
输出
[6 6 2;8 6 9]
答案 0 :(得分:1)
我将提出一种可能的解决方案(在4,200万个选项中:-)
想法是使用面向对象的方法。因此,具有数据和方法的类。
数据是float矢量的必需矢量。并且方法是提取和添加。出于调试目的,还会覆盖插入操作符。
请注意:棘手的部分是解析输入字符串。特别是在可能无处不在的空白处。为了易于使用,我为浮点值定义了一个正则表达式。 regex_token_iterator将提取子匹配项并将其复制到列中。直到下一个“;”。看起来很复杂,但最终还是很容易理解。
我在代码中添加了很多注释,这使它有些冗长。无论如何,这将有助于更好地理解。
然后,main函数看起来非常简单。 。
编辑:
基于David C. Rankin的推荐,我更新了源代码:
#include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <regex>
// Our test data (raw string) . We could of course also read from a file or from std::cin or any istream
std::istringstream testData(
R"#( [ 1 2 3 ; 4 5 6 7 ]
[ 7 8 9; 10 11 12]
)#");
struct Matrix
{
// The data of our matrix
std::vector<std::vector<double>> data{};
// Overloading the extractor operator >> for our Matrix class
friend std::istream& operator >> (std::istream& is, Matrix& m) {
// Read a complete line
std::string line;
getline(is, line);
// Define a regex that matches any double number
std::regex re("([-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)");
// Set iterators.
// "Start" will be set to begin() or one past the end of the next semicolon
std::string::iterator start = line.begin();
// Position of semincolon or end()
std::string::iterator posSemicolon{};
// Read all rows and columns
do {
// Set the end iterator for this loop run to the position of the semicolon (or end() )
posSemicolon = std::find(start, line.end(), ';');
// Add a new row
m.data.emplace_back(std::vector<double>());
// Read a complete line with doubles and put that as column values in the current row
std::transform(
std::sregex_token_iterator(start, posSemicolon, re, 1), // Search for text that matches the regex
std::sregex_token_iterator(), // Search until the end (posSemicolon)
std::back_inserter(*(std::prev(m.data.end()))), // Put this data into the columns of the current row
// Convert the string matched by the regex, into a double
[](const std::string& stringAsDouble) -> double { return stod(stringAsDouble); }
);
// In case there is more input,
if (posSemicolon != line.end()) {
// then continue tokenizing in the next loop run past the semicolon
start = posSemicolon + 1;
}
} while (posSemicolon != line.end());
return is;
}
// For debug output purposes. Copy the data of the matrix to std::cout
friend std::ostream& operator << (std::ostream & os, const Matrix & m) {
std::for_each(
m.data.begin(), // Iterate over all rows
m.data.end(),
[&os](const std::vector<double> & row) { // Do for all rows
std::copy( // Copy data to ostream (print)
row.begin(), // Iterate ove all columns for this row
row.end(),
std::ostream_iterator<double>(os, " ")); // Print
std::cout << '\n'; // Line break after printing a row
}
);
return os;
}
// Overload of the addition operator
friend Matrix operator +(Matrix & m1, Matrix & m2) {
// Define an empty matrix
Matrix result{};
// To be on the safe side, we will resize the destination matrix size
// to maximum values of both matrices
// Get the max number of rows ofrom both m1 and m2
const size_t maxRowSize = std::max(m1.data.size(), m2.data.size());
// Set number of rows in resulting Matrix
result.data.resize(maxRowSize);
// Get the maximum number of columns in any of the 2 metrices m1 or m2
const size_t maxColumnSize = std::max(
std::max_element(
m1.data.begin(), // Iterate over all rows of Matrix m1
m1.data.end(),
[](const std::vector<double> & dv1_1, const std::vector<double> & dv1_2) {
return dv1_1.size() < dv1_2.size();
}
)->size(),
std::max_element(
m2.data.begin(), // Iterate over all rows of Matrix m1
m2.data.end(),
[](const std::vector<double> & dv2_1, const std::vector<double> & dv2_2) {
return dv2_1.size() < dv2_2.size();
}
)->size()
);
// Iterate over all matrix elements
// For all rows
for (size_t row = 0; row < maxRowSize; ++row) {
// Resize the the number of columns in the target matrix
result.data[row].resize(maxColumnSize);
// Now iterate over all columns in that row
for (size_t col = 0; col < maxColumnSize; ++col) {
// And add the values. First check for valid row and column indices
double m1Value = ((row < m1.data.size()) && (col < m1.data[row].size())) ? m1.data[row][col] : 0.0;
double m2Value = ((row < m2.data.size()) && (col < m2.data[row].size())) ? m2.data[row][col] : 0.0;
result.data[row][col] = m1Value + m2Value;
}
}
return result;
}
};
int main()
{
// Define some matrices
Matrix m1, m2, m3;
// Read the test data. You can also read from std::cin or from a file
testData >> m1 >> m2;
// Add the Matrices
m3 = m1 + m2;
// Show result
std::cout << "Matrix 1:\n" << m1 << "\nMatrix 2:\n" << m2 << "\nMatrix3 = Matrix1 + Matrix2:\n" << m3;
return 0;
}