2D Arrays - sum diagonals, transpose, shift columns - c++

I recently turned in homework which I had thought I had done correct but my teacher marked me for things that I honestly thought were right.
The first question: Fill up the following code for computing the sum of values on the principal and minor diagonal in a square matrix A[7][7]. Assume the matrix is defined
int sum = 0; // he marked this wrong. Why is initializing to 0 wrong?
for(int i = 0; i < 7; i++) {
for(int j = 0; j < 7; j++) { // also marked j < 7 wrong
sum = sum + A[i][i] + A[i][7-1-i]
}
return sum;
}
Question 2: Transpose a square matrix A[50][50] i.e., the first row becomes the first column and vice-versa, the second row becomes the second column and so on. Assume the matrix is defined.
void transposeSquare(){
for(int i=0;i<50;i++){
for(int j=0;j<50;j++){ //marked j=0 wrong
int temp = A[i][i];
A[i][j] = A[j][i];
A[j][i] = temp;
}
}
}
Why is j=0 in transposeSquare not right?
Why would sum be anything other than 0?
If i < 7 should j < 7 too if its a square matrix?
Thanks!

Your logic is wrong for couple of reasons.
By using a nested loop inside the outer loop, you are adding the numbers in the diagonals 7 times instead of just once.
When i is 3, the line
sum = sum + A[i][i] + A[i][7-1-i]
is equivalent to:
sum = sum + A[3][3] + A[3][7-1-3]
which is the same as:
sum = sum + A[3][3] + A[3][3]
Adding A[3][3] twice to the sum is not correct.
To fix the problems, use:
for(int i = 0; i < 7; i++){
sum = sum + A[i][i] + A[i][7-1-i];
}
sum -= A[3][3]; // Remove the element that was added twice.
You can use += to simplify the code a little bit.
for(int i = 0; i < 7; i++){
sum += A[i][i] + A[i][7-1-i];
}
sum -= A[3][3]; // Remove the element that was added twice.

Your code has small errors that's why your teacher has entitled your code as wrong.
For the first part,
int sum = 0;
int size = 7;
for(int i = 0; i < size; i++) {
sum += A[i][j] + A[i][sz-1-i]; // Error: Typo, it should be A[i][j] instead of A[i][i]
}
if(size%2 != 0)
sum -= A[size/2][size/2]; // Missed Case: Subtract the middle element since its repeated only when the size of array is an odd number
return sum; // Return the sum at the end!
For second Part You don't need to iterate the whole two-D array. Because if you do so it will copy upper triangle into lower triangle instead of calculating the Transpose. So traverse any triangle (Upper or Lower).
Like I have traversed Lower Triangle in this code.
void transposeSquare(){
for(int i=0;i<50;i++){
for(int j=0; j<i ;j++){ // Fix 1: Loop j to i-1
int temp = A[i][j]; // Fix 2: Typo it should be A[i][j] instead of A[i][i]
A[i][j] = A[j][i];
A[j][i] = temp;
}
}
}
Checkout Triangular Matrix for better explanation.

Related

CS question in using loops instead of built-in math functions in c++

