int variable not resetting on c++? - c++

So, my program is supposed to receive test inputs like:
3
1 0 1
0 1 1
1 0 1
5
1 1 1 0 0
1 1 0 1 1
1 0 1 0 1
0 1 0 1 0
0 1 1 1 1
3
1 0 0
0 1 0
0 0 1
2
1 1
1 1
0
where the single-valued lines (n) are the size of a NxN matrix located in the following n entries like shown above. If n = 0, the program stops. The output must be the biggest sum amongst the columns of the matrix. So I expect outputs like this:
3
4
1
2
After a lot of effort and wasted time, I managed to get the first output correctly, but I noticed the following ones sometimes summed up and suggested some variable was not being reset. Here's my code:
#include <iostream>
using namespace std;
int pop = 0;
int main() {
int n, i, j, k;
cin >> n;
while (n!=0) {
int alunos[n]={0};
pop = 0;
for (i=0;i<n;i++) {
int array[n]={0};
for (j=0;j<n;j++) {
cin >> array[j];
if (array[j]==1) alunos[j]++;
}
}
for (k=0;k<n;k++) {
if(alunos[k]>pop) pop = alunos[k];
}
cout << pop << endl;
cin >> n;
}
return 0;
}
Noticed that I'm outputting pop(the biggest sum) and resetting it to 0 everytime a new n is given. alunos[n] is an array with the sums of each column (also resetted on every while loop) and array[n] is just an auxiliary array for reading each line of input. My outputs with this are:
3
5
6
8
Thanks in advance!

You cannot use initializers with variable length arrays. Either switch to some sort of container:
std::vector<int> alunos(n);
or fill the array with zeros manually:
int alunos[n];
std::fill(alunos, alunos+n, 0);
Also, ignoring errors is unhealthy. Don't do it.

Related

How to fix a bug in my homework solution in C++?

I need to write a program which reads the statistics of n League A football teams and prints the teams name which fall in League B.
A team falls in League B, if it has less than k points after having played m weeks where m is between 1 and 150. Each team gets three points for a win, one point for draw and zero points when lost.
Input Specification: In the first line, you will be given the number of teams 0 < n ≤ 500 and the points 0 < k ≤ 300 needed to stay in league A. Then in the following n lines, there will be the team name and its results. Semicolon indicates the end of input series.
Number 2 represents win, number one represents draw and number zero represents loss.
Output specification:
Sample Input I
4 19
Team_A 1 1 1 1 1 1 1 1 1 0 1 1 1 0 2 1 0 ;
Team_B 0 1 0 2 2 1 1 0 1 1 0 2 0 1 0 0 2 ;
Team_C 0 0 1 0 2 2 2 1 1 1 1 1 0 0 2 1 2 ;
Team_D 0 1 0 1 2 1 2 1 0 0 0 2 2 2 0 0 0 ;
Sample Output I
Team_A 16
Team_B 18
This is the code I came up with, but the output is wrong and I don't know why,
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int n,points,sum=0,i,value;
char name[15];
char p;
scanf("%d %d",&n,&points);
for(i=1;i<=n;i++)
{
scanf("%s",&name);
do
{
scanf("%c ",&p);
if(p!=';')
{
value=p-48;
sum=sum+value;
}
}while(p!=';');
if(sum<=points)
printf("%s %d",name,sum);
}
return 0;
}
You might look for problems by stuffing the program with output statements.
If you add after scanf("%c ",&p); an output statement to show the value of p, you will find that the first value for p is a space character, which spoils your calculation.
In the same way, if you trace the value of value, you will find that you forgot to initialize this variable to zero for each team.

