I'm writing a program to find the determinant of a matrix n x n, using Laplace expansion.
Briefly, the program creates a two-dimensional array based on a user request. The users choose the size of the two-dimensional array and fills it in themselves. Next comes the computation of the matrix using Laplace.
The problem is that I can't use the resulting array values in the determinant function. I'm completely new to C ++, so any help would be welcome. The code shown below. Thanks
#include<iostream>
#include<iomanip>
#include<math.h>
using namespace std;
void fin(int**, int, int);
void fout(int**, int, int);
int main() {
int **board, n;
double alpha, beta;
cout << "Enter the number of rows and columns: ";
cin >> n;
cout << endl;
board = new int* [n];
for(int row = 0; row < n; row++)
board[row] = new int[n];
fin(board,n,n);
cout << endl;
fout(board,n,n);
cout << endl;
cout << "Determinant of the matrix is " << determinant(board, n);
cout << endl;
return 0;
}
void fin(int **p, int R, int C)
{
for(int row = 0; row < R; row++)
{
cout << "Enter " << C + 1 << " numbers for row number " << R + 1 << ": ";
for(int col = 0; col < C; col++)
cin >> p[row][col];
cout << endl;
}
}
void fout(int **p, int R, int C)
{
for(int row = 0; row < R; row++)
{
for(int col = 0; col < C; col++)
cout << setw(5) << p[row][col];
cout << endl;
}
}
int determinant( int **result, int n) {
int det = 0;
int submatrix[10][10];
if (n == 2)
return ((result[0][0] * result[1][1]) - (result[1][0] * result[0][1]));
else {
for (int x = 0; x < n; x++) {
int subi = 0;
for (int i = 1; i < n; i++) {
int subj = 0;
for (int j = 0; j < n; j++) {
if (j == x)
continue;
submatrix[subi][subj] = result[i][j];
subj++;
}
subi++;
}
det = det + (pow(-1, x) * result[0][x] * determinant( submatrix, n - 1 ));
}
}
return det;
}
Related
I am writing a matrix class where I need to perform some matrix calculations in the main program. I am not sure why the program is ending abruptly when user chooses a matrix of size more than 2x2 matrix. The std::cin works fine until two rows but program ends after the loop reaches third row. Only part of the code is shown below which is related to my question.
#include<iostream>
#include <vector>
#include <cassert>
using std::vector;
using namespace std;
class Matrix {
private:
int rows;
int cols;
int **vtr;
public:
Matrix(int m = 2, int n = 2)
{
rows = m;
cols = n;
vtr = new int*[m];
for (int i = 0; i < m; i++)
{
vtr[i] = new int [n];
}
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
vtr[i][j] = 0;
}
}
}
void read()
{
cout << "Enter the number of rows and columns of Matrix separated by a space: ";
cin >> rows >> cols;
Matrix a(rows, cols);
a.write();
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
cout << "(" << i << "," << j << ") : ";
cin >>vtr[i][j];
}
}
}
void write()
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
cout << vtr[i][j] << " ";
}
cout << endl;
}
cout << endl << endl;
}
};
int main()
{
Matrix A, B, C;
int row, column ;
cout << "For Matrix A" << endl;
A.read();
cout << "For Matrix B " << endl;
B.read();
cout << "For Matrix C" << endl;
C.read();
}
Since the 2D array, vtr is created when declaring the Matrix object, you can move the vtr creation after reading the console input like below.
Matrix(int m = 2, int n = 2)
{
/*rows = m;
cols = n;
vtr = new int*[m];
for (int i = 0; i < m; i++)
{
vtr[i] = new int [n];
}
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
vtr[i][j] = 0;
}
}*/
}
void read()
{
cout << "Enter the number of rows and columns of Matrix separated by a space: ";
cin >> rows >> cols;
vtr = new int*[rows];
for (int i = 0; i < rows; i++)
{
vtr[i] = new int [cols];
}
//Matrix a(rows, cols);
//write();
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
cout << "(" << i << "," << j << ") : ";
cin >>vtr[i][j];
}
}
write(); //Prints the array
}
The three matrixs will be construct when you define Matrix A, B, C. So the matrix size is 2x2. When you call function cin to assign value to some position is not in 2x2 will not work.
So I need to find sum of all positive even numbers in every row (which I've already done actually). And then I have to sort these rows depending on their sums
As I think, it must be done in one function (otherwise there will be no connections as I cannot use global variables). In my case it's void print:
void print(const int** arr, int rows, int columns) {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
cout << setw(7) << arr[i][j];
}
cout << endl;
}
int sum = 0;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
if (arr[i][j] > 0 && arr[i][j] % 2 == 0)
{
//cout << setw(7) << arr[i][j];
sum = sum + arr[i][j];
}
}
cout << endl << "Sum of positive even elements in the row " << i + 1 << " = " << sum;
sum = 0;
}
}
Full code:
#include <iostream>
#include <iomanip>
#include <time.h>
#include <conio.h>
#include <algorithm>
using namespace std;
int** createMalloc(int, int);
int** createCalloc(int rows, int columns);
int** createNew(int rows, int columns);
void deleteNew(int** arr, int rows);
void init(int**, int, int);
void freeMemory(int**, int);
void print(const int**, const int, const int);
void initPrint(int** arr, int rows, int columns);
void main() {
int rowCount, colCount;
cout << "Enter number of rows: "; cin >> rowCount;
cout << "Enter number of columns: "; cin >> colCount;
cout << " Array creation algorithm\n";
start:
cout << "Input number : \n1 for malloc\n2 for calloc\n3 for new\n";
int k;
cin >> k;
switch (k) {
case 1: {
int** a = createMalloc(rowCount, colCount);
initPrint(a, rowCount, colCount);
freeMemory(a, rowCount);
break;
}
case 2: {
int** a = createCalloc(rowCount, colCount);
initPrint(a, rowCount, colCount);
freeMemory(a, rowCount);
break;
}
case 3: {
int** a = createNew(rowCount, colCount);
initPrint(a, rowCount, colCount);
deleteNew(a, rowCount);
break;
}
default:cout << "Input 1, 2 or 3, please.";
cout << endl << endl;
goto start;
}
cout << endl << endl;
}
int** createMalloc(int rows, int columns) {
int** arr = (int**)malloc(rows * sizeof(int*));
for (int i = 0; i < rows; i++) {
arr[i] = (int*)malloc(columns * sizeof(int));
}
return arr;
}
int** createCalloc(int rows, int columns) {
int** arr = (int**)calloc(rows, sizeof(int*));
for (int i = 0; i < rows; i++) {
arr[i] = (int*)calloc(columns, sizeof(int));
}
return arr;
}
int** createNew(int rows, int columns) {
int** arr = new int* [rows];
for (int i = 0; i < rows; i++) {
arr[i] = new int[columns];
}
return arr;
}
void initPrint(int** arr, int rows, int columns) {
init(arr, rows, columns);
print((const int**)arr, rows, columns);
}
void init(int** arr, int rows, int columns) {
const int Low = -2, High = 4;
srand((unsigned)time(NULL));
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
arr[i][j] = Low + rand() % (High - Low + 1);
}
}
}
void freeMemory(int** arr, int rows) {
for (int i = 0; i < rows; i++) {
free(arr[i]);
}
free(arr);
}
void deleteNew(int** arr, int rows) {
for (int i = 0; i < rows; i++) {
delete[] arr[i];
}
delete[] arr;
}
void print(const int** arr, int rows, int columns) {
// виведення масива на екран
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
cout << setw(7) << arr[i][j];
}
cout << endl;
}
int sum = 0;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
if (arr[i][j] > 0 && arr[i][j] % 2 == 0)
{
//cout << setw(7) << arr[i][j];
sum = sum + arr[i][j];
}
}
cout << endl << "Sum of positive even elements in the row " << i + 1 << " = " << sum;
sum = 0;
}
}
P.S. Two-dimensional arrays must be necessarily dynamic ones. Also, cannot do this task using vector. Only malloc, calloc and new
As I think, I need to transform function printSecondaryDiagonal (that actually print elements of secondary diagonal) into one-dimensional array and then sort its elements in ascending order, right?
P.S. Two-dimensional array in the beginning must be necessarily a dynamic one. Also, cannot do it using vector. Only malloc, calloc and new
#include <iostream>
#include <iomanip>
using namespace std;
void getManual(int** arr, int rows, int columns);
void getRandom(int** arr, int rows, int columns);
void printSecondaryDiagonal(int** arr, int rows, int columns);
void main() {
int rowCount = 5;
int colCount = 6;
cout << "Enter quantity of rows: ";
cin >> rowCount;
cout << "Enter quantity of columns: ";
cin >> colCount;
int** arr = new int* [rowCount];
for (int i = 0; i < rowCount; i++) {
arr[i] = new int[colCount];
}
cout << " Array formation algorithm\n";
start:
cout << "Input number : \n1 for manual\n2 for random\n";
int k;
cin >> k;
switch (k) {
case 1: getManual(arr, rowCount, colCount);
break;
case 2: getRandom(arr, rowCount, colCount);
break;
default:cout << "Input 1 or 2, please.";
cout << endl << endl;
goto start;
}
cout << endl;
printSecondaryDiagonal(arr, rowCount, colCount);
for (int i = 0; i < rowCount; i++) { //очищуємо память для кожного рядка
delete[] arr[i];
}
delete[] arr;
}
void getManual(int** arr, int rows, int columns) { //введення з клавіатури
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
cout << "a[" << i << "][" << j << "]=";
cin >> arr[i][j];
//cin >> *(*(arr + i) + j); //вказівникова форма
}
}
}
void getRandom(int** arr, int rows, int columns) { //випадкова генерація чисел
int lowest = -21, highest = 34;
int i, j;
srand(time(NULL));
// ініціалізація масива
for (i = 0; i < rows; i++) {
for (j = 0; j < columns; j++) {
arr[i][j] = lowest + rand() % (highest - lowest + 1);
cout << setw(7) << arr[i][j];
}
cout << endl;
}
}
Function that I need to transform into one-dimensional array and which is the main problem for me:
void printSecondaryDiagonal(int** arr, int rows, int columns) {
cout << "Secondary Diagonal: ";
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
// Condition for secondary diagonal
if ((i + j) == (columns - 1)) {
cout << arr[i][j] << setw(7);
}
}
}
}
The elements of the secondary diagonal can be extract with one for loop as I will show. The secondary diagonal will be save in an 1-d array `secDiag[i]`. Then, using `std::sort` in `algorithm` head file to sort this array in ascending order.
void printSecondaryDiagonal(int** arr, int rows, int columns) {
cout << "Secondary Diagonal: ";
int *secDiag = new int [rows];
int r, c;
for (r = 0; r < rows ; r++) {
c = columns - r -1;
if (c < 0) break;
secDiag[r] = arr[r][c];
}
for (int i =0; i<r; i++) std::cout << setw(7) << secDiag[i];
std::cout << std::endl;
std::cout << "After sorted: ";
std::sort(secDiag, secDiag+r);
for (int i =0; i<r; i++) std::cout << setw(7) << secDiag[i];
std::cout << std::endl;
delete [] secDiag;
}
A test run:
Enter quantity of rows: 3
Enter quantity of columns: 3
Array formation algorithm
Input number :
1 for manual
2 for random
2
33 -13 29
-7 -2 10
-8 18 6
Secondary Diagonal: 29 -2 -8
After sorted: -8 -2 29
void printSecondaryDiagonal(int** arr, int rows, int columns) {
cout << "Secondary Diagonal: ";
int i = 0;
int j = columns - 1;
int k = 0;
int size =0;
if (rows>columns)
{
size = columns;
}
else
{
size = rows;
}
int *diagonal = new int[size];
while (i < rows && j >= 0)
{
diagonal[k] = arr[i][j];
cout << arr[i][j] << setw (7);
i++;
j--;
k++;
}
for (int i = 0; i < size - 1; i++)
{
for (int j = 0; j < size - i - 1; j++)
{
if (diagonal[j] > diagonal[j + 1])
{
// swap arr[j+1] and arr[j]
int temp = diagonal[j];
diagonal[j] = diagonal[j + 1];
diagonal[j + 1] = temp;
}
}
}
for (int r = 0; r < size; r++)
{
cout << diagonal[r] << endl;
}
delete [] diagonal;
}
I am trying to get the program to run from 4 column of the seasons, and 2 columns for years 2016 and 2017. The input is rainfall for both years for each season. It is allowing me to enter numbers for times for winter and then stops and it is not calculating right. Any help as to what I am doing wrong?
#include <iostream>
#include <string>
using namespace std;
void Read(double rainfall[][4], int row);
void Calculate(double rainfall[][4], int row);
void Write(double rainfall[][4], int row);
int main()
{
double rainfall[2][4];
int row = 2;
Read(rainfall, row);
Calculate(rainfall, row);
Write(rainfall, row);
}
void Read(double rainfall[][4], int row)
{
for (int i = 0; i < row - 1; i++)
{
if (i == 0)
cout << "Enter rainfall for Winter: " << endl;
else if (i == 1)
cout << "Enter rainfall for Spring: " << endl;
else if (i == 2)
cout << "Enter rainfall for Summer: " << endl;
for (int j = 0; j < 2; j++)
{
cout << j + 1 << " : " << endl;
cin >> rainfall[i][j];
}
}
}
void Calculate(double rainfall[2][4], int row)
{
int i, j;
double row_sum;
for (i = 0; i < row; i++)
{
row_sum = 0;
for (j = 0; j < 4; j++)
{
row_sum = row_sum + rainfall[i][j];
}
rainfall[i][4] = row_sum;
}
double col_sum;
for (j = 0; j < 4; j++)
{
col_sum = 0;
for (i = 0; i < row - 1; i++)
{
col_sum = col_sum + rainfall[i][j];
}
rainfall[2][j] = col_sum;
}
}
void Write(double rainfall[][4], int row)
{
int i, j;
for (i = 0; i < row; i++)
{
for (j = 0; j < 4; j++)
cout << rainfall[i][j] << " ";
cout << endl;
}
}
Change this line
for (int i = 0; i < row - 1; i++)
to
for (int i = 0; i < row; i++)
In C++, you should use std::vector or std::array instead and avoid C style arrays, that way you get better help when you go out-of-bounds with your array which I think is happening in more places than one.
I'm working on a code that finds all saddle points in a matrix. Both smallest in their row and biggest in their column, and biggest in their row and smallest in their column fall under the definition (of my university) of a saddle point. Being a beginner I managed to get half of it done (finding saddle points which are smallest in their row and biggest in their column) by copying parts of what we've done in class and typing it myself. I have been stuck on it for quite some time and can't figure how to add the saddle points which are biggest in their row and smallest in their column to the program.
This is what I have so far:
#include <iostream>
#include <cstdlib>
using namespace std;
int a[10][10];
int x, y;
int pos_max(int j) //saddle points check
{
int max = 0;
for (int i = 1; i <= x - 1; i++) {
if (a[i][j] > a[max][j]) {
max = i;
}
}
return max;
}
int main() {
cout << "Enter the number of rows: ";
cin >> x;
cout << "Enter the number of columns: ";
cin >> y;
cout << "----------------------------" << endl;
for (int i = 0; i <= x - 1; i++) //input of the matrix
for (int j = 0; j <= y - 1; j++) {
cout << "a[" << i + 1 << ", " << j + 1 << "] = ";
cin >> a[i][j];
}
cout << "----------------------------\n";
for (int i = 0; i <= x - 1; i++) //visualization of the matrix
{
for (int j = 0; j <= y - 1; j++)
cout << a[i][j] << " ";
cout << endl;
}
cout << "----------------------------\n";
int r;
int flag = 0;
int i = y;
for (int j = 0; j <= y - 1; j++) {
r = pos_max(j);
for (i = 0; i <= y - 1; i++) {
if (a[r][i] < a[r][j]) {
break;
}
}
if (i == y) {
cout << "Saddle points are: ";
cout << "a[" << r + 1 << ", " << j + 1 << "] = " << a[r][j] << "\n";
flag = 1;
}
}
if (flag == 0) {
cout << "No saddle points\n";
}
cout << "----------------------------\n";
return 0;
}
First, there is a logical error with your code. In the pos_max function, it will return the index of the element which is maximum in the column. There can be a case when there are multiple maximum with the same value in the column, however, it returns the one which is not the minimum in the row, hence your program won't be able to print that saddle point.
To solve this, you can either return an array of all indices which are maximum in a column and then check for each of those points if it's minimum in their respective column, but I think it's not a very elegant solution. In any case, you will again have to write the entire code for the other condition for saddle points, minimum in column and maximum in row.
Hence, I would suggest a change in strategy. You create 4 arrays, max_row, max_col, min_row, min_col, where each array stores the minimum / maximum in that row / column respectively. Then you can traverse the array and check if that point satisfies saddle point condition.
Here is the code:
#include <iostream>
#include <cstdlib>
using namespace std;
int a[10][10];
int max_row[10], max_col[10], min_row[10], min_col[10];
int x, y;
bool is_saddle(int i, int j) {
int x = a[i][j];
return (max_row[i] == x && min_col[j] == x) || (min_row[i] == x && max_col[j] == x);
}
int main() {
/* code to input x, y and the matrix
...
*/
/* code to visualize the matrix
...
*/
/* populating max and min arrays */
for (int i = 0; i <= x-1; ++i) {
max_row[i] = a[i][0], min_row[i] = a[i][0];
for (int j = 0; j <= y-1; ++j) {
max_row[i] = max(max_row[i], a[i][j]);
min_row[i] = min(min_row[i], a[i][j]);
}
}
for (int j = 0; j <= y-1; ++j) {
max_col[j] = a[0][j], min_col[j] = a[0][j];
for (int i = 0; i <= x-1; ++i) {
max_col[j] = max(max_col[j], a[i][j]);
min_col[j] = min(min_col[j], a[i][j]);
}
}
/* Check for saddle point */
for (int i = 0; i <= x-1; ++i) {
for (int j = 0; j <= y-1; ++j) {
if (is_saddle(i, j)) {
cout << "Saddle points are: ";
cout << "a[" << i + 1 << ", " << j + 1 << "] = " << a[i][j] << "\n";
flag = 1;
}
}
}
if (flag == 0) {
cout << "No saddle points\n";
}
cout << "----------------------------\n";
return 0;
}
#include <iostream>
using namespace std;
int getMaxInRow(int[][5], int, int, int);
int getMinInColumn(int[][5], int, int, int);
void getSaddlePointCordinates(int [][5],int ,int );
void getInputOf2dArray(int a[][5], int, int);
int main()
{
int a[5][5] ;
int rows, columns;
cin >> rows >> columns;
getInputOf2dArray(a, 5, 5);
getSaddlePointCordinates(a,rows,columns);
}
void getInputOf2dArray(int a[][5], int rows, int columns)
{
for (int i = 0; i < rows; i = i + 1)
{
for (int j = 0; j < columns; j = j + 1)
{
cin >> a[i][j];
}
}
}
void getSaddlePointCordinates(int a[][5],int rows,int columns)
{
int flag = 0;
for (int rowNo = 0; rowNo < 5; rowNo++)
{
for (int columnNo = 0; columnNo < 5; columnNo++)
{
if (getMaxInRow(a, rows, columns, rowNo) == getMinInColumn(a, rows, columns, columnNo))
{
flag = 1;
cout << rowNo << columnNo;
}
}
}
if (flag == 0)
cout << "no saddle point";
cout << "\n";
}
int getMaxInRow(int a[][5], int row, int column, int rowNo)
{
int max = a[rowNo][0];
for (int i = 1; i < column; i = i + 1)
{
if (a[rowNo][i] > max)
max = a[rowNo][i];
}
return max;
}
int getMinInColumn(int a[][5], int row, int column, int columnNo)
{
int min = a[0][columnNo];
for (int i = 1; i < row; i = i + 1)
{
if (a[i][columnNo] < min)
min = a[i][columnNo];
}
return min;
}
just take the reference arr(ref[size]) // memorization method to check the minimum and maximum value in it.
Here is the Code Implementation with time complexity O(n *n) & space complexity O(n):
#include <bits/stdc++.h>
using namespace std;
#define size 5
void util(int arr[size][size], int *count)
{
int ref[size]; // array to hold all the max values of row's.
for(int r = 0; r < size; r++)
{
int max_row_val = arr[r][0];
for(int c = 1; c < size; c++)
{
if(max_row_val < arr[r][c])
max_row_val = arr[r][c];
}
ref[r] = max_row_val;
}
for(int c = 0; c < size; c++)
{
int min_col_val = arr[0][c];
for(int r = 1; r < size; r++) // min_val of the column
{
if(min_col_val > arr[r][c])
min_col_val = arr[r][c];
}
for(int r = 0; r < size; r++) // now search if the min_val of col and the ref[r] is same and the position is same, if both matches then print.
{
if(min_col_val == ref[r] && min_col_val == arr[r][c])
{
*count += 1;
if((*count) == 1)
cout << "The cordinate's are: \n";
cout << "(" << r << "," << c << ")" << endl;
}
}
}
}
// Driver function
int main()
{
int arr[size][size];
for(int i = 0; i < size; i++)
{
for(int j = 0; j < size; j++)
cin >> arr[i][j];
}
int count = 0;
util(arr, &count);
if(!count)
cout << "No saddle points" << endl;
}
// Test case -> Saddle Point
/*
Input1:
1 2 3 4 5
6 7 8 9 10
1 2 3 4 5
6 7 8 9 10
0 2 3 4 5
Output1:
The cordinate's are:
(0,4)
(2,4)
(4,4)
Input2:
1 2 3 4 5
6 7 8 9 1
10 11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
Output2:
No saddle points
*/