operations with matrix from two differents txt files - c++

Good day :) I want to make a program (in Visual C ++) that does several differents operations with two matrix from two different files. So far i was done this.
typedef unsigned int uint;
class matrix {
private:
uint nrows, ncol;
float **elements;
public:
matrix(const char*);
void printmatrix(const char*);
};
#include "matrix.h"
#include <iostream>
#include <fstream>
#include <iomanip>
matrix::matrix(const char*file) {
ifstream fcin(file, ios::in);
if (!fcin) {
cerr << "\nError: the file doesnt exist\n";
exit(EXIT_FAILURE);
}
fcin >> nrows;
fcin >> ncol;
elements = new float*[nrows];
for (uint i = 0; i < nrows; i++) {
elements[i] = new float[ncol];
for (uint j = 0; j < ncol; j++)
fcin >> elements[i][j];
}
fcin.close();
}
void matrix::printmatrix(const char*file) {
ofstream fcout(file, ios::out);
if (!fcout) {
cerr << "\nError: file doesnt exist\n";
exit(EXIT_FAILURE);
}
fcout << nrows;
fcout << "\n";
fcout << ncol;
fcout << "\n";
for (uint i = 0; i < nrows; i++) {
for (uint j = 0; j < ncol; j++)
fcout << setw(6) << elements[i][j];
fcout << "\n";
}
fcout.close();
};
#include "matrix.h"
#include <cstdlib>
int main()
{
matrix A("matrix1.txt");
A.imprimir("matrix2.txt");
system("PAUSE");
return 0;
}
I begun to do the program with randomly generated matrixs, and to do operations (addition, subtraction, multiplication) with overloaded operators; And also do the operations "inverse matrix" and "multiplication by a scalar". However, when working with matrixs from two different text files, I complicate: \ and I have many doubts, starting with, what is the prototype for the operator overload for matrixs from two differents text files?
When I did the sum for randomly generated matrixs, I had done this:
matrix* operator+ (const matrix&matrix2){
matrix*sum=new matriz(nrow, ncol);
for (uint i=0; i<nrows; i++){
for (uint j=0; j<ncol; j++){
sum->elements[i][j]=elements[i][j]+matrix2.elements[i][j];
}
}
return sum;
}
And similarly I had performed the operations mentioned above and they worked well. but, I have no idea how to do operations (with overhead) with matrixs obtained from two different text files. Can you help me, please? :) Sorry if my question is not clear at all, im from latinoamerica and my english is bad

Related

Dual selection sorting an array - honestly stumped

