C++ For loops and multidimensional arrays - c++

So I have an assignment for my C++ class. Basically we have to create a 3x3 multidimensional array, calculate the sum of rows, sum of columns, sum of diagonal values and sum of anti-diagonal values, I usually just input 1 2 3 4 5 6 7 8 9 as values as a starting point.
Now, I'm not trying to be rude but my teacher is not very good, we basically spend 2 hours on a single problem without her doing much explaining. Other than that I started with C++ Primer and Programming: Principles and Practice Using C++ so I believe I'll be able to learn a lot on my own.
Anyhow my questions are probably quite stupid, but if anyone feels like helping, here they are:
My /**/ commented for loop for anti-diagonal value gives me a wrong sum. I'm assuming it has something to do with the nature of for-loops or I just type it out wrong, but I didn't figure it out yet.
2.The teacher's solution for calculating the anti-diagonal values is the following:
for (i = 0; i < row_num; ++i)
for (j = 0; j < col_num; ++j)
if (i + j == row_num - 1)
anti-diagonal += A[i][j];
How is it different from my approach? I believe mine is simpler and works better.
3.In line:
int sumRows[row_num] = { 0 };
Why do {} have to be used? Our teacher didn't bother with explaining that. I tried without {} but I got an error.
Here is the full code for my version:
#include "../../std_lib_facilities.h"
#include <iostream>
using namespace std;
#define row_num 3 //no. of rows
#define col_num 3 //no. of columns
int main()
{
int i = 0;
int j = 0;
int diagonal = 0;
int antidiagonal = 0;
int sumRows[row_num] = { 0 };
int sumCol[col_num] = { 0 };
int A[row_num][col_num];
//Input to matrix
for(i=0; i<row_num; i++)
for (j = 0; j < col_num; j++)
{
cout << "A[" << i << "]" << "[" << j << "]: ";
cin >> A[i][j];
sumRows[i] += A[i][j];
sumCol[j] += A[i][j];
}
cout << endl;
//Print out the matrix
for (i = 0; i < row_num; i++)
{
for (j = 0; j < col_num; j++)
cout << A[i][j] << '\t';
cout << endl;
}
//prints sum of rows
for (i = 0; i < row_num; i++)
cout << "Sum of row " << i + 1 << " "<< sumRows[i] << endl;
//prints sum of columns
for (j = 0; j < row_num; j++)
cout << "Sum of column " << j + 1 << " " << sumCol[j] << endl;
//Sum of diagonal values
for (i = 0; i < row_num; i++)
diagonal += A[i][i];
//Sum of antidiagonal values
for (i = 0, j = 2; i < row_num, j >= 0; i++, j--)
antidiagonal += A[i][j];
/*for(i=0; i<row_num; i++)
for (j = 2; j >= 0; j--)
{
antidiagonal += A[i][j];
}
*/
cout << "\nSum of diagonal values: " << diagonal << endl;
cout << "Sum of antdiagonal values: " << antidiagonal << endl;
return 0;
}

1) Your commented out loop sums all values, not just those along the antidiagonal.
2) It is different from your approach in that it will iterate over every value in the matrix, but then it will only add to the total if it detects it is in one of the appropriate cells. Your solution only iterates over the appropriate cells and doesn't have to evaluate any ifs, so it will be more efficient. However, you need to change your loop condition to i < row_num && j >= 0. Using a comma here will discard the result of one of the checks.
3) int sumRows[row_num] = { 0 }; initializes the whole sumRows array with 0's.

1) This
for(i=0; i<row_num; i++)
for (j = 2; j >= 0; j--)
{
antidiagonal += A[i][j];
}
is wrong, because for i=0 you iterate through all j values, ie
i=0 , j=2,1,0 then i=1
2) Your teachers loop is easier to read and correct. Yours has a wrong break condition:
for (i = 0, j = 2; i < row_num, j >= 0; i++, j--)
^------------------------ WRONG
Read about the comma operator to understand what is actually going on here. You just didnt realize the problem, because the two conditions are by chance equivalent.
3) You dont have to use it, it is just a new and fancy way to initialize the array.

