Why is My Program Only Sometimes Correctly Identifying the Highest and Lowest Values in an Array? [closed] - c++

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
I am writing a homework program which, among other things, must be able to output the highest and lowest values in an array. The ten numerical values in this array, referred to as scores int he context of the program are inputted by the user early on. I have two functions which calculate the highest and lowest value int he array respectively. For reasons I cannot figure out, the getHighScore function only sometimes correctly determines the largest value depending on what values have been stored int he array and the value returned by the getLowScore function always determines that the lowest number is the same one that is returned by getHighScore.
I have already tried comparing my code to other code both from my own past programs and online that is meant to serve the same purpose, and although it was nearly identical to one such example, my getLowScore function still never works as intended. I believe it also worth including the function in my program which calculates the average of the array's contents below, as although it uses different commands, it always works as intended and I am not sure what sets it apart from the other two functions.
//Stores the highest score in the array in the "highest" variable
int getHighScore (/*in*/const int somearray[], /*in*/int size)
//PRE: The contents of the array have been defined, as well as the
//variable "size"
//POST: The largest value in the array is stored in the "highest" variable
{
int highest = 0;
highest = somearray [0]; //Set highest to the first element in the array
for (int index = 1; index < size; index++)
{
if (somearray [index] > highest);
highest = somearray [index];
}
return highest;
}
//Stores the lowest score in the array in the "lowest" variable
int getLowScore (/*in*/const int somearray[], /*in*/int size)
//PRE: The contents of the array have been defined, as well as the
//variable "size"
//POST: The lowest value in the array is stored in the "lowest" variable
{
int lowest = 0;
lowest = somearray [0]; //Set lowest to the first element in the array
for (int index = 1; index < size; index++)
{
if (somearray [index] < lowest);
lowest = somearray [index];//
}
return lowest;
}
//Stores the mean of all the values in the array in the "average" variable
int getAvgScore (/*in*/const int somearray[], /*in*/int size)
//PRE: The contents of the array have been defined, as well as the
//variable "size"
//POST: The average value in the array is stored in the "average" variable
{
int totalScore = 0;
double average = 0;
//average = somearray [0]; //Set highest to the first element in the
array
for (int index = 0; index < size; index++)
{
totalScore += somearray [index];
}
average = totalScore / 10;
return average;
}
This code compiles, but logic errors prevent me from achieving the desired outcome.

It's these lines right here:
if (somearray [index] > highest);
highest = somearray [index];
Should be something like this instead:
if (somearray [index] > highest) {
highest = somearray [index];
}
Note: You may or may not be making the same mistake more than once, so I'd double check if I were you.

