C++ assigning values to index 10 of an array affects index 0 - c++

I have a 2 dimensional array that is filled with info and has 10 indexes. When I run the code below :
for(int studentIndex = 0; studentIndex < numOfStudents; studentIndex++)
{
if(grade[studentIndex][9] > 59){
grade[studentIndex][10] = 1; // 1 stands for pass
}else{
grade[studentIndex][10] = 0; // 0 stands for fail
}
}
grade[studentIndex][10] changes and so does the grade[studentIndex][0] for the next index. the problem is somewhere there because when I cout index 0 before this portion, the value is fine but after this it changes to 1 or 0.

In an array of size 10, the highest index is 9 since indexing begins at 0. I'm guessing that grade[index][10] is basically pushing the pointer forward into grade[index+1][0] and that's why you're seeing this behaviour. You'll need to either enlarge your student info array to 11 or figure out whether you're getting your indexing wrong.

and so does the grade[studentIndex][0] for the next index
This makes it sound like grade is defined as int grade[numOfStudents][10] (or something in that direction). The valid indices for the subarray are only 0 to 9.

Related

I wrote this simple code that should calculate the highest number of a series of array elements but the results are strange

I wrote this simple code that should calculate the highest number of a series of array elements but the results are strange, i'm pretty sure it has something to do with the way I wrote but I can't figure out what I did wrong
I tried the same code on c++ shell and it gave me different results
#include <iostream>
using namespace std;
int main()
{
int size,c,max;
cout<< "enter the size of the array" << endl;
cin>> size;
int a[size];
max=a[0];
cout <<"fill the array" << endl;
for(c=0; c<size; c++){
cin>>a[size];
if(max<a[size]){
max=a[size];
}
}
cout<<"the highest number is:"<<max;
}
enter the size of the array
5
fill the array
1
2
3
4
5
the highest number is:27
Process returned 0 (0x0) execution time : 14.653 s
Press any key to continue.
enter the size of the array
7
fill the array
1
2
3
4
5
6
7
the highest number is:27
Process returned 0 (0x0) execution time : 14.653 s
Press any key to continue.
enter the size of the array
8
fill the array
1
2
3
4
5
6
7
8
the highest number is:8
Process returned 0 (0x0) execution time : 5.915 s
Press any key to continue. (if the size of the array is over 8 it works)
You loop is wrong because you use the size of the array instead of the loop index c. This is how your code should look.
for(c=0; c<size; c++){
cin>>a[c];
if(max<a[c]){
max=a[c];
}
}
The other error you have is that you use the value of the first element in the array before you have given it a value.
int a[size];
max=a[0]; // at this point a[0] does not have a value
You should recode like this
cout <<"fill the array" << endl;
cin>>a[0];
max=a[0];
for(c=1; c<size; c++){
cin>>a[c];
if(max<a[c]){
max=a[c];
}
}
Now a[0] is only being used after you've given it a value, and the loop has been changed to start at c=1.
I'm not familiar with C++, but i'll point the issue you have :
for(c=0; c<size; c++){
cin>>a[size];
if(max<a[size]){
max=a[size];
}
}
cout<<"the highest number is:"<<max;
this is always putting the input into the last item of your array, thus you don't keep track of the input anymore (if you need it), you should put your loop variable into the index for the max comparison and array storing operation.
Another issue is that you use max=a[0]; but it's has not been already filled. This is can be a deal when you are using negative value or depending of the implentation of the language.
Another issue I saw (i'm unsure but happend to me in C), is that you are creating an array like this :
int size,c,max;
cout<< "enter the size of the array" << endl;
cin>> size;
int a[size];
If i'm correct (from my C experience), this shouldn't be done this way, because your array is created at compile time, but the value of size is not already initialized, writing somewhere in memory where you shouldn't write. This might cause the "27" issue by the way.
Would firstly recommend you create your array like this, it will initialise the array with 0 at each index, as accessing an empty index could produce undefined behaviour:
int a[size] = {0};
Secondly, you are using size as the index to your array in the loop, you should be using the value you are incrementing (c) to access each index. Maybe you could use the later standard of c++ and write it like this (using for each):
for (auto &singleInput : a) // access by reference to avoid copying
{
cin >> singleInput;
if(max < singleInput)
{
max = singleInput;
}
}

Incorrect output using array as counter

I'm trying to teach myself programming by attempting problems from codeabbey.com.
I'm not getting the correct output on this question.
Question:
Here is an array of length M with numbers in the range 1 ... N, where N is less than or equal to 20. You are to go through it and count how many times each number is encountered.
Input data contain M and N in the first line.
The second (rather long) line will contain M numbers separated by spaces.
Answer should contain exactly N values, separated by spaces. First should give amount of 1-s, second - amount of 2-s and so on.
Data input:
10 3
1 2 3 2 3 1 1 1 1 3
Correct Output:
5 2 3
My Output:
7 3 4
You can check here
My Code:
#include <iostream>
using namespace std;
int main()
{
int arrayLength,range,a;
cin>>arrayLength>>range;
int array[20];
array[20]={0};
for(int i=0; i<arrayLength; i++)
{
cin>>a;
++array[a-1];
}
for(a=0; a<range; a++)
{
cout<<array[a]<<" ";
}
return 0;
}
There aren't any error messages or warnings. Also, if you have any suggestions for improving the code, that'd be nice.
int array[20];
array[20]={0};
is wrong, since it leave the array un-initialized and tries to initialize the 21st element (which is undefined behaviour btw, since your array has only 20 elements, remember that indexing starts from 0). Use
int array[20] = {0}; // this will initialize all elements to 0
and your code will work as expected. See here for more details regarding aggregate initialization in C++.
array[20]={0}; initializes the 21st element(non-existing) to 0.
So you have to use int array[20] = {0}; which will initialize all 20 elements to zero.
Also from your code, you are not storing the elements to an array. You are just incrementing the corresponding count when an input is read. If so, what is the need of initializing an array to max limit. Just declare the array as you need it. In your case,
int array[range] = {0};
It will initialize an array of three (range =3 here) elements.

removing lagging zeros from dynamic array

Trying to continue this function with another for-loop that will remove lagging zeros. I.e if poly a
is 1 1 1 and poly b is 0 -1 -1, answer is 100, but should be 1, how can I remove the zeros?
If you MUST use a dynamic array, and not a stl vector or array:
//first get the index of the last trailing 0
int j;
for (j=max-1; j>0 && sum[j] == 0; --j);
//next allocate memory for new array that will not have any trailing 0s
int* tmp = sum;
sum = new int[j+1];
//now copy old values into new array
for(size_t k=0;k<=j;++k){
sum[k] = tmp[k];
}
delete[] tmp;
Feel free to replace the loop for copying values with the shorter memcpy command:
memcpy(sum,tmp,sizeof(int)*(j+1));
The above code will result in an array of at least 1 value, so if you have all 0s, then it will just be 0. Otherwise it will shrink your array to the appropriate size. I did make the assumption that you stored larger values at the front of your array, and the least significant digits at the end.
You should iterate through your list backwards.
for( int i=max-1; i>=0; i--) {
//calculate sum
if (sum[i] == 0 && i == max-1 && max > 0) { max--;}
}
p->deg=max;
p->coeffs=sum;

What does this statement do "while(a[i]--!=0)"?

Below is the code used for sorting numbers in non-decreasing order:
#include<stdio.h>
#include<stdlib.h>
# define size 1000001
static int a[size];
int main()
{
int t, k, i;
scanf("%d", &t);
for(i = 0; i < t; i++)
{
scanf("%d", &k);
a[k] += 1;
}
for(i = 0; i < 1000001; i++)
{
while(a[i]-- != 0)
printf("%d\n", i);
}
return 0;
}
It would be really of great help if someone could explain the code to me. I have gone through the code and I have no idea as to how it can sort numbers. There is no swapping done at any place but still it works in c++ editor.
This program doesn't sort numbers in a mathematical sense, but that isn't important since it gives you the illusion of doing it.
The program asks for t, which would be better named numberOfValues... the number of values you will input.
The array a[size] can be thought of as size buckets of values. In your program, these buckets are simply counters. Each bucket has a number, 0 through size. When value 5 is input, bucket a[5] has its count increased. This continues until all buckets are set.
The program then works through the buckets. Most of your buckets will be empty, but when a bucket is non-zero (while a[i] != 0 -- ignore the missing -- for now), the bucket needs to be "emptied" while at the same time, its contents need to be accounted for. The bucket a[i] holds the count of i elements, so the loop prints that a value of i is next in the sort, while also decrementing the count (a[i]--). This continues until the bucket is empty (== 0) and the program moves to the next bucket.
Eventually all of your buckets have been emptied and the sort is completed.
Decrements variable a[i] until it's 0 while printing it out every time
There is no swapping because is not needed: numbers are not stored as usual, it uses a huge array to mark which number has been entered:
If you add the number 200, it stores array[200]=1. If you add again 200, then array[200]=2.
Then, it prints the array in the following way: imagine you have [0,1,2,1,0,0...], so there is one 1, two 2, one 3...
So it just shows 1,2,2,3
The code iterates for each value in the array a. Each value a[i] in the array is iterated in the while loop. while(a[i]--!=0) checks if the value of a[i] is zero. If not, the loop body is executed. When the control enters the loop body, decrementing the a[i] value. Eg) If a[i]=6, the output will be:
5
4
3
2
1
0
Consider for i=0;
Then a[i]--!=0 will get executed till value at a[i] does not become zero.When value at a[i] becomes zero while loop will get terminated and next iteration of for loop will start.
its a nice code but its space complexity is high.
This part of the code
for(i = 0; i < t; i++)
{
scanf("%d", &k);
a[k] += 1;
}
stores frequency of number entered (its somewhat like hashing)
say if I entered 5 4 2 4 2
then
a[5] =1
a[4] =2
a[2] =2
all others will be zero
so if you want to say find frequency of "n" in the array then just print a[n]
lets come to your questions now
how this code sorts the number ?
what's use of while(a[i]--!=0)?
Answer to first question :
we go from 0 to 1000001 in oder so if 4 2 5 6 is entered
As the loop goes from 0 to 100001 first it checks a[2] !=0 then a[4] later a[5] then a[6] all non zero frequency terms are printed .
so as per checking oder first 2 4 5 6 is printed
Answer to the second question :
why isn't is while(a[i]!=0) because iam checking only if its non zero if its non zero lets print the number
but say i entered 4 3 2 4 2
then the output should print 2 2 3 4 4
so while(a[i] --!=0) is used it prints the number a[i] times say if
a[4]=2 which means 4 is present 2 times hence its should print 4 4 so while loop runs twice as a[4] =2

