Function returning the wrong value - c++

This project is a homework assignment for school. The instructor has asked us to input 20 random integers then print the smallest in the list and then search the list for the first iteration of the number entered. My problem is returning the smallest number of the list. The function, shown below accepts an integer array and an integer with the size of the array. In Visual Studio, the tests for the smallest number work until the function returns the value. Instead of returning the smallest number, the function returns some kind of default value as opposed to the smallest integer. I have been staring at this code for the past two hours, any help would be appreciated.
int theSmallest(const int a[], int number_used)
{
int temp = a[0];
// Find the smallest number in array a[]
for (int i = 0; i <= number_used; i++)
{
if (temp >= a[i])
{
temp = a[i];
}
}
return temp;
}

Your program has undefined behavior because you are accessing the array a using an invalid index.
When an array has 20 elements, the valid indices are 0-19, not 0-20.
You are using
for (int i = 0; i <= number_used; i++)
and then accessing a[i] in the loop. If number_used is equal to 20, you are accessing a using and index value of 20, which is not correct.
Change that to use i < number_used.
for (int i = 0; i < number_used; i++)
A minor issue is that you are using temp >= a[i], which can be changed to use temp > a[i]. Use of >= in this case will work but it will do more work than necessary.
Here's an updated version of the function:
int theSmallest(const int a[], int number_used)
{
int temp = a[0];
// Find the smallest number in array a[]
for (int i = 1; i < number_used; i++)
{
if (temp > a[i])
{
temp = a[i];
}
}
return temp;
}

Assuming number_used is the size of array, code can be written as:
int theSmallest(const int a[], int number_used)
{
if( a == nullptr or number_used == 0 )
throw std::runtime_error( "invalid argument" );
return *std::min_element( a, a + number_used );
}
Note: you code has issue in case number_used is equal to 0 or a pointer is passed as nullptr, you may not expect that to happen but it is good idea to always validate your input (at least by assert())

Change to i < number_used and I think change to if(temp > a[i]).
You can also start i=1 since you made the assumption index 0 is the smallest.

Change
for (int i = 0; i <= number_used; i++)
to
for (int i = 1; i < number_used; i++)

Related

comparing one array element with the next element to find what is the biggest element

I'm trying to find a way to iterating while comparing the element with the next element to find what is the biggest element in the array. But, the output i want keep repeating as much as the loop run.
int main(){
int array[4];
for ( int i = 0; i < 4; i++){
cin >> array[i];
}
for (int i:array){
for (int j = 1; j < 4; j++){
if (i < array[j]){
break;
}
if (i > array[j] ){
cout << i;
}
}
}
}
You can use the following program to find the biggest element in the array. Note that there is no need to use two for loops as you did in your code snippet.
#include <iostream>
int main()
{
int array[4] = {1,10, 13, 2};
int arraySize = sizeof(array)/sizeof(int);//note that you can also use std::size() with C++17
int startingValue = array[0];
for(int i = 1; i < arraySize; ++i)//start from 1 instead of 0 since we already have array[0]
{
if(array[i] > startingValue)
{
startingValue = array[i];
}
}
//print out the biggest value
std::cout<<"the biggest element in the array is: "<<startingValue<<std::endl;
return 0;
}
Your program is reapeating output because you have the cout inside the if which is satisfied multiple times(depending upon how big the array is and what elements it contains). For example, if you try your example on the array int array[] = {23,2,13,6,52,9,3,78}; then the output of your program will be 2323231313652525293787878 . So the output is reapeating more than 2 times. You can instead use the version i gave that uses only 1 for loop and prints the correct biggest element only once.
Note that you can also use std::size with C++17 while sizeof(array)/sizeof(int) works with all C++ versions.

Array Sorting Issues in C++

