Min and max of n sets of numbers - c++

I am supposed to write a program in C++ which will find maximum and minimum of n sets of numbers in the following way:
The first input is a positive integer n = the number of 5-element sets of numbers. That is, we want to have n lines of numbers, 5 (real) numbers in each line.
Each set of numbers consists of 5 numbers separated by a space bar.
As a result we want to find for each of the n sets its maximum, minimum and arithmetic mean.
Here is my attempt:
#include<iostream>
using namespace std;
int n;
float maxx, minn, a;
int main()
{
cin >> n;
for (int j = 0; j < n; j++)
{
float T[5];
for (int i = 0; i < 5; i++)
{
cin >> T[i];
}
if (T[0] > T[1]) {
maxx = T[0];
minn = T[1];
}
else {
maxx = T[1];
minn = T[0];
}
for (int i = 0; i < 5; i += 2) {
if (T[i + 2] > T[i + 3]) {
if (T[i + 2] > maxx) {
maxx = T[i + 2];
if (T[i + 3] < minn) {
minn = T[i + 3];
}
}
}
else {
if (T[i + 3] > maxx) {
maxx = T[i + 3];
if (T[i + 2] < minn) minn = T[i + 2];
}
}
}
a = (T[0] + T[1] + T[2] + T[3] + T[4]) / 5.0;
cout << maxx << endl;
cout << minn << endl;
cout << a << endl;
}
return 0;
}
Here is what happens after correcting i, j=1, i, j ++ into i, j=0 and changing the algorithm for min and max:
As you can see, the calculations are done correctly this time, but there is still a problem with the loop.
Could you tell me what is wrong with my solution? How can I fix it?
OK! IT WORKS JUST FINE NOW! THANK YOU A LOT FOR ALL YOUR HELP AND PATIENCE!

As written, your code results in undefined behavior, because it is going to corrupt the stack memory.
float T[5];
for(i = 1; i <= 5; i++)
{
cin >> T[i];
}
This obviously results in undefined behavior. This may or may not be your actual bug, but until this bug is fixed (and this bug is repeated several times, in the following code), you cannot expect any defined behavior from your program.

If you enter 2 for n, then the outer loop (for(int j=0; j<n; j++)) will run two times, letting you enter the five numbers for calculations twice. That's how you coded it. If it's not supposed to be like that then you need to rethink the solution about the problem you try to solve.

float T[5];
for(i = 1; i <= 5; i++)
{
cin >> T[i];
}
Each and every array starts with an index 0.
For example if you declare an integer array say int a[10];
It's starting address is say 1000.
Then the memory location goes like this:
For first element a[0] 1000+0*size of int
For second element a[1] 1000+1*size of int
For third element a[2] 1000+2*size of int....... and so on.
In this example you have started with T[1], which is starting address+1*size of float, which is logically the second element

According to your code you have to enter the other set of numbers after you get max, min and average.

You currently have out of bound accesses (T[i + 2] > T[i + 3] where i == 3).
split in sub-function may help:
void max_min_mean_5()
{
float values[5];
for (auto& value : values) {
std::cin >> value;
}
const auto p = std::minmax_element(std::begin(values), std::end(values));
const auto mean = std::accumulate(std::begin(values), std::end(values), 0.f) / 5.f;
std::cout << *p.second << std::endl;
std::cout << *p.first << std::endl;
std::cout << mean << std::endl;
}
int main()
{
int n;
std::cin >> n;
for (int i = 0; i != n; ++i) {
max_min_mean_5();
}
}
Live demo.

change
for(j=1; j<=n; j++)
to
for(j=1; j<=n; ++j)
Because j++ evaluates to prior j value, ++j evaluates to the just incremented value.

Related

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.

SIGSEGV(signal 11) 'segmentation fault' in FCTRL2 codechef