Related

Checking how many times a number has been entered

I'm trying to solve one of the questions on a task sheet I've received, to help me further in my understanding of C++ code from my class.
It kept showing 100000 in output after I entered the values. Where is that 1 coming from?
I know there are better ways to write code for this but I just want to know were is my problem.
The question is
(and I quote):
Write a program that:
Asks the user to enter 10 numbers between 1 and 5 into an array and displays the array on screen.
Creates a second array of size 5 and fills it with zeros.
Counts how many 1s, 2s, , … 5s have been entered into the first array and stores this number in the second array.
Displays the second array as shown in the example below.
Code:
int A1[10];
int A2[5] = { 0,0,0,0,0 };
int count = 10;
for (int i = 0; i < count; i++)
{
here:
cout << endl << i + 1 << "- enter a number between 1 and 5 for value : ";
cin >> A1[i];
if (A1[i] < 1 || A1[i]>5)
{
cout << "eror! enter a number between 1 and 5!";
goto here;
}
}
for (int i = 0; i < 10; i++)
{
for (int j = 1; j < 6; j++)
{
if (A1[i] = j)
{
A2[j - 1]++;
break;
}
}
}
for (int i = 0; i < 5; i++)
cout << A2[i];
The error is on the row 21 or 22, you are using a single = which is the assignment sign, inside the if statement, so you are overwriting the value of A[i] to the value of j, but want to check if the element of A[i] is equal to j... So you have to add a = in the if statement.
I don't recommend that you use goto:, it creates spaghetti code. you can put an i-- in your error clause, like so:
int temp;
for (int i = 0; i < count; i++){
cout << i + 1 << "- enter a number between 1 and 5 for value : " << endl;
cin >> temp;
if (temp >= 1 && temp <=5)
A1[i] = temp;
else
i--;
}
Also, if you want to compare 2 values, you should use the == operator. that is what's causing the problem in your second loop
like so:
for(int i = 0; i < count; i++){
for(int j = 1; j < 6; j++)
if(A1[i] == j)
A2[j-1]++;
}
This should work.