void dualSort(int [], double [], int);
int main()
{
const int ARRAY_SIZE = 1000; // Array size
double accountNumbers[ARRAY_SIZE]; // Array with 1000 elements
double accountBalances[ARRAY_SIZE]; // Loop counter variable
int count = 0; // Input file stream object
ifstream inputFile;
// Open the file.
inputFile.open("FinalNumbers.txt");
// Read the numbers from the file into the array
while (count < ARRAY_SIZE && inputFile >> accountNumbers[count] >> accountBalances[count] ) {
count++;
}
inputFile.close();
// Display the read data
cout << "The bank account numbers are: " << endl;
for (int count = 0; count < ARRAY_SIZE; count++) {
cout << accountNumbers[count] << "\n" << accountBalances[count] << " " << endl;
}
void dualSort(int accountNumbers[], double accountBalances, int ARRAY_SIZE);
}
I am required to use the selection sort or bubble sort algorithm.
I have Bank Account Numbers that have to be correspondingly and ascending sorted with there Account Balance, all the data is read from a file.
After sorting the data I have to rewrite it into another file, which is the least of my worries.
So the question is how do I go about sorting my accountNumbers in ascending order along with their accountBalance following them.
You need to sort according to accountNumbers but apply every swap operation to both arrays.
Here is the code using selection sort:
void dualSort(int accountNumbers[], double accountBalances[], int ARRAY_SIZE)
{
int minIndex;
for(int i = 0; i < ARRAY_SIZE - 1; i++)
{
minIndex = i;
for(int j = i + 1; j < ARRAY_SIZE; j++)
{
if(accountNumbers[j] < accountNumbers[minIndex])
{
minIndex = j;
}
}
swap(accountNumbers[i], accountNumbers[minIndex]);
swap(accountBalances[i], accountBalances[minIndex]);
}
}
You can declare a struct:
struct Account{
int accountNum;
int accountBalance;
bool operator<(const Account& a);
};
Then overload the comparison operator:
bool Account::operator<(const Account& a);
{
return (accountNum < a.accountNum);
}
Then put all your data in a struct vector using for loops:
std::vector<Account> accVec;
Finally sort vector using std::sort()
std::sort(accVec.begin(), accVec.end());
Now you have your data neatly stored in a vector in ascending order of account number.
Alternatively you can apply regular bubbleSort to sort the elements, as shown by "abcOfJavaAndCPP"
for(int j = 1; j < accVec.size(); ++j)
for(int i = 1; i < accVec.size() ; ++i)
if(accVec[i-1] < accVec[i])
std::swap(accVec[i], accVec[i+1]);
to do bubble sort algorithm you must do 2 for loops and a temporary variable
int tempAccNumber=0;
int tempAccBalance=0;
for(int j=0;j<ARRAY_SIZE-1;++j)
for(int i=0;i<ARRAY_SIZE-1;++i)
if(accountNumbers[i]>accountNumbers[i+1])
{
tempAccNumber=accountNumbers[i];
accountNumbers[i]=accountNumbers[i+1];
accountNumbers[i+1]=tempAccNumber;
tempAccBalance=accountBalances[i];
accountBalances[i]=accountBalances[i+1];
accountBalances[i+1]=tempAccBalance;
}
just implement this to your function that do the bubble sort
Code can be simplified quite a bit by using some more modern C++ techniques:
#include <vector>
struct Account {
double balance;
int number;
};
bool operator<(const Account& lhs, const Account& rhs) {
return lhs.number < rhs.number;
}
void dualSort(vector<Account>& v) {
for (std::size_t i = 0; i != v.size() - 1; ++i) {
for (std::size_t j = 0; j != v.size() - 1; ++j) {
if (v[j] < v[j+1]) std::swap(v[j], v[j+1]);
}
}
}
int main()
{
const int ARRAY_SIZE = 1000; // Array size
std::vector<Account> v(ARRAY_SIZE);
std::ifstream inputFile;
// Open the file.
inputFile.open("FinalNumbers.txt");
for (std::size_t i = 0; i != ARRAY_SIZE; ++i) {
inputFile >> v[i].number >> v[i].balance;
}
inputFile.close();
// Display the read data
cout << "The bank account numbers are: " << endl;
for (int count = 0; count < ARRAY_SIZE; count++) {
cout << v[count].number << "\n" << v[count].balance << " " << endl;
}
void dualSort(v);
}
Would encourage you to learn about classes, or even just structs to start, and also get familiar with std::vector as you should be using it a lot.

What's wrong with ADT constructor for SquareMatrix?