i got this question and i dont understand what this program is supposed to do.
the question is:
Show the pairs of numbers between 1 and 1000 whose sum of squares is a power third of any number, and the sum of their third powers is the square of some number. Do not use mathematical functions such as ..., sqrt, pow
Can anyone explain what I'm supposed to do, and how exactly can a loop replace the pow and sqrt functions.
Show the pairs of numbers between 1 and 1000 whose sum of squares is a power third of any number, and the sum of their third powers is the square of some number. Do not use mathematical functions such as ..., sqrt, pow
Let's try it.
Show the pairs of numbers between 1 and 1000
for(int i = 0; i <= 1000; i++)
for(int j = i; j <= 1000; j++) // starting at i to not repeat pairs twice
whose sum of squares
for(int i = 0; i <= 1000; i++)
for(int j = i; j <= 1000; j++) // starting at i to not repeat pairs twice
{
int sumSquare = i * i + j * j;
is a power third of any number
for(int i = 0; i <= 1000; i++)
for(int j = i; j <= 1000; j++) // starting at i to not repeat pairs twice
{
int sumSquare = i * i + j * j;
bool found = false;
for(int k = 1; k * k * k <= sumSquare; k++) // inefficient
{
if (k * k * k == sumSquare)
{
found = true;
}
}
if (found)
{
cout << i << " " << j << " " << k << endl;
}
}
and so on... You'll need to add the third condition, you may need to deal with overflows, maybe use size_t, and make it more efficient.
But that should give you the correct ideas...

Find the largest Magic Square

Given an m x n integer grid, return the size (i.e., the side length k) of the largest magic square that can be found within this grid.
The question can be found here on leetcode
I first wanted to see if a naive brute force approach would pass, so I came up with the following algorithm
Iterate through all values of k (from min(rows,cols) of the matrix to 1)
For each of the k values, check if it's possible to create a magic of square of dimensions kxk by checking all possible sub matrices and
return k if it's possible. This would be O(rows*cols*k^2)
So that would make the overall complexity O(k^3*rows*cols). (Please correct me if I am wrong)
I have attached my code in C++ below
class Solution {
public:
int largestMagicSquare(vector<vector<int>>& grid) {
int rows = grid.size(),cols = grid[0].size();
for(int k = min(rows,cols); k >= 2; k--){ // iterate over all values of k
for(int i = 0; i < rows-k+1; i++){
for(int j = 0; j < cols-k+1; j++){
int startX = i, startY = j, endX = i+k-1, endY = j+k-1;
int diagSum = 0, antiDiagSum = 0;
bool valid = true;
// calculate sum of diag
for(int count = 0; count < k; count++){
diagSum += grid[startX][startY];
startX++,startY++;
}
// this is the sum that must be same across all rows, cols, diag and antidiag
int sum = diagSum;
// calculate sum of antidiag
for(int count = 0; count < k; count++){
antiDiagSum += grid[endX][endY];
endX--,endY--;
}
if(antiDiagSum != sum) continue;
// calculate sum across cols
for(int r = i; r <=i+k-1; r++){
int colSum = 0;
for(int c = j; c <= j+k-1; c++){
colSum += grid[r][c];
}
if(colSum != sum){
valid = false;
break;
}
}
if(!valid) continue;
// calculate sum across rows
for(int c = j; c <= j+k-1; c++){
int rowSum = 0;
for(int r = i; r <= i+k-1; r++){
rowSum += grid[r][c];
}
if(rowSum != sum){
valid = false;
break;
}
}
if(!valid) continue;
return k;
}
}
}
return 1;
}
};
I thought I would optimize the solution once this works (Maybe binary search over the values of k). However, my code is failing for a really large test case for a matrix of dimension 50x50 after passing 74/80 test cases on Leetcode.
I tried to find out the source(s) that could be causing it to fail, but I am not really sure where the error is.
Any help would be appreciated. Thanks!
Please do let me know if further clarification about the code is needed
The calculation of antiDiagSum is wrong: it actually sums the values on the same diagonal as diagSum, just in reverse order. To traverse the opposite diagonal, you need to increment the Y coordinate and decrement the X coordinate (or vice versa), but your code decrements both of them.
It is probably easiest if you fix this by calculating both diagonal sums in the same loop:
for(int count = 0; count < k; count++){
diagSum += grid[startX][startY];
antiDiagSum += grid[endX][startY];
startX++, startY++, endX--;
}

Partial Pivoting/Gaussian elimination- swapping columns instead of rows producing wrong output

I'm trying to implement a quick program to solve a system of linear equations. The program reads the input from a file and then writes the upper-triangular system and solutions to a file. It is working with no pivoting, but when I try to implement the pivoting it produces incorrect results.
As example input, here is the following system of equations:
w+2x-3y+4z=12
2w+2x-2y+3z=10
x+y=-1
w-x+y-2z=-4
I expect the results to be w=1, x=0, y=-1 and z=2. When I don't pivot, I get this answer (with some rounding error on x). When I add in the pivoting, I get the same numbers but in the wrong order: w=2,x=1,y=-1 and z=0.
What do I need to do to get these in the correct order? Am I missing a step somewhere? I need to do column swapping instead of rows because I need to adapt this to a parallel algorithm later that requires that. Here is the code that does the elimination and back substitution:
void gaussian_elimination(double** A, double* b, double* x, int n)
{
int maxIndex;
double temp;
int i;
for (int k = 0; k < n; k++)
{
i = k;
for (int j = k+1; j < n; j++)
{
if (abs(A[k][j]) > abs(A[k][i]))
{
i = j;
}
}
if (i != k)
{
for (int j = 0; j < n; j++)
{
temp = A[j][k];
A[j][k] = A[j][i];
A[j][i] = temp;
}
}
for (int j = k + 1; j < n; j++)
{
A[k][j] = A[k][j] / A[k][k];
}
b[k] = b[k] / A[k][k];
A[k][k] = 1;
for (i = k + 1; i < n; i++)
{
for (int j = k + 1; j < n; j++)
{
A[i][j] = A[i][j] - A[i][k] * A[k][j];
}
b[i] = b[i] - A[i][k] * b[k];
A[i][k] = 0;
}
}
}
void back_substitution(double**U, double*x, double*y, int n)
{
for (int k = n - 1; k >= 0; k--)
{
x[k] = y[k];
for (int i = k - 1; i >= 0; i--)
{
y[i] = y[i] - x[k]*U[i][k];
}
}
}
I believe what you implemented is actually complete pivoting.
With complete pivoting, you must keep track of the permutation of columns, and apply the same permutation to your answer.
You can do this with an array {0, 1, ..., n}, where you swap the i'th and k'th values in the second loop. Then, rearange the solution using this array.
If what you were trying to do is partial pivoting, you need to look for the maximum in the respective row, and swap the rows and the values of 'b' accordingly.

Locating the largest element in the row of a multi dimensional array

I'd like to subtract the highest element in this 5x2 matrix, with it's subsequent element, in the other column.
For ex: the highest element right now is 150, whose location is (4,1). I'd like to subtract 150 with 89, which is it's subsequent element. In the same way if the highest element belonged to the first column, then it should subtract itself from the element in the next column.
Thanks
int big=0,lead=0,m,n;
int a[5][2]={140,82,89,150,110,110,112,106,88,90};
for(int j=0; j<5; j++)
{
for(int i=0 ; i<2; i++)
{
m=j;
n=i;
if(a[j][i] > big)
{
big = a[j][i];
if(big == a[j][i])
{
lead = big-a[j][1];
}
else
{
lead = big-a[1][i];
}
}
}
}
cout<<big<<"\n"<<lead<<"\n"<<m<<","<<n<<endl;
}
I think you declare the array wrong, i build 2D array as
int a[2][5] = {
{140,82,89,150,110},
{110,112,106,88,90}
};
First, you want to find the largest using big variable (i assume). So
int big = 0,n,m;
for(int x = 0; x < 2; x++){
for(int y = 0; y < 5; y++){
if(a[x][y] > big){
big = a[x][y];
n = x;
m = y;
}
}
}
Here you save the biggest and it's coordinate at n and m variable.
After that, you want to subtract it with column - 1 (column + 1 if it is on the first column)
if(m == 0){
big -= a[n][m + 1];
}
else{
big -= a[n][m - 1];
}