How do I write a code in C++ for fitting a quadratic polynomial to a dataset? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I'm not brilliant at coding, I'm just starting off and the code I created runs with that many errors I feel like I should just start again, but I have no clue what to do differently.
Below is the code I'm running that's coming back with all the errors, I just can't put my finger on what I'm doing wrong and it's so overwhelming.
Please help if you can, thank you x
Edit: sorry I forgot to add the errors! I've got 23 errors, most are 'array type is not assignable' and 'expression did not evaluate to a constant'
#include<iomanip>
#include<cmath>
using namespace std;
int main()
{
int i, j, k, n, N;
cout.precision(4); //set precision
cout.setf(ios::fixed);
cout << "\nEnter the no. of data pairs to be entered:\n"; //To find the size of arrays that will store x,y, and z values
cin >> N;
double x[N], y[N];
cout << "\nEnter the x-axis values:\n"; //Input x-values
for (i = 0; i < N; i++)
cin >> x[i];
cout << "\nEnter the y-axis values:\n"; //Input y-values
for (i = 0; i < N; i++)
cin >> y[i];
cout << "\nWhat degree of Polynomial do you want to use for the fit?\n";
cin >> n; // n is the degree of Polynomial
double X[2 * n + 1]; //Array that will store the values of sigma(xi),sigma(xi^2),sigma(xi^3)....sigma(xi^2n)
for (i = 0; i < 2 * n + 1; i++)
{
X[i] = 0;
for (j = 0; j < N; j++)
X[i] = X[i] + pow(x[j], i); //consecutive positions of the array will store N,sigma(xi),sigma(xi^2),sigma(xi^3)....sigma(xi^2n)
}
double B[n + 1][n + 2], a[n + 1]; //B is the Normal matrix(augmented) that will store the equations, 'a' is for value of the final coefficients
for (i = 0; i <= n; i++)
for (j = 0; j <= n; j++)
B[i][j] = X[i + j]; //Build the Normal matrix by storing the corresponding coefficients at the right positions except the last column of the matrix
double Y[n + 1]; //Array to store the values of sigma(yi),sigma(xi*yi),sigma(xi^2*yi)...sigma(xi^n*yi)
for (i = 0; i < n + 1; i++)
{
Y[i] = 0;
for (j = 0; j < N; j++)
Y[i] = Y[i] + pow(x[j], i) * y[j]; //consecutive positions will store sigma(yi),sigma(xi*yi),sigma(xi^2*yi)...sigma(xi^n*yi)
}
for (i = 0; i <= n; i++)
B[i][n + 1] = Y[i]; //load the values of Y as the last column of B(Normal Matrix but augmented)
n = n + 1; //n is made n+1 because the Gaussian Elimination part below was for n equations, but here n is the degree of polynomial and for n degree we get n+1 equations
cout << "\nThe Normal(Augmented Matrix) is as follows:\n";
for (i = 0; i < n; i++) //print the Normal-augmented matrix
{
for (j = 0; j <= n; j++)
cout << B[i][j] << setw(16);
cout << "\n";
}
for (i = 0; i < n; i++) //From now Gaussian Elimination starts(can be ignored) to solve the set of linear equations (Pivotisation)
for (k = i + 1; k < n; k++)
if (B[i][i] < B[k][i])
for (j = 0; j <= n; j++)
{
double temp = B[i][j];
B[i][j] = B[k][j];
B[k][j] = temp;
}
for (i = 0; i < n - 1; i++) //loop to perform the gauss elimination
for (k = i + 1; k < n; k++)
{
double t = B[k][i] / B[i][i];
for (j = 0; j <= n; j++)
B[k][j] = B[k][j] - t * B[i][j]; //make the elements below the pivot elements equal to zero or elimnate the variables
}
for (i = n - 1; i >= 0; i--) //back-substitution
{ //x is an array whose values correspond to the values of x,y,z..
a[i] = B[i][n]; //make the variable to be calculated equal to the rhs of the last equation
for (j = 0; j < n; j++)
if (j != i) //then subtract all the lhs values except the coefficient of the variable whose value is being calculated
a[i] = a[i] - B[i][j] * a[j];
a[i] = a[i] / B[i][i]; //now finally divide the rhs by the coefficient of the variable to be calculated
}
cout << "\nThe values of the coefficients are as follows:\n";
for (i = 0; i < n; i++)
cout << "x^" << i << "=" << a[i] << endl; // Print the values of x^0,x^1,x^2,x^3,....
cout << "\nHence the fitted Polynomial is given by:\ny=";
for (i = 0; i < n; i++)
cout << " + (" << a[i] << ")" << "x^" << i;
cout << "\n";
return 0;
}
You have in your code several variables which are declared as double x[N], where N is a variable that is known only at run-time. This is not guaranteed to be supported. Instead, you should use a std::vector, initialized like this: std::vector<double> x(N). This creates a vector of doubles of size N, zero-initialized. Look up how to use vectors here: https://en.cppreference.com/w/cpp/container/vector . Also, you should use descriptive variable names, which will help you read and understand your own code (and others you're asking for help). Don't be afraid of 23 error messages, I routinely get 100+ on first compilation of a fresh batch of code. Often they can cascade where one causes a lot of others down the line, so work starting from the one that's earliest in the code, recompiling after every bugfix. The 100+ effectively become 30 or so, sometimes.
Also, it would be helpful to split your function into several functions, and test each one individually, then bring them all together.

jacobi iterative method has wrong answer in c++