This project I am writing in order to create a Square Matrix ADT object has a problem with the constructor (not the default constructor). I have traced the problem back to the constructor but I cannot figure out what is wrong with it which makes it crash everytime I try to run my test in main.cpp.
I usually get an error that say something along the lines "Thread 1: EXC_BAD_ACCESS: ..." and the console usually says "(11db)"
Does anyone have any ideas on what might be causing all the problems?
This is the header file:
#include <iostream>
#include <vector>
using namespace std;
#ifndef SquareMatrix_h
#define SquareMatrix_h
class SquareMatrix {
private:
vector<vector<double>> numMatrix;
public:
SquareMatrix();
SquareMatrix(vector<vector<double>>& v2d);
double getValue(int x, int y);
void setValue(int x, int y, double value);
friend SquareMatrix operator * (SquareMatrix m1, SquareMatrix m2);
friend SquareMatrix operator - (SquareMatrix m1, SquareMatrix m2);
friend ostream& operator <<(ostream &out, SquareMatrix m);
};
#endif /* SquareMatrix_h */
This is my SquareMatrix.cpp file: (The constructor that I believe isn't working is the second function in the code: SquareMatrix::SquareMatrix(vector>& v2d) {...)
#include "SquareMatrix.h"
#include <iostream>
using namespace std;
SquareMatrix::SquareMatrix() {
numMatrix.clear();
for(int i = 0; i < 10; i++) {
vector<double> initial;
for(int j = 0; j < 10; j++) {
initial.push_back(0.0);
}
numMatrix.push_back(initial);
}
}
SquareMatrix::SquareMatrix(vector<vector<double>>& v2d) {
bool flagSize = true;
for(int i = 0; i < v2d.size(); i++) {
if(v2d[i].size() != v2d.size()) {
flagSize = false;
break;
}
}
if(flagSize) {
numMatrix.clear();
for(int i = 0; i < v2d.size(); i++) {
vector<double> initial;
for(int j = 0; j < v2d[i].size(); i++) {
initial.push_back(v2d[i][j]);
}
numMatrix.push_back(initial);
}
} else {
numMatrix.clear();
for(int i = 0; i < 10; i++) {
vector<double> initial;
for(int j = 0; j < 10; j++) {
initial.push_back(0.0);
}
numMatrix.push_back(initial);
}
}
}
double SquareMatrix::getValue(int x, int y) {
if((x < numMatrix.size()) && (y < numMatrix.size()) && (x >= 0) && (y >= 0)) {
return numMatrix[x][y];
}
return 0;
}
void SquareMatrix::setValue(int x, int y, double value) {
if((x < numMatrix.size()) && (y < numMatrix.size()) && (x >= 0) && (y >= 0)) {
numMatrix[x][y] = value;
}
}
SquareMatrix operator * (SquareMatrix m1, SquareMatrix m2) {
if(m1.numMatrix.size() == m2.numMatrix.size()) {
vector<vector<double>> result;
for(int i = 0; i < m1.numMatrix.size(); i++) {
vector<double> initial;
for(int j = 0; j < m1.numMatrix.size(); j++) {
initial.push_back(0);
}
result.push_back(initial);
}
for(int i = 0; i < m1.numMatrix.size(); i++) {
for(int j = 0; j < m1.numMatrix.size(); j++) {
result[i][j] = 0;
for (int a = 0; a < m1.numMatrix.size(); a++) {
result[i][j] += m1.numMatrix[i][a] + m2.numMatrix[a][j];
}
}
}
return SquareMatrix(result);
}
return SquareMatrix();
}
SquareMatrix operator - (SquareMatrix m1, SquareMatrix m2) {
if(m1.numMatrix.size() == m2.numMatrix.size()) {
vector<vector<double>> result;
for(int i = 0; i < m1.numMatrix.size(); i++) {
vector<double> initial;
for(int j = 0; j < m1.numMatrix[i].size(); j++) {
double pushNum = (m1.getValue(i,j) - m2.getValue(i,j));
initial.push_back(pushNum);
}
result.push_back(initial);
}
return SquareMatrix(result);
}
return SquareMatrix();
}
ostream& operator << (ostream &out, SquareMatrix m) {
out << "(";
for (int i = 0; i < m.numMatrix.size(); i++) {
for (int j = 0; j < m.numMatrix.size(); j++) {
out << " " << m.numMatrix[i][j];
if(j != (m.numMatrix.size() - 1)) {
out << ", ";
}
}
}
out << ")";
return out;
}
Then this is the main.cpp that I am using to test the SquareMatrix ADT object:
#include "SquareMatrix.h"
#include <iostream>
#include <random>
#include <ctime>
#include <vector>
using namespace std;
int main() {
srand(time(NULL));
vector<vector<double>> m1;
vector<vector<double>> m2;
int size = 0;
cout << "Enter the size of the Square Matrix: ";
cin >> size;
for (int i = 0; i < size; i++) {
vector<double> in1;
vector<double> in2;
for (int j = 0; j < size; j++) {
in1.push_back(rand() % 100);
in2.push_back(rand() % 100);
}
m1.push_back(in1);
m2.push_back(in2);
}
SquareMatrix res1 = SquareMatrix(m1);
SquareMatrix res2 = SquareMatrix(m2);
cout<< "\nMatrix 1: " << endl;
cout << res1 << endl;
cout<< "\nMatrix 2: " << endl;
cout << res2 << endl;
SquareMatrix mult = res1*res2;
cout << "\nMatrix1 * Matrix 2: " << endl;
cout << mult << endl;
SquareMatrix min1_2 = res1 - res2;
cout << "Matrix1 - Matrix 2: " << endl;
cout << min1_2 << endl;
SquareMatrix min2_1 = res2 - res1;
cout << "Matrix2 - Matrix 1: " << endl;
cout << min2_1 << endl;
return 0;
}
Any help you could give would be appreciated. :)
As pointed out in the comments, you problem is a simple typo in one of your nested loops. However, I'd like to add some recommendations to make your code less error prone (and also more readable).
Firstly, when iterating over all elements of a vector, unless you need an index for something else, you should be using a range-based for-loop. In your code, you might replace the check for square size with the following:
for (const vector<double>& vec: v2d){
if (vec.size() != v2d.size()){
flagSize = false;
break;
}
}
This expresses your intent a little more clearly, and, more importantly, prevents you from accidentally reading from/writing to a location out of your vector's bounds (accidentally typing <= instead of just < happens to the best of us).
Secondly, the two nested loops (that contained your error) can be replaced with a simple copy assignment (numMatrix = v2d; reference). Again, this expresses your intent in addition to being a whole lot shorter. No need to reinvent the wheel with functions like these.
The contents of the else-branch of the surrounding if-statement can also be replaced with a call to assign (the first overload listed on the page, use like numMatrix.assign(10, vector<double>(10, 0.0))). Like before, clearer expression of intent and avoidance of index errors.
Finally, the parameter in this constructor can be a const reference instead of a normal one since you do not alter its contents in any way (and, given this, it should be const).
You might wonder why "expression of intent" is relevant, or what it even means in this context. Essentially, it's all about making what you're trying to do immediately obvious to any reader. This is more important in large projects with many contributors but it is helpful even when debugging small applications like this one. You seem to be learning still, but I strongly believe it's a good thing to keep in mind from the beginning. After all, many of these changes also make for briefer code, making it that much easier for others to help you if you run into a problem.
I realize this left the scope of the original question somewhat, but I hope you find this helpful nonetheless.