I am facing SIGSEGV error on submitting solution for codechef small factorial problem code FCTRL2 though the code works fine on ideone
coding language C++ 4.3.2
Example
Sample input:
4
1
2
5
3
Sample output:
1
2
120
6
#include <iostream>
using namespace std;
void fact(int n) {
int m = 1, a[200];
for (int j = 0; j < 200; j++) {
a[j] = 0;
}
a[0] = 1;
for (int i = 1; i <= n; i++) {
int temp = 0;
for (int j = 0; j < m; j++) {
a[j] = (a[j] * i) + temp;
temp = a[j] / 10;
a[j] %= 10;
if (temp > 0) {
m++;
}
}
}
if (a[m - 1] == 0) {
m -= 1;
}
for (int l = m - 1; l >= 0; l--) {
cout << a[l];
}
}
int main() {
int i;
cin >> i;
while (i--) {
int n;
cin >> n;
fact(n);
cout << endl;
}
return 0;
}
Caveat I'm not going to just fix up your code for you straight up, but I will highlight where it's going wrong and why you get the seg fault.
Your problem is with your implementation of how you're trying to handle the digit by digit multiplication - specifically with what happens to your m value. Test it out by outputting m each time it's incremented - you'll find it's incrementing more often than you intend. You're right to realise you need to use an approach to get to 158 digits and your basic concept could be made to work.
The first clue is by testing with n = 6 when you get a leading 0 that you shouldn't even though you try to get rid of that problem with the if block that contains m-=1
Try with n = 25 and you will see a lot of leading zeros.
Any value greater than this will fail with a Segmentation error. The Seg fault is because, with this error, you try to set values of the array a beyond the max index (as m gets greater than 200)
N.B. Your assertion that the code works on Ideone.com is only true up to a point - it will fail with n > 25.
(Erased code computing a factorial using int)
The problem in your code is that you increment m each time temp is not 0 for each digit multiplication. You may then get a SIGSEGV when computing big factorials because m becomes too big. You probably saw it because 0 shows up in front of your result. I guess this is why you added the
if (a[m - 1] == 0) {
m -= 1;
}
You should only increment m when the inside loop is finished and term is not null. Once fixed you can get rid of the above code.
void fact(int n) {
int m = 1, a[200];
for (int j = 0; j < 200; j++) {
a[j] = 0;
}
a[0] = 1;
for (int i = 1; i <= n; i++) {
int temp = 0;
for (int j = 0; j < m; j++) {
a[j] = (a[j] * i) + temp;
temp = a[j] / 10;
a[j] %= 10;
}
// if (temp > 0) {
// a[m++] = temp;
// }
while (temp > 0)
{
a[m++] = temp%10;
temp /= 10;
}
}
for (int l = m - 1; l >= 0; l--) {
cout << a[l];
}
}

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.

Sudoku solving matrix, while statement gives an infinite loop

This code should produce a solved sudoku matrix, however the while statement puts it in an infinite loop. Removing the while statement gives me a matrix with some values still 99 or 0. And i can't generate 9 random numbers uniquely one by one.
IF YOU WANT TO RUN AND CHECK THE CODE, REMOVE THE WHILE STATEMENT.
int a[9][9];
int b[9][9];
int inputvalue(int x, int y, int value) //checks horizontally, vertically and 3*3matrix for conflicts
{
int i, j;
for (i = 0; i < 9; i++)
{
if (value == a[x][i] || value == a[i][y])
return 0;
}
for (i = (x / 3) * 3; i <= ((x / 3) * 3) + 2; i++)
{
for (j = (y / 3) * 3; j <= ((y / 3) * 3) + 2; j++)
if (b[i][j] == value)
return 0;
}
return value;
}
int main()
{
int i, j, k;
unsigned int s;
cout << "sudoku\n";
time_t t;
s = (unsigned) time(&t);
srand(s);
for (i = 0; i < 9; i++)
{
for (j = 0; j < 9; j++)
a[i][j] = 99;
}
for (i = 0; i < 9; i++)
{
for (j = 1; j <= 9; j++)//j is basically the value being given to cells in the matrix while k assigns the column no.
while(a[i][k]==99||a[i][k]==0)
{
k = rand() % 9;
a[i][k] = inputvalue(i, k, j);
}
}
for (i = 0; i < 9; i++)
{
for (j = 0; j < 9; j++)
{
cout << a[i][j] << " ";
}
cout << endl;
}
return 0;
getch();
}
You are using assignment =, instead of equality == here:
while(a[i][k]=99||a[i][k]=0)
^ ^
this should be:
while(a[i][k]==99||a[i][k]==0)
a[i][k]=99 will always evaluate to true since 99 is non-zero, although your original code does not compile for me under gcc as it is, so I suspect the code you are running either has some parenthesizes or is slightly different.
Also using k in the while loop before it is initialized is undefined behavior and it is unclear that your termination logic makes sense for a k that is constantly changing for each loop iteration.
Another source of the infinite loop is inputvalue which seems to get stuck returning 0 in some instances, so you need to tweak that a bit to prevent infinite loops.
Also, srand(time(NULL)); is a more common way to initialize the pseudo-random number generator