I'm writing Jacobi iterative method to solve any linear system of equations. this program works for some examples but doesn't work for others. for example for
A= and B=
7 3 5
2 3 4
this will works and answers are true but for
A= and B=
1 2 3
3 4 7
the answers are wrong and huge numbers.
I really don't know what should I do to make a correct calculation.
I used some other codes but still I have this issue with codes.
#include <iostream>
using namespace std;
int main(){
double A[10][10], alpha[10][10], B[10], betha[10], x[10][100], sum[10];
int i, j, n, k, kmax;
cout << "insert number of equations \n";
cin >> n;
cout << "insert LHS of equations (a11,a12,...,ann)\n";
for (i = 1; i <= n; i++){
for (j = 1; j <= n; j++){
cin >> A[i][j];
}
}
cout << "A=\n";
for (i = 1; i <= n; i++){
for (j = 1; j <= n; j++){
cout << A[i][j] << "\t\t";
}
cout << "\n\n";
}
cout << "alpha=\n";
for (i = 1; i <= n; i++){
for (j = 1; j <= n; j++){
if (i == j){
alpha[i][j] = 0;
}
else{
alpha[i][j] = -A[i][j] / A[i][i];
}
}
}
for (i = 1; i <= n; i++){
for (j = 1; j <= n; j++){
cout << alpha[i][j] << "\t\t";
}
cout << "\n\n";
}
cout << "insert RHS of equations";
for (i = 1; i <= n; i++){
cin >> B[i];
}
cout << "\nbetha=\n";
for (i = 1; i <= n; i++){
betha[i] = B[i] / A[i][i];
cout << betha[i] << endl;
}
cout << "Enter the number of repetitions." << endl;
cin >> kmax;
k = 0;
for (i = 1; i <= n; i++){
sum[i] = 0;
x[i][k] = betha[i]; //initial values
}
for (k = 0; k <= kmax; k++){
for (i = 1; i <= n; i++){
for (j = 1; j <= n; j++){
sum[i] += alpha[i][j] * x[j][k];
}
x[i][k] = betha[i] + sum[i];
sum[i] = 0;
}
}
cout << "answers:\n\n";
for (i = 1; i <= n; i++){
cout << x[i][kmax] << endl;
}
return 0;
}
You should again check the condition for convergence. There you will find that usually the method only converges for diagonally dominant matrices. The first example satisfies that condition, while the second violates it clearly.
If convergence is not guaranteed, divergence might happen, as you found.
More specifically, the Jacobi iteration in the second example computes
xnew[0] = (3 - 2*x[1])/1;
xnew[1] = (7 - 3*x[0])/4;
Over two iterations the composition of steps gives
xtwo[0] = (3 - 2*xnew[1])/1 = -0.5 + 1.5*x[0];
xtwo[1] = (7 - 3*xnew[0])/4 = -0.5 + 1.5*x[1];
which is clearly expanding the initial errors with factor 1.5.
Your matrix, in row order, is: [{1, 2} {3, 4}]
It has determinant equal to -2; clearly it's not singular.
It has inverse: [{4, -2}, {-3, 1}]/(-2)
The correct solution is: {1, 1}
You can verify this by substituting back into the original equation and checking to make sure you have an identity: [{1, 2} {3, 4}]{1, 1} = {3, 7}
Iterative methods can be sensitive to initial conditions.
The point about diagonally dominant is correct. Perhaps a more judicious choice of initial condition, closer to the right answer, would allow you to converge.
Update:
Jacobi iteration decomposes the matrix into diagonal elements D and off-diagonal elements R:
Jacobi will converge if:
Since this is not the case for the first row of your sample matrix, you might have a problem.
You still get there in a single step if you use the correct answer as your initial guess. This says that even Jacobi will work with a judicious choice.
If I start with {1, 1} I converge to the correct answer in a single iteration.

Two-dimensional array: calculate sum of rows and product of columns