C++ Arrays and Mathmatics

A={O|0<x<=10}
B={E|0<x<=10}
R={(a,b)a A, b B|a<b}
A={2,4,6,8,10}
B={1,3,5,7,9}
AxB={(2,1)(2,3)(2,5)(2,7)(2,9) (4,1)(4,3)(4,5)(4,7)(4,9) (6,1)(6,3)(6,5)(6,7)(6,9) (8,1)(8,3)(8,5)(8,7)(8,9) (10,1)(10,3)(10,5)(10,7)(10,9)}
R={(2,3)(2,5)(2,7)(2,9) )(4,5)(4,7)(4,9) )(6,7)(6,9) (8,9)}
Solve it using C++ program. You can use Arrays for storing the values and use nested for loop for finding the R(Relation). The above code is a Desecrate mathematics question and i want to solve it using C++. i want to search from the arrays i write this code kindly guide me what is wrong in my code...
#include<iostream>
using namespace std;
main()
{
int a[5]= {2,4,6,8,10}, b[5]={1,3,5,7,9} ,R1[10],R2[10], counts =0;
for (int i=0; i<5; ++i)
{
for (int j=0; j<5; j++)
{
if (a[i]<b[j])
{
R2[counts]= b[j];
R1[counts]= a[i];
counts++;
}
}
}
for(int i=0; i<counts; i++)
{
cout<<R2[i]<<endl;
cout<<R1[i];
}
}
for(int i=0; i<counts; i++)
{
cout << "(" << R1[i] << "," << R2[i] << ")" << endl;
}