Ordering an array based on 2D array of relations (higher, lower, doesn't matter)

I have been stuck with this problem for two days and I still can't get it right.
Basically, I have a 2D array with relations between certain numbers (in given range):
0 = the order doesn't matter
1 = the first number (number in left column) should be first
2 = the second number (number in upper row) should be first
So, I have some 2D array, for example this:
0 1 2 3 4 5 6
0 0 0 1 0 0 0 2
1 0 0 2 0 0 0 0
2 2 1 0 0 1 0 0
3 0 0 0 0 0 0 0
4 0 0 2 0 0 0 0
5 0 0 0 0 0 0 0
6 1 0 0 0 0 0 0
And my goal is to create a new array of given numbers (0 - 6) in such a way that it is following the rules from the 2D array (e.g. 0 is before 2 but it is after 6). I probably also have to check if such array exists and then create the array. And get something like this:
6 0 2 1 4 5
My Code
(It doesn't really matter, but I prefer c++)
So far I tried to start with ordered array 0123456 and then swap elements according to the table (but that obviously can't work). I also tried inserting the number in front of the other number according to the table, but it doesn't seem to work either.
// My code example
// I have:
// relArr[n][n] - array of relations
// resArr = {1, 2, ... , n} - result array
for (int i = 0; i < n; i++) {
for (int x = 0; x < n; x++) {
if (relArr[i][x] == 1) {
// Finding indexes of first (i) and second (x) number
int iI = 0;
int iX = 0;
while (resArr[iX] != x)
iX++;
while (resArr[iI] != i)
iI++;
// Placing the (i) before (x) and shifting array
int tmp, insert = iX+1;
if (iX < iI) {
tmp = resArr[iX];
resArr[iX] = resArr[iI];
while (insert < iI+1) {
int tt = resArr[insert];
resArr[insert] = tmp;
tmp = tt;
insert++;
}
}
} else if (relArr[i][x] == 2) {
int iI = 0;
int iX = 0;
while (resArr[iX] != x)
iX++;
while (resArr[iI] != i)
iI++;
int tmp, insert = iX-1;
if (iX > iI) {
tmp = resArr[iX];
resArr[iX] = resArr[iI];
while (insert > iI-1) {
int tt = resArr[insert];
resArr[insert] = tmp;
tmp = tt;
insert--;
}
}
}
}
}
I probably miss correct way how to check whether or not it is possible to create the array. Feel free to use vectors if you prefer them.
Thanks in advance for your help.
You seem to be re-ordering the output at the same time as you're reading the input. I think you should parse the input into a set of rules, process the rules a bit, then re-order the output at the end.
What are the constraints of the problem? If the input says that 0 goes before 1:
| 0 1
--+----
0 | 1
1 |
does it also guarantee that it will say that 1 comes after 0?
| 0 1
--+----
0 |
1 | 2
If so you can forget about the 2s and look only at the 1s:
| 0 1 2 3 4 5 6
--+--------------
0 | 1
1 |
2 | 1 1
3 |
4 |
5 |
6 | 1
From reading the input I would store a list of rules. I'd use std::vector<std::pair<int,int>> for this. It has the nice feature that yourPair.first comes before yourPair.second :)
0 before 2
2 before 1
2 before 4
6 before 0
You can discard any rules where the second value is never the first value of a different rule.
0 before 2
6 before 0
This list would then need to be sorted so that "... before x" and "x before ..." are guaranteed to be in that order.
6 before 0
0 before 2
Then move 6, 0, and 2 to the front of the list 0123456, giving you 6021345.
Does that help?
Thanks for the suggestion.
As suggested, only ones 1 are important in 2D array. I used them to create vector of directed edges and then I implemented Topological Sort. I decide to use this Topological Sorting Algorithm. It is basically Topological Sort, but it also checks for the cycle.
This successfully solved my problem.

Optimize triplet summation in C++

Problem
I need to compute a function of an array of integers. For every three-element subset (or triplet) of the array, I need to compute the term floor((sum of triplet)/(product of triplet)). Then I need to return the sum of all such terms.
Example
Input (length; array):
5
1 2 1 7 3
Output:
6
Explanation
The following triplets exist in the given array:
1 2 1
1 2 7
1 2 3
1 1 7
1 1 3
1 7 3
2 1 7
2 1 3
2 7 3
1 7 3
Considering these triplets from the sample input:
1 2 1 contributes 2, because floor((1+2+1)/(1*2*1)) = floor(4/2) = 2
1 2 3 contributes 1
1 1 7 contributes 1
1 1 3 contributes 1
2 1 3 contributes 1
All other triplets contribute 0 to the sum.
Hence the answer is (2+1+1+1+1)=6.
My Solution
What I tried is complexity O(n^3). Code is given below:
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
long t,n[300005],sum=0,mul=1,i,j,k,res=0;
cin >> t;
for(i=0;i<t;i++)
cin >>n[i];
for(i=0;i<t-2;i++)
for(j=i+1;j<t-1;j++)
for(k=j+1;k<t;k++)
{
sum = n[i]+n[j]+n[k];
mul = n[i]*n[j]*n[k];
res += floor(sum/mul);
}
cout << res << endl;
return 0;
}
Is there any hint of better optimization?
While still O(n^3), you could save some operations by caching the redundant calculations between n[i] and n[j] as you iterate over n[k].
For example:
long sum_ij,mul_ij;
for(i=0;i<t-2;i++) {
for(j=i+1;j<t-1;j++) {
sum_ij = n[i]+n[j];
mul_ij = n[i]*n[j];
for(k=j+1;k<t;k++)
{
sum = sum_ij+n[k];
mul = mul_ij*n[k];
res += floor(sum/mul);
}
}
}

Copying data file into an array

I have a project for school. They gave me a data file that needs to be in an array of 10*10. This array needs to be an upper triangle, which means that all values of and below the diagonal have to be zero. This data file is the time that a project takes by every stage. It means that every [i][j] represents the time for stage from i to j.
Just to make it more complicated the problem ask you to find the longest time per column and add it to the longest time in the next column.
here is my code so far:
#include <iostream>
#include<iomanip>
#include <fstream>
#include <cmath>
using namespace std;
//Function prototype
int minCompletionTime (int Data[], int numTasks);
int main()
{
//Declaring and initializing variables
int num_Events(0), completion_Time(0);
int startSearch(0), endSearch(0);
const int SIZE(10);
char datch;
//Declaring an array to hold the duration of each composite activity
int rows(0),duration_Data [10];
//Declaring an input filestream and attaching it to the data file
ifstream dataFile;
dataFile.open("duration.dat");
//Reading the data file and inputting it to the array. Reads until eof
//marker is read
while (!dataFile.eof())
{
//Declaring an index variable for the array
//Reading data into elements of the array
dataFile >> duration_Data[rows];
//Incrementing the index variable
rows++;
}
//Taking input for the number of events in the project
cout << "Enter the number of events in the project >>> ";
cin >> num_Events;
//Calling the function to calculate the minimum completion time
completion_Time = minCompletionTime(duration_Data, num_Events);
//Outputting the minimum completion time
cout << "The minimum time to complete this project is " << completion_Time
<< "." << endl;
}
int minCompletionTime (int Data[], int numTasks)
{
int sum=0;
//As long as the index variable is less than the number of tasks to be
//completed, the time to complete the task stored in each cell will be
//added to a sum variable
for (int Idx=0; Idx < numTasks ; Idx++)
{
sum += Data[Idx];
}
return sum;
}
Any help will be appreciated
My data file only has 6 elements that holds this elements: 9 8 0 0 7 5
my data should look like this in order to start doing operations.
0 0 0 0 0 0 0 0 0 0
0 0 9 8 0 0 0 0 0 0
0 0 0 0 7 0 0 0 0 0
0 0 0 0 5 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
It is a little confusing. I am sorry. The first and second column should have values of zero and first row the same way. after fifth row should be all zeros as well since it will be filled with more information from other data file.
There are a few ways of solving this problem. Here are 2 very naive ways:
1. Use a 10x10 array:
Read everything in from the data file (dataFile >> data[row][col]).
Have 2 nested loops:
The outer loop iterates over columns.
The inner loop iterates over the rows of that specific column.
Since you have to find the max and the values under the diagonal is zero, you can just be lazy and find the max of each column (you might have trouble if it's a lot larger than 10x10). However, if you want to only go through the rows that are necessary, I'll let you figure it out (it's very simple, don't over think).
2. Only use a 1x10 array:
Initialize the array with the minimal value (0 or -1 should work for you), let's call it the max_row.
Read item by item on each row, and compare it to the value that's stored in the max_row and replace appropriately.
When you're done, just sum up the elements in max_row.

Why does it cout in something that we doesn't cin in arrays?

When the following program is fead the following input (reading from cin):
1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1
The output is surprising:
1 1 1 2 2 1 1 1 1 1 1 1 1 1 1 1
#include<iostream>
using namespace std;
int main()
{
int arey[3][3];
int i,j;
for(j=0;j<=3;j++)
{
for(i=0;i<=3;i++)
{
cin>>arey[j][i];
}
}
arey[0][0]=1;
arey[3][3]=1;
i=0,j=0;
for(j=0;j<=3;j++)
{
for(i=0;i<=3;i++)
{
cout<<arey[j][i];
}
}
return 0;
}
Can someone explain what I should change to get the same output as the input?
Is the matrix 3x3 or 4x4?
you created 3x3 but the loops run for 4 elements and you also update [3][3]
Basically your indexes overflow and you overwrite a different cell in the matrix.
Update: cheecked your input, use: int arey[4][4];
Arrays use 0 based indices, so the valid range of indices for your
int arey[3][3];
are 0 <= i < 3 and 0 <= j < 3
So you need to change the condition in your for loops to be strictly < instead of <=
I really don't think I understand your question, but this is wrong:
int arey[3][3];
...
for(j=0;j<=3;j++) // <= invalid
...
array[3][3]=1; // out of bounds
arey is a 3*3 array. You can't access arey[3][?], that's out of bounds. The only valid indices are 0..2.
Once you've written past the bounds of your array, your program behavior becomes undefined.