I think #Chipster's answer is correctly, another suggestion to avoid that kinds of error is treat your compile warning as error.
Because if you check you compile warning carefully, you will find at least one warning(I'm use clang)
warning: if statement has empty body [-Wempty-body]
if (somearray [index] > highest);

The only issues I can see with your getLowScore/getHighScore methods is that they may go very wrong if the size is zero. Otherwise, there are no problems there. Without any additional context provided as to where & how those methods are used, it's not possible to help much further sadly.
Only other issue I can see in the getAvgScore method is that you want to append .0 to the 10 here:
average = totalScore / 10.0;
(otherwise the average can only ever end up being a whole number). Also, would it be sensible to return a double from getAvgScore? If thats cast to an int where its used, so be it. But at least you are returning the additional digits to the right of the decimal place in case you need them.

Related

OpenCL 1D range loop without knowledge of global size

I was wondering how can I iterate over a loop with a any number of work items (per group is irrelevant)
I have 3 arrays and one of them is 2-dimensional(a matrix). The first array contains a set of integers. The matrix is filled with another set of (repeated and random) integers.
The third one is only to store the results.
I need to search for the farest pair's numbers of occurrences of a number, from the first array, in the matrix.
To summarize:
A: Matrix with random numbers
num: Array with numbers to search in A
d: Array with maximum distances of pairs of each number from num
The algorithm is simple(as I don't need to optimize it), I only compare calculated Manhattan distances and keep the maximum value.
To keep it simple, it does the following (C-like pseudo code):
for(number in num){
maxDistance = 0
for(row in A){
for(column in A){
//calculateDistance is a function to another nested loop like this
//it returns the max found distance if it is, and 0 otherwise
currentDistance = calculateDistance(row, column, max)
if(currentDistance > maxDistance){
maxDistance = currentDistance
}
}
}
}
As you can see there is no dependent data between iterations. I tried to assign each work item a slice of the matrix A, but still doesn't convince me.
IMPORTANT: The kernel must be executed with only one dimension for the problem.
Any ideas? How can I use the global id to make multiple search at once?
Edit:
I added the code to clear away any doubt.
Here is the kernel:
__kernel void maxDistances(int N, __constant int *A, int n, __constant int *numbers, __global int *distances)
{
//N is matrix row and col size
//A the matrix
//n the total count of numbers to be searched
//numbers is the array containing the numbers
//distances is the array containing the computed distances
size_t id = get_global_id(0);
int slice = (N*N)/get_global_size(0);
for(int idx_num = 0; idx_num < n; idx_num++)
{
int number = numbers[idx_num];
int currentDistance = 0;
int maxDistance = 0;
for(int c = id*slice; c < (id+1)*slice; c++)
{
int i = c/N;
int j = c%N;
if(*CELL(A,N,i,j) == number){
coord_t coords;
coords.i = i;
coords.j = j;
//bestDistance is a function with 2 nested loop iterating over
//rows and column to retrieve the farest pair of the number
currentDistance = bestDistance(N,A,coords,number, maxDistance);
if(currentDistance > maxDistance)
{
maxDistance = currentDistance;
}
}
}
distances[idx_num] = maxDistance;
}
}
This answer may be seen as incomplete, nevertheless, I am going to post it in order to close the question.
My problem was not the code, the kernel (or that algorithm), it was the machine. The above code is correct and works perfectly. After I tried my program in another machine it executed and computed the solution with no problem at all.
So, in brief, the problem was the OpenCL device or most likely the host libraries.

'i' meaning and why is it there?

I'm new here as well to coding. Recently I've been going through Principles and Practice Using C++ and inside his code there is always an i inserted into his examples. Some are inside "vector's subscript" function, or inside "for statements" such as int i. But he didn't even make an int called i, it's just there. Maybe I missed something while reading, I don't know, but I hope someone wouldn't mind giving me a meaning as to why it's inserted in the places it's placed in, or just the meaning of i.
Below I took one of his examples from page 148 to show you
int main()
{
vector<double> temps; //temperatures
double temp = 0;
double sum = 0;
double high_temp = 0;
double low_temp = 0;
while (cin>>temp) // read and put into temps
temps.push_back(temp) ;
for (int i = 0; i<temps.size(); ++i) // these 'i's
{
if(temps[i] > high_temp) high_temp = temps[i]; // and these
if(temps[i] < low_temp) low_temp = temps[i];
sum += temps[i]; // compute sum
}
cout << " High temperature: " << high_temp<< endl; // find high
cout << " Low temperature: " << low_temp << endl; // find low
cout << "Average temperature: " << sum/temps.size() << endl;
}
When you write a software program, each variable that you declare must have a meaning, must represent something.
This is also the case in the book fragment you just read, only that we are talking about arrays. As you know, arrays are a collection of values of the same value type. Because it's a collection, it means there are 1 or more values into that array.
This raises the question: if there are 1 ore more values, how can I acces one specific value of that array? Here is where the i you read comes in.
The variable i has the meaning of the position of the array I am working on right now, where "working on" can mean reading, writing, etc. Because i is a variable, it must have a data type, hence the int i notation.
Using i as a variable in this context is not mandatory, but it's a very common practice. If you have a matrix, for example, you will need two such variables (one for rows and one for columns) which most likely will be i and j.
This also explains why we use i inside a for loop. In English, this means that the loop works with the elements that have the coefficient number from 0 to the array size.
i was declared as an int type in the for loop, but it could also be declared before that loop. Something like:
int i=0;
...
for (i=0; i<...)
i is declared as a variable of type int, here:
for (int i = 0; .......)
{
// 'i' used here
}
// 'i' cannot be used here
That i has a scope only inside that for loop. After the loop terminates, so does the lifetime of that variable i.
i is a part of convention, where it stands for iteration number.
It has been defined in the for loop:
for (int i = 0 ....
Which basically states that you start from iteration number zero. Once you gain some experience, you will see that iterations don't always start from zero, so i may be initialized with a different value (or a different variable name may be used instead of i altogether).
Mathematically, i is often used in context of a list/array: the ith element or summation from i=0 to i=n etc.
i is an integer, used as an indexing variable. You often see it in loops.
First, let's think about a vector and what it looks like. A vector is a variable-length array.
So if we have a vector named myVector with 5 elements, then we have something that looks like
myVector: item1 item2 item3 item4 item5
Now how do we specify individual items? We'll need to index each item. Traditionally (from mathematics), indexing begins at 0. So to index the first element, we do myVector[0]. To index the second element, we do myVector[1], and so on. (The [] is known as the subscript operator. You can also use myVector.at(0), myVector.at(1), but this is less used.)
Now what if we wanted to find the minimum or maximum value in a vector? We'd need to check each item and compare them. So we'll need to iterate (loop) through the entire array.
How do we do this? How do we iterate through each and every item? To loop through each item, we'd need something to specify the items. To loop through every item, we'd need a loop.
The loop in your code does this, iterating from 0 up to the length of the array/vector.
for (int i = 0; i < temps.size(); ++i) // iterate through EVERY element of the vector
{
// access EACH element of using temps[i]
}

Having trouble reading the output of my code

So the question was to return the difference between the maximum number and the smallest. My first code written was.
public int bigDiff(int[] nums) {
int max = 0;
int min = 0;
for(int i = 0; i < nums.length; i++){
if(Math.max(max, nums[i]) == nums[i])
max = nums[i];
else if (Math.min(min, nums[i]) == nums[i])
min = nums[i];
}
return max-min;
}
but this only outputs the largest number in the list.
Although, when I was just playing around and changed
int max = nums[0];
int min = nums[0];
it worked?, but I have no idea why. If anyone could understand how I would appreciate an explanation :D
Imagine array of values: 1,2,3. The proper minumum is 1. But, you have initialized min to 0. No value from this array is less than 0, so, min remains 0. Whoops, the answer is wrong. The similar case: array of -1, -2, -3, and maximum inited to 0 - again, wrong result.
I know three standard approaches to fix this:
Maximum and minimum are inited to the first value of sequence (array, in your case). That is exactly how you fixed it - by setting to nums[0]. OTOH you needn't start with index 0 - 1 is good also (very minor optimization but worth noting).
Maximum is inited with a smallest value ever possible for this type (for int, it's INT_MIN from <limits.h>), and minumum - to possible maximal one (INT_MAX, respectively). Most likely both will be immediately updated with nums[0].
A boolean variable with meaning "no values yet" is tested, and direct assignment instead of comparing is used when it is set (in your case, with i == 0 and immediately reset to false. It's a definitely overkill for a directly available integer array, but is good for cumbersome situations when comparing is inside of a callback instantiated through a template calling sequence, or another too-many-abstraction-levels design...
You have already warned that else is wrong, but, mathematically, it's allowed for my variants 1 and 3 (but not for variant 2! let you find out the fail proof by itself).
When you was just playing around and changed int max = nums[0]; int min = nums[0]; it worked.
Because, if you want to get the max num, you have to let variable max smaller than all of the member of arrary, then the function max() will make the max be the current maximum number。
So,the variable min must be larger then each member of the array!

C++ array (Beginner)

I misstook arrays for vectors, Sorry (array is vektor in swedish)
I would need some help with a program I'm making. It is a assignment so I really need to understand how I do this and not just get the code :P
I need to make a array containing 10 "numbers" (I would like to make them editable when the program is running).
After I'v done this I need to make the program calculate the "average value" of all the numbers "/
Would be pretty neat if you could pick how many numbers you wanted the average value of as well, if anyone could share some knowledge in how I should to that :P
Anyways, I'v tried some code to make the vector that didn't work, I might as well add it here:
int vector[10];
and
vector[0] "number 1: ";
and so on for the input of numbers in the vector.
int sum = vector[0] + vector[1] + ...
cout << "average value is: " << sum/5;
should work for getting the average value though (right?)
I should allso add:
float average(int v[], int n)
to this thing as well, can't really se how though.
Any help/knowledge at all would be awesome! Cheers.
To pick how many numbers you wanted to average:
Native: (G++/Clang) only, not "legal" C++
cin >> num;
int vector[num];
"Correct" native (pointers):
int *vector = new int [num];
"Proper" C++:
#include <vector>
std::vector<int> v(num);
A function like following would work for computing average of an array containing n elements.
float average(int v[], int n)
{
float sum = 0;
for(int i = 0 ; i < n ; i++)
{
sum += v[i]; //sum all the numbers in the vector v
}
return sum / n;
}
You can declare your array as you have done however i do recommend you to name it something else then vector to avoid confusion. About tour issue with changing the numbers in the array you can do this by for example maning a loop going from one to 10 and then make the user enter values for all the fields.
Vektor på svenska = array på engelska (vector är något annat :))
If you want exactly 10 numbers, you can eliminate a lot of overhead by simply using an array. However, assuming you want to use a vector, you can easily find the average taking advantage of its "size" member, as such:
float average(std::vector<int> nums)
{
int sum = 0;
for (unsigned int i = 0; i < nums.size(); i++)
sum += nums[i];
return sum / nums.size();
}
Note that this does assume the sum won't be higher than 2^31-1, IE the highest number a signed integer can represent. To be safer you could use an unsigned and/or 64 bit int for sum, or some arbitrary precision library like gmp, but I'd assume that is all outside the scope of your assignment.
You must declare and array of size 10, which you have done.
Use a loop to get ten inputs from the user.
(for or while loops would do)
Use another loop to calculate the sum of all ten numbers and store it in a variable.
Divide the variable by ten.
This is what you need to do essentially. But, to make your driver program prettier, you can define the following functions:
void GetInput(int *A); //put the input loop here
You can also write any one of the given two functions:
long Sum(int * A) //put the summing loop here
double Average(int * A) //put the summing loop here AND divide the sum by ten
Since you are a beginner I feel obliged to tell you that you don't need to return an array since it isalways passed as a reference parameter. I did not bother to pass the array size as a parameter to any functions because that is fixed and known to be 10 but it will be good practice to do that.

How do I find the mode of a sorted array?

I need to write a function to find the mode of a array. I'm not good at coming up with algorithms however and I'm hoping someone else knows how to do this.
I know the size of the array and the values in each element, and I have the array sorted from least to greatest.
array would be passed to the mode function like
mode = findMode(arrayPointer, sizePointer);
UPDATE:
After reading the comments I've tried this
int findMode(int *arrPTR, const int *sizePTR)
{
int most_found_element = arrPTR[0];
int most_found_element_count = 0;
int current_element = arrPTR[0];
int current_element_count = 0;
int count;
for (count = 0; count < *sizePTR; count++)
{
if(count == arrPTR[count])
current_element_count++;
else if(current_element_count > most_found_element)
{
most_found_element = current_element;
most_found_element_count = current_element_count;
}
current_element = count;
current_element_count=1;
}
return most_found_element;
}
I'm still having problems grasping this algorithm though if anyone can sort me out.
I've never used vectors so don't really understand the other examples.
You have almost everything.
You can take advantage of the fact that the array is sorted.
Just go through the array keeping track of both the current equal consecutive numbers, and the greatest number of equal consecutive numbers you have found until that point (and which number produced it). In the end you will have the greatest number of equal consecutive numbers and which number produced it. That will be the mode.
Note: For a solution which does not require the array to be sorted, see for example one based in the histogram approach in a related question.
set most_found_element to the first element in the array
set most_found_element_count to zero
set current_element to the first element of the array
set current_element_count to zero
for each element e in the array
if e is the same as the current_element
increase current_element_count by one
else
if current_element_count is greater than most_found_element_count
set most_found_element to the current_element
set most_found_element_count to current_element_count
set current_element to e
set current_element_count to one
if current_element_count is greater than most_found_element_count
set most_found_element to the current_element
set most_found_element_count to current_element_count
print most_found_element and most_found_element_count
I thought the names would explain it, but here we go:
When we start, no element has been found the most times
so the "high-score" count is zero.
Also, the "current" value is the first, but we haven't looked at it yet
so we've seen it zero times so far
Then we go through each element one by one
if it's the same as "current" value,
then add this to the number of times we've seen the current value.
if we've reached the next value, we've counted all of the "current" value.
if there was more of the current value than the "high-score"
then the "high-score" is now the current value
and since we reached a new value
the new current value is the value we just reached
Now that we've seen all of the elements, we have to check the last one
if there was more of the current value than the "high-score"
then the "high-score" is now the current value
Now the "high-score" holds the one that was in the array the most times!
Also note: my original algorithm/code had a bug, we have to do an extra check of "current" after the loop ends, as it never finds "the one after the last".
Hints:
Q: How do you define the mode?
A: The number whose count is greatest within the array.
Q: How do you count numbers in an ordered array?
A: Iterate through the array, and while the next item is equal to the previous, increment the count for that value.
Q: If the count of the previous value is less than the count of the current value, then can the previous value be the mode?
A: No
If the input array is sorted, here is the same approach as described in other answers but implemented in a different way, a better and easy to understand way.
Run a loop over the input array.
Keep global mode value and mode count.
Run a sliding window till you find equal elements.
If local equal element count is greater than global mode count, then update global mode and mode count.
Here is working and tested code in C++.
int mode(vector<int> a, int N)
{
int mode = a[0];
int mode_count = 1;
int i = 0;
while (i < N - 1) {
int cur = a[i];
int cur_count = 1;
while (a[i] == a[i + 1]) {
i++;
cur_count++;
}
if (cur_count > mode_count) {
mode_count = cur_count;
mode = a[i];
}
i++;
}
return mode;
}