How to access value inside vector of vectors of type class

I'm in an introductory C++ class and we've been tasked to write a program that reads a .ppm picture file, copies it, then writes it to an output file.
To do this, my PpmPicture class has a vector of vectors, where each index contains a Pixel with red, green, and blue ints.
My problem is with my output function, where I'm trying to output those ints to a file. How do I go about accessing them individually? Here is my code, you can see where I'm trying to output those values at the bottom in my writePpmFile function. I know the picture.red[0][0] doesn't make any sense, I was just trying to brute force a solution and that happened to be the last thing I tried.
#include <iostream>
#include <vector>
#include <fstream>
#include <sstream>
using namespace std;
struct Pixel {
Pixel();
Pixel(int redValue, int greenValue, int blueValue);
int red;
int green;
int blue;
};
Pixel::Pixel() {
red = 0;
green = 0;
blue = 0;
}
Pixel::Pixel(int redValue, int greenValue, int blueValue) {
red = redValue;
green = greenValue;
blue = blueValue;
}
class PpmPicture {
public:
PpmPicture();
bool readPpmFile(string inputFile);
int writePpmFile(string outputFile);
private:
vector<vector<Pixel> > picture;
int rows;
int columns;
int intensity;
};
PpmPicture::PpmPicture() {
rows = 0;
columns = 0;
}
int main(int argc, char *argv[]) {
PpmPicture myPic;
if(argc != 3) {
cout << "usage: inputfile outputfile";
return 0;
}
myPic.readPpmFile(argv[1]);
myPic.writePpmFile(argv[2]);
}
bool PpmPicture::readPpmFile(string inputFile) {
Pixel pix;
vector<Pixel> tempArray;
fstream fin;
string fileType;
int i, j;
fin.open(inputFile.c_str());
//Check if file opened
if(fin.fail()) {
return false;
}
while(!fin.eof()) {
//Input first four values into appropriate variables
fin >> fileType >> columns >> rows >> intensity;
//Fill tempArray with pixel values
while(fin >> pix.red >> pix.green >> pix.blue) {
tempArray.push_back(pix);
}
}
//Read file until you reach the number of rows specified by the file
for(j = 0; j < rows; j++) {
//Input pixel values into each index in the row array
//Enter new row when one row's width is achieved
for(i = 0; i < columns; i++) {
picture[j].push_back(tempArray[i]);
}
}
return true;
}
int PpmPicture::writePpmFile(string outputFile) {
ofstream fout;
int i, j, temp;
fout.open(outputFile.c_str());
if(fout.fail()) {
return -2;
}
if(columns < 0 || rows < 0) {
return -1;
}
fout << "P3" << endl;
fout << columns << rows << endl;
fout << intensity << endl;
fout << picture.red[0][0];
fout << picture.green[0][0];
fout << picture.blue[0][0];
/*for(j = 0; j < rows; j++) {
for(i = 0; i < columns; i++) {
fout << picture[j][i] << " ";
}
}*/
return 0;
}
I should add, like I said this is an introductory class so we haven't gone over a lot of shortcuts/different functions. So if possible keeping it somewhat simple (even if it isn't that efficient) would be preferred :)
This is mostly a question of applying what you already know, but it seems like you're doing it in a sightly odd order.
Since picture is a vector<vector<Pixel>>, picture[i] is a vector<Pixel> and picture[i][j] is a Pixel.
The components of a Pixel are always accessed the same way – pixelvalue.componentname – so the components of this Pixel are picture[i][j].red, picture[i][j].green, and picture[i][j].blue.
A better approach to this would be writing an insertion operator for Pixel for example:
ostream& operator<<(ostream& lhs, const Pixel& rhs) {
lhs << rhs.red << ' ' << rhs.green << ' ' << rhs.blue;
}
Given this you can stream all of vector<Pixel> picture to ostream fout with only the command:
copy(cbegin(picture), cend(picture), ostream_iterator<Pixel>(fout, " "))