I am trying to make a program that sorts an array without using the sort function (that won't work with objects or structs). I have made the greater than one work, but the less than one keeps changing the greatest element in the array to a one and sorting it wrong, and when used with the greater than function, the first element is turned into a large number. Can someone please help me fix this or is it my compiler.
void min_sort(int array[], const unsigned int size){
for(int k = 0; k < size; k++) {
for(int i = 0; i < size; i++) {
if(array[i] > array[i+1]){
int temp = array[i];
array[i] = array[i+1];
array[i+1] = temp;
}
}
}
}
You are not looping correctly. Looks like you are trying bubble sort which is:
void min_sort(int array[], const unsigned int size){
for(int k = 0; k < size; k++)
for(int i = k+1; i < size; i++)
if(array[i] < array[k]){
int temp = array[i];
array[i] = array[k];
array[k] = temp;
}
}
void min_sort(int array[], const unsigned int size)
{
for(int i=0;i<size-1;i++)
{
for(int j=0;j<size-1-i;j++)
{
if(array[j]>array[j+1])
{
swap(array[j] , array[j+1]);
}
}
}
}
I see that you are trying to implement the bubble sort algorithm. I have posted the code for bubble sort here. In bubble sort you basically compare the element at an index j and the element next to it at index j+1. If array[j] is greater than array[j+1] , you swap them using the swap() function or by using the temp method. The outer loop will run size - 1 times , and the inner loop will run size - 1 - i times because the last element will already be in place.
For Example we have an array of size 4 with elements such as :
array[i] = [100,90,8,10]
The bubble sort will sort it in the following steps :
90,100,8,10
90,8,100,10
90,8,10,100
8,90,10,100
8,10,90,100
8,10,90,100
See, the use of size-1-i . You can see the nested loop runs less number of times in each iteration of the outer loop.
There is only one mistake that your 2nd loop condition should be: i < size -1.
So it should be:
for (int i = 0; i < size -1; i++)
Your attempt at bubble sort is basically correct, you just have an out of bounds issue with your inner loop. During the inner loop's last run, i == size - 1, therefore i + 1 is equal to size, thus data[i+1] is out of range. Simply change the condition of your for to be i < size - 1.
Working example: https://godbolt.org/z/e5ohWPfTz

My array is gettting an error because it's being defined as a singular integer

The point of this program is to output whether a series of digits (the number of digits undefined) is sorted or not (largest to smallest or smallest to largest).
I have defined my array in my function parameter, and I am trying to use a for loop to store the user's input, as long as it is above 0, in said array.
However, I am getting the error argument of type int is incompatible with parameter of type int*.
The exact error is the argument of type int is incompatible with parameter of type int*.
It is referring to line 22 and 23, these two;
isSorted(list[2000]); and
bool is = isSorted(list[2000]);.
I know this means my for loop is assigning a single value to my variable repeatedly from reading similar questions however I can not figure out how to fix this.
#include <iostream>
using namespace std;
bool isSorted(int list[]);
int main()
{
int i;
int list[2000];
int k = 0;
for (i = 0; i < 2000; i++)
{
int j;
while (j > 0)
{
cin >> j;
list[i] = j;
}
}
isSorted(list[2000]);
bool is = isSorted(list[2000]);
if (is == true)
cout << "sorted";
else
cout << "unsorted";
return 0;
}
bool isSorted(int list[])
{
int i = 0;
for (i = 0; i < 2000; i++)
{
if (list[i] > list[i + 1] || list[i] < list[i - 1])
{
return false;
}
else
return true;
}
}
I removed unused variable k.
Made 2000 parameterized (and set to 5 for testing).
In isSorted you are not allowed to return
true in the else as if your first element test would end in else you would return true immediately not testing other elements. But those later elements can be unsorted as well.
In isSorted you are not allowed to run the loop as for(i = 0; i < 2000; i++), because you add inside the for loop 1 to i and end up querying for i == 1999 list[2000], which is element number 2001 and not inside your array. This is correct instead: for (i = 0; i < 1999; i++). You also do not need to check into both directions.
You cannot call isSorted(list[2000]) as this would call is sorted with an int and not an int array as parameter.
You write int j without initializing it and then query while j > 0 before you cin << j. This is undefined behaviour, while most likely j will be zero, there is no guarantee. But most likely you never enter the while loop and never do cin
I renamed the isSorted as you just check in your example for ascending order. If you want to check for descending order you are welcome to train your programming skills and implementing this yourself.
Here is the code with the fixes:
#include <iostream>
using namespace std;
bool isSortedInAscendingOrder(int list[]);
const int size = 5; // Set this to 2000 again if you want
int main()
{
int i;
int list[size];
for (i = 0; i < size; i++)
{
int j = 0;
while(j <= 0)
{
cin >> j;
if(j <= 0)
cout << "rejected as equal or smaller zero" << endl;
}
list[i] = j;
}
if (isSortedInAscendingOrder(list))
cout << "sorted" << endl;
else
cout << "unsorted" << endl;
return 0;
}
bool isSortedInAscendingOrder(int list[])
{
for (int i = 0; i < size -1; i++)
{
if (list[i] > list[i + 1])
{
return false;
}
}
return true;
}
This is a definition of an array of 2000 integers.
int list[2000];
This is reading the 2000th entry in that array and undefined, because the highest legal index to access is 1999. Remember that the first legal index is 0.
list[2000]
So yes, from point of view of the compiler, the following only gives a single integer on top of being undefined behaviour (i.e. "evil").
isSorted(list[2000]);
You probably should change to this, in order to fix the immediate problem - and get quite close to what you probably want. It names the whole array as parameter. It will decay to a pointer to int (among other things loosing the information of size, but you hardcoded that inside the function; better change that by the way).
isSorted(list);
Delete the ignored first occurence (the one alone on a line), keep the second (the one assigning to a bool variable).
On the other hand, the logic of a your sorting check is flawed, it will often access outside the array, for indexes 0 and 1999. I.e. at the start and end of your loop. You need to loop over slightly less than the whole array and only use one of the two conditions.
I.e. do
for (i = 1; i < 2000; i++)
{
if (list[i] < list[i - 1])
/* ... */
The logic for checking ascending or descending sorting would have to be more complex. The question is not asking to fix that logic, so I stick with fixing the issues according to the original version (which did not mention two-way-sorting).
You actually did not ask about fixing the logic for that. But here is a hint:
Either use two loops, which you can break from as soon as you find a conflict, but do not return from the fuction immediatly.
Or use one loop and keep a flag of whether ascending or descending order has been broken. Then return true if either flag is still clear (or both, in case of all identical values) or return false if both are set.

Return the index for the maximum value

I have written the following which gets the index value for the maximum number.
int TravellingSalesMan::getMaximum(double *arr){
double temp = arr[0];
int iterator = 0;
for(int i = 0; i < 30; i++){
if(arr[i] > temp){
iterator = i;
}
}
return iterator;
}
But the output keeps stepping into the conditional statement and keeps printing out 29. I am not sure why this is happening
I also tried using max_element() but with no luck
EDIT
The above function is invoked as following
static unsigned int chromosome = 30;
double value[chromosome]
for(int i = 0; i < chromosomes; i++){
value[i] = estimateFitness(currPopultaion[i]);
}
int best = 0;
best = getMaximum(value);
cout<<best<<endl; // this just prints out 29
Okay, so I didn't plan on writing the answer, but I just saw too many logical mistakes in the code for me to write in the comments section!
First of all, your use of the variable name iterator is very
wrong. It's not used for iteration over the list. Why create confusion. Best to use something like max_index or something like that.
Why start from i=0? Your temp value is arr[0], so there is no use. of checking with first element again. Start from i=1!
temp is pointless in that function. The maximum index should initially be 0, and set to i if ever there is some arr[i] that is greater than arr[max_index].
Passing the length separately to the function is better coding as it makes the code more clearer.
The content in arr is not modified, and as such better safe than sorry: make the pointer const.
Re-writing the code, it should be:
int TravellingSalesMan::getMaximum(const double *arr,int len)
{
int max_index = 0;
for(int i = 1; i < len; i++)
{
if(arr[i] > arr[max_index])
max_index = i;
}
return max_index;
}
Worth noting, but unchanged in the code above, len, i, and the function result should all be an unsigned integer type. There is no reason, to allow signed integer indexing, so make it a warning-condition from the caller if they do so by hard-specifying unsigned or just size_t as the indexing variable types.
You should be assigning a new value to temp when you find a new maximum.
int TravellingSalesMan::getMaximum(double *arr){
double temp = arr[0];
int iterator = 0;
for(int i = 0; i < 30; i++){
if(arr[i] > temp){
iterator = i;
temp = arr[i]; // this was missing
}
}
return iterator;
}
Without this you are finding the largest index of a value greater than the value at index zero.
A much better solution is to simply use std::max_element instead. Pointers can be used as iterators in most (if not all) algorithms requiring iterators.
#include <algorithm>
static unsigned int chromosomes = 30;
double value[chromosomes];
for (int i=0; i<chromosomes; ++i) {
value[I] = estimate_fitness(current_population[i]);
}
double *max_elm = std::max_element(&value[0], &value[chromosomes]);
int best = int(max_elm - &value[0]);
std::cout << best << std::endl;

c++ array can't get the right array

I have Array A[9]= {1,2,3,4,5,6,7,8,9} and I need to delete the numbers which are not dividing by 2. The code I tried to do:
int main()
{
int n;
ifstream fd(Cdf);
fd>>n; // read how many numbers are in the file.
int A[n];
for(int i = 0; i < n; i++)
{
fd >> A[i]; //read the numbers from file
}
for(int i = 0; i < n; i ++) // moving the numbers.
{
if(A[i] % 2 !=0)
{
for(int j = i; j < n; j++)
{
A[i] = A[i+1];
}
}
}
fd.close();
return 0;
}
But I get numbers like 224466888. what I need to do to get 2,4,6,8?
I need to delete numbers in the same array.
First you should use std::vector for dynamic size arrays.
Second, for removing numbers that are even in a vector, you can do :
std::vector<int> inf = {12,0,5,6,8};
auto func = [](int i){return i % 2 != 0;};
inf.erase(std::remove_if(inf.begin(),inf.end(),func), inf.end());
EDIT :
Ok, so you can still do this without std::vectors, but it will be uglier :
#include <algorithm>
int res[] = {2,5,9,8,6,7};
int size = 6;
auto func = [](int i){return i % 2 != 0;};
int new_size = std::remove_if(res,res + size, func) - res;
All the data you want is in [0, new_size[ range, the other part of your array is now garbage.
Your removal loop is indexing with the wrong variable:
for(int j = i; j < n; j++)
{
A[i] = A[i+1];
}
You're using i, which doesn't change in the loop.
Change it to j. You also need to subtract one from the upper limit, as you'd step outside of the array otherwise when accessing A[j + 1].
for(int j = i; j < n - 1; j++)
{
A[j] = A[j + 1];
}
An array can't be used for your purpose. It is allocated on stack and its size can't be changed dynamically (you can't change the size of an array in general, not only when it is allocated on stack).
You could allocate a second array and keep reallocating it with realloc everytime you add a new element but that's not the good way to do it. You are working with C++ so just use a std::vector<int> and your problems will be solved:
std::vector<int> evenArray;
evenArray.reserve(sizeof(A)/sizeof(A[0])/2);
if (number is even) {
evenArray.pushBack(number);
}
Mind that vector stores elements contiguously so this is legal:
int *evenA = &evenArray[0];
For your inner for loop you should be referencing j, not i.
for(int j = i; j < n - 1; j++)
{
A[j] = A[j+1];
}
Otherwise, what's the point of creating j?
Of course, this also means if you read the whole array back you will display all the characters that were shifted (which will just be equal to the last number). So, you should probably keep track of the new length of the array and just iterate to that instead of the end of the array.
EDIT:
In the inner for loop you need to loop to n - 1 otherwise when you have A[j + 1] it will go off the end of the array when you to change it, which may or may not give you a runtime error.