Multiplying Matrices using 2d Vectors in C++

I'm trying to design a program that creates a matrix using vectors of vectors of integers, and then multiplyies it with another matrix. I know how to multiply matrices on paper, but when I try to implement it in my program, I'm not getting it to work. I know that both matrices are entered correctly and are passed correctly as I have the the output of those functions so that I can debug. The program works incorrectly when I try to multiply them. The answer and the number of elements are not right. I know I'm missing something but can't figure out what.
Matrix Matrix::operator*(Matrix m){
vector<int> mRow = m.getRow(0);
vector<int> mCol = m.getCol(0);
vector<int> newElem;
int product = 0;
//adds the contents of the 2nd matrix to the 2d vector
vector< vector<int> > m2(mRow.size(), vector<int>(mCol.size()));
for (int i = 0; i < mRow.size(); i++){
mRow.clear();
mRow = m.getRow(i);
for (int j = 0; j < mCol.size(); j++){
m2[j][i] = mRow[j];
}
}
//Multiplies the matrices using the 2d matrix**THIS IS WHERE IT GOES WRONG**
for (int i = 0; i < row; i++){
for (int j = 0; j < column; j++){
product += matrix[i][j]*m2[j][i];
}
newElem.insert(newElem.begin()+i,product);
product = 0;
}
//displays the products so that i can see if its working
for (int i = 0; i < newElem.size(); i++){
cout << " "<<newElem[i]<<endl;
}
//adds the new product vector to a new Matrix object and returns it
Matrix newM(row, mCol.size());
vector<int> temp;
for (int i = 0; i < row; i++){
for (int j = 0; j < mCol.size(); j++){
temp.insert(temp.begin()+j, newElem[0]);
newElem.erase(newElem.begin());
}
newM.setRow(temp,i);
temp.clear();
}
return newM;
}
Although I don't know whether this helps, I'm using this site as a reference for multiplying 2 matrices together.
Your matrix representation has nothing to do with your mistake. You need to have more nested iterations. Think of a result matrix and iterate through that to calculate it's every element. In a pseudocode:
for i in result column
for j in result row
res[i, j] = multiply(m1, m2, i, j)
where multiply function is the nested loop, something like this:
multiply(m1, m2, i, j)
{
val = 0;
for k in row
val += m1[i, k] * m2[k, j]
return val
}
Here is an implementation of the outer loops. Mind you, there are no error checking in the code.
vector<vector<int> > ml;
vector<vector<int> > mr;
// fill in ml and mr
...
// result matrix
vector<vector<int> > res;
// allocate the result matrix
res.resize(ml.size());
for( it = res.begin(); it != res.end(); ++it)
it->resize(ml[0].size());
// loop through the result matrix and fill it in
for( int i = 0; i < res.size(); ++i)
for( int j = 0; j < res[0].size(); ++j)
res[i][j] = multiply(ml, mr, i, j);
Leaving a proper implementation of multiply() function to you.