My quick sort implementation fails in some cases

I have implemented a quick sort algorithm but when I tested it I noticed that it fails when the input array has the largest element in the first element (this is the element I got the pivot from). Here's my code:
void partition(int *a,int size){
if(size<=1){return;}
int pivot=a[0];
int left=0,right=0;
for(left=1,right=size-1;left<=right;){ //was size-1
if(a[left]>=pivot&&a[right]<=pivot) {
swap(left,right,a);
}
if(a[left]<pivot){left++;}
if(a[right]>pivot){right--;}
}
swap(0,right,a);
partition(a,right-1);
partition(&(a[right+1]),size-right-1);
}
Some samples that it fails on:
I/P 245 111 32 4
O/P 4 111 32 245 `
I/P 154 11 43 3 7
O/P 7 11 43 3 154
What are the possible mistakes I have made?
Well, the problem lies here :
partition(a,right-1); // <- It's partition(array,size)!
Change it to
partition(a,right);
And it will work. I think you know the reason.
For the partition function to work correctly, you must supply 2 things :
1) The array to work on.
2) The number of elements it has, the size.
The problem lies in the first recursive call to partition the left subarray: partition(a,right-1)
The argument 2, the size, is incorrectly specified to be right-1, when it is actually right.
This can be worked out by using the fact that the number of elements in an array from an index a to b ( both included,b>=a) are N= b-a+1.
Here, we have a=0, b=right-1, thus the number of elements in the left sub array, the size, N=(right-1)-(0)+1=right.
Thus the to work correctly, you must call it like partition(a,right);.
The left sub array ends at right-1, but it has right-1+1=right elements.
Happens all the time :)
You are missing a case where there is an element in the array which is the pivot, in the partition function.
Assume arr = { 5, 5, 1 , 1, 5, }
pivot = 5
iter1:
left=1, arr[left]=5 ; right=4,arr[right]=5
(swapping)
not increasing left nor decreasing right - since 5 < 5 == false ; 5 > 5 == false
Next iteration, the same scenario will repeat itself, and you will actually get an infinite loop.
One way to deal with it is to determine that the "big" part will also increase all elements that are exactly the pivot, and swap elements if arr[right] < pivot (not <=), and decrease right if arr[right] >= pivot (not >), something like:
...
for(left=1,right=size-1;left<=right;){ //was size-1
if(a[left]>=pivot&&a[right]<pivot) {
// ^ note < not <=
swap(left,right,a);
}
if(a[left]<pivot){left++;}
if(a[right]>=pivot){right--;}
// ^ note >=
}
...