I am currently working on a task which says the following:
Input a two-dimensional array A (m,n) [m < 10, n < 20]. In the n + 1 column calculate the sum of the rows, and in the m + 1 row the product of the columns. Print out the resulting matrix.
According to my understanding of this task, at the end of each column must be the sum of according rows (so on the right hand side), and the product of the column (at the end/bottom?).
This task is so confusing I do not know where to start. I found some code that covers the idea but does not include the product and it does not display these values as the task asks me to:
#include<iostream.h>
#include<conio.h>
void main()
{
clrscr();
int a[3][3];
int i, j, s = 0, sum = 0;
cout << "Enter 9 elements of 3*3 Matrix \n";
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++)
cin >> a[i][j];
cout << "Matrix Entered By you is \n";
for (i = 0; i < 3; i++)
{
for (j = 0; j < 3; j++)
cout << a[i][j] << " ";
cout << endl;
}
for (i = 0; i < 3; i++)
{
for (j = 0; j < 3; j++)
s = s + a[i][j];
cout << "sum of" << i + 1 << " Row is" << s;
s = 0;
cout << endl;
}
cout << endl;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 3; j++)
s = s + a[j][i];
cout << "sum of" << i + 1 << " Column is" << s;
s = 0;
cout << endl;
}
cout << endl;
for (i = 0; i < 3; i++)
sum = sum + a[i][i];
cout << "Sum of Diagnols Elements is \n" << sum;
getch();
}
We beginners should help each other.
Here you are
#include <iostream>
#include <iomanip>
int main()
{
const size_t M = 10;
const size_t N = 20;
int a[M][N] = {};
std::cout << "Enter number of rows: (less than " << M << "): ";
size_t m;
std::cin >> m;
if (!(m < M) || (m == 0)) m = M - 1;
std::cout << "Enter number of columns: (less than " << N << "): ";
size_t n;
std::cin >> n;
if (!(n < N) || (n == 0)) n = N - 1;
std::cout << std::endl;
for (size_t i = 0; i < m; i++)
{
std::cout << "Enter " << n
<< " numbers for the row " << i << ": ";
for (size_t j = 0; j < n; j++) std::cin >> a[i][j];
}
for (size_t j = 0; j < n; j++) a[m][j] = 1;
for (size_t i = 0; i < m; i++)
{
for (size_t j = 0; j < n; j++)
{
a[i][n] += a[i][j];
a[m][j] *= a[i][j];
}
}
std::cout << std::endl;
for (size_t i = 0; i < m + 1; i++)
{
for (size_t j = 0; j < n + 1; j++)
{
std::cout << std::setw(3) << a[i][j] << ' ';
}
std::cout << '\n';
}
std::cout << std::endl;
}
The program output might look like
Enter number of rows: (less than 10): 3
Enter number of columns: (less than 20): 3
Enter 3 numbers for the row 0: 1 2 3
Enter 3 numbers for the row 1: 4 5 6
Enter 3 numbers for the row 2: 7 8 9
1 2 3 6
4 5 6 15
7 8 9 24
28 80 162 0
So you have to declare an array with 10 rows and 20 columns. The user should enter the dimensions of the array that are correspondingly less than 10 and 20. One row and one column are reserved for sums and products.
It is desirable that the array would be initially initialized by zeroes.
int a[M][N] = {};
In this case you need not to set the last column with zeroes as you have to do with last row initializing it with ones.
That is all.:)
Start with the declaration: make sure that your program works with m×n matrix, not simply a 3×3 matrix. Since m and n have limits of 10 and 20, and because you must add an extra row and a column to the result, the declaration should be
int a[11][21];
You also need to declare m and n, have end-user enter them, and validate them to be within their acceptable ranges:
int m, n;
cin >> m >> n;
... // Do the validation
Now you can rewrite your loops in terms of m and n, rather than using 3 throughout your code.
With these declarations in place, you can total the numbers in place, i.e. for each row r you would write
for (int i = 0 ; i != n ; i++) {
a[r][n+1] += a[r][i];
}
Similarly, you would compute the product (don't forget to start it with the initial value of 1, not 0).
At the end you would print an (m+1)×(n+1) matrix to complete the task.
Solution : use this kind of functions for your array after making it global.
void Adder(int row, int colum)
{
for (int i = 0; i < row - 1; i++)
{
int temp = 0;
for (int j = 0; j < colum - 1; j++)
{
temp += a[i][j]; // added all other than last one
}
a[i][j] = temp; // assigned to last one in row
}
}
void Mul(int row, int colum)
{
for (int i = 0; i < colum- 1; i++)
{
int temp = 1;
for (int j = 0; j < row - 1; j++)
{
temp *= a[j][i]; // multiplied all element other than last one
}
a[j][i] = temp; // assigned to last one in column
}
}

C++ unexpected memory error

I've problem with easy C++ program which finds the largest submatrix in given matrix:
int *A = new int[n*m];
... setting fields for matrix, finding the largest one and etc
... r := size of square-submatrix, max_i := row, max_j := column of the largest
for (i = max_i; i < max_i + r; i++)
{
for (j = max_j; j < max_j + r; j++)
cout << A[i * n + j] << "\t";
cout << "\n";
}
<memory free>
end of program
Everything works great (so it's not problem with logic) - finding correct submatrix, prinitng etc.
Unexpectedly (or due to late night) when I put in memory free line delete[] A or delete everything crushes down with errors (but it's still printing result correctly - so the error must be in this line). I've tried set it to NULL and every combination. What goes wrong?
Thanks in advance
EDIT:
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
int i,j,k;
int m,n;
int r;
cout << "Size of matrix: \nRows: ";
cin >> n;
cout << "Columns: ";
cin >> m;
int *A = new int[n*m];
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
A[n*i + j] = rand() % 19 - 9;
cout << A[n*i + j] << "\t";
}
cout << "\n";
}
cout << "Size of submatrix: ";
cin >> r;
int liczba_kwadratow = (m + 1 -r) * (n+1 -r);
int max = -10000;
int max_i = 0;
int max_j = 0;
int row_iter = 0;
int col_iter = 0;
for (k = 0; k <liczba_kwadratow; k++)
{
int sum = 0;
for ( i = row_iter; i < row_iter + r; i++)
for ( j = col_iter; j < col_iter + r; j++)
sum += A[i * n + j];
if ( sum > max )
{
max = sum;
max_i = row_iter;
max_j = col_iter;
}
col_iter++;
if ( row_iter + r > m )
{
row_iter++;
col_iter = 0;
}
}
cout << "Field of the largest submatrix " << r << " of " << r << " equals " << max << "\n";
for (i = max_i; i < max_i + r; i++)
{
for (j = max_j; j < max_j + r; j++)
cout << A[i * n + j] << "\t";
cout << "\n";
}
...works great without delete[] A or delete A
}
The problem can at least be identified via the method(s) I've told you in the comments (or by using a debugger). Easiest way is changing the dynamical array to a std::vector then use member function at. You will then realize you get an out of bound exception thrown here:
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
A.at(n*i + j) = rand() % 19 - 9; // throws here!!!!, replace n by m
cout << A.at(n*i + j) << "\t";
}
cout << "\n";
}
When input is 6 5 3, then you get an exception when you first try to access A[30], which gives you a headache when delete[] - ing. Now you can figure out what's wrong I guess ...
You inverted i and j in your matrix access code.
basically the formula could be
current row + current column * number of rows
or
current row * number of columns + current column
Two remarks on your code and debugging:
using one-letter variables minimizes the wear and tear on your keyboard and fingers and reduces disk and memory usage. It tends to increase debugging time dramatically, though.
The assumption that the code is OK just because it does not crash immediately is absolutely wrong. C/C++ is the realm of undefined behaviours (in your case, probably the most common one: writing outside allocated memory). An UB is a nasty piece of work precisely because it can produce any outcome, including (frequently) an apparent absence of consequences, only to cause a perfectly OK bit of code to crash 10.000 lines later.