Can't read integer from file to matrix

I have to read from a file an array of numbers with an unknown size and save it as a matrix. The code must be as compact as possible, which is why I don't want to read file as string and then convert it to an int.
int main()
{
ifstream infile("array.txt");
int n, counter = 0, **p;
while (!infile.eof()) {
counter++;
}
counter = sqrt(counter);
cout << "counter is " << counter << endl;
p = new int*[counter];
for (int i = 0; i < counter; i++)
p[i] = new int[counter];
while (!infile.eof()) {
for (int i = 0; i < counter; i++) {
for (int j = 0; j < counter; j++)
p[i][j] = n;
}
}
for (int i = 0; i < counter; i++) {
for (int j = 0; j < counter; j++) {
cout << p[i][j] << " ";
}
cout << endl;
}
_getch();
return 0;
}
Here is my code, it was made for a square matrix. The problem is, I can't read the file at second time to save the numbers to the matrix.
You have a lot of problems in your code. A big one is that you have several infinite loops and aren't even reading from a file. An even bigger problem is that you're not using C++ constructs. I've written a small program that does what you're trying to do using more C++ concepts. In this case, you should use a std::vector - they will handle all the dynamic sizing for you.
test.cc
#include <iostream>
#include <vector>
#include <sstream>
#include <fstream>
#include <string>
// Nobody wants to write `std::vector<std::vector<int>>` more than once
using int_matrix = std::vector<std::vector<int>>;
void populate_matrix(int_matrix& mat, const std::string& line) {
int num;
std::stringstream ss(line);
std::vector<int> row;
// Push ints parsed from `line` while they still exist
while(ss >> num) {
row.push_back(num);
}
// Push the row into the matrix
mat.push_back(row);
}
// This is self-explanatory, I hope
void print_matrix(const int_matrix& mat) {
size_t n = mat.at(0).size();
for(size_t i = 0; i < n; ++i) {
for(size_t j = 0; j < n; ++j) {
std::cout << mat.at(i).at(j) << " ";
}
std::cout << std::endl;
}
}
int main(int argc, char** argv) {
int_matrix mat;
// Pass the file as a command-line arg. Then you don't need to worry about the path as much.
if(argc != 2) {
std::cout << "Number of arguments is wrong\n";
return EXIT_FAILURE;
}
// Open file with RAII
std::ifstream fin(argv[1]);
std::string line;
// Handle each line while we can still read them
while(std::getline(fin, line)) {
populate_matrix(mat, line);
}
print_matrix(mat);
return EXIT_SUCCESS;
}
This code assumes the text file looks something like this:
numbers.txt
1 2 3
4 5 6
7 8 9
i.e., n lines with n numbers per line separated by whitespace.
To compile and run this code, you can follow these steps:
13:37 $ g++ test.cc -std=c++14
13:37 $ ./a.out /path/to/numbers.txt
As far as I can see the program runs once through the file and later you run another while loop to read from the file. When you read from a file, then its like your "cursor" moves forward. So basicly, if you hit the end, you have to reset the cursor back to the start of the file.
You can set your cursor back with seekg(0).(http://www.cplusplus.com/reference/istream/istream/seekg/)