recursive function error - c++

I have a program that is supposed to read in values from user into a vector. My function is then supposed to keep a running sum and start from element 1 and compare element 2 to the sum(this point it is just element 1). Move to the next element, add element 2 to the sum and see if element 3 is greater than the sum of elements 1 and 2. I am supposed to print only the elements that are greater than the sum. I'm having trouble getting it to print out any values. Could someone please let me know what I might be doing wrong? Thanks
int main()
{
vector <int> theData;
int i;
cout<< "Enter in the list of integers ending with a -1" << endl;
do
{
cin >> i;
if (i==-1)
{
break;
}
theData.push_back(i);
}while(i!=-1);
int index = 1;
int runningSum = unsortedData[i];
largeValue(unsortedData, index, runningSum);
system("PAUSE");
return 0;
}
void largeValue(vector<int> myVector, int index, int runningSum)
{
int size = myVector.size();
if (index == size)
{
return;
}
if (myVector[index] > runningSum)
{
cout << myVector[index] << " ";
runningSum += myVector[index];
index = index +1;
largeValue(myVector, index, runningSum);
}
else if (myVector[index] < runningSum)
{
runningSum += myVector[index];
index = index + 1;
largeValue(myVector, index, runningSum);
}
}

There are several errors in your code:
int runningSum = unsortedData[i];
You probably meant index, not i. Both are wrong, though: the first index in the array is 0, not 1 (which is the value of index).
Also, your recursive function contains at least one error: you don’t consider that the current element equals the sum.
Another thing: you pass the vector to your function by value – not a good idea: for each call of the function, the whole vector is copied, which may take considerable time for medium-sized vectors. In “real” code, large data types should always be passed by (const) reference. Just change the function signature slightly:
void largeValue(vector<int> const& myVector, int index, int runningSum)
This way, you pass an unmodifiable reference of your vector to the function instead of copying it. Notice that this makes it impossible to modify the data of the vector inside the function.

Firstly, your function fails to meaningfully process the case when myVector[index] == runningSum.
Secondly, the initial value of runningSum is taken from unsortedData[i] which doesn't make any sense, since i is -1 at that time. You probably meant unsortedData[0].

Early in main you use theData and later you use unsortedData. I'm not sure why the compiler hasn't complained about unsortedData not being defined.

Related

Function to check if an array is a permutation

I have to write a function which accepts an int array parameter and checks to see if it is a
permutation.
I tried this so far:
bool permutationChecker(int arr[], int n){
for (int i = 0; i < n; i++){
//Check if the array is the size of n
if (i == n){
return true;
}
if (i == arr[n]){
return true;
}
}
return false;
}
but the output says some arrays are permutations even though they are not.
When you write i == arr[n], that doesn't check whether i is in the array; that checks whether the element at position n is i. Now, that's even worse here, as the array size is n, so there's no valid element at position n: it's UB, array is overindexed.
If you'd like to check whether i is in the array, you need to scan each element of the array. You can do this using std::find(). Either that, or you might sort (a copy of) the array, then check if i is at position i:
bool isPermutation(int arr[], int n){
int* arr2 = new int[n]; // consider using std::array<> / std::vector<> if allowed
std::copy(arr, arr + n, arr2);
std::sort(arr2, arr2 + n);
for (int i = 0; i < n; i++){
if (i != arr2[i]){
delete[] arr2;
return false;
}
}
delete[] arr2;
return true;
}
One approach to checking that the input contains one of each value is to create an array of flags (acting like a set), and for each value in your input you set the flag to true for the corresponding index. If that flag is already set, then it's not unique. And if the value is out of range then you instantly know it's not a permutation.
Now, you would normally expect to allocate additional data for this temporary set. But, since your function accepts the input as non-constant data, we can use a trick where you use the same array but store extra information by making values negative.
It will even work for all positive int values, since as of C++20 the standard now guarantees 2's complement representation. That means for every positive integer, a negative integer exists (but not the other way around).
bool isPermutation(int arr[], int n)
{
// Ensure everything is within the valid range.
for (int i = 0; i < n; i++)
{
if (arr[i] < 1 || arr[i] > n) return false;
}
// Check for uniqueness. For each value, use it to index back into the array and then
// negate the value stored there. If already negative, the value is not unique.
int count = 0;
while (count < n)
{
int index = std::abs(arr[count]) - 1;
if (arr[index] < 0)
{
break;
}
arr[index] = -arr[index];
count++;
}
// Undo any negations done by the step above
for (int i = 0; i < count; i++)
{
int index = std::abs(arr[i]) - 1;
arr[index] = std::abs(arr[index]);
}
return count == n;
}
Let me be clear that using tricky magic is usually not the kind of solution you should go for because it's inevitably harder to understand and maintain code like this. That should be evident simply by looking at the code above. But let's say, hypothetically, you want to avoid any additional memory allocation, your data type is signed, and you want to do the operation in linear time... Well, then this might be useful.
A permutation p of id=[0,...,n-1] a bijection into id. Therefore, no value in p may repeat and no value may be >=n. To check for permutations you somehow have to verify these properties. One option is to sort p and compare it for equality to id. Another is to count the number of individual values set.
Your approach would almost work if you checked (i == arr[i]) instead of (i == arr[n]) but then you would need to sort the array beforehand, otherwise only id will pass your check. Furthermore the check (i == arr[n]) exhibits undefined behaviour because it accesses one element past the end of the array. Lastly the check (i == n) doesn't do anything because i goes from 0 to n-1 so it will never be == n.
With this information you can repair your code, but beware that this approach will destroy the original input.
If you are forced to play with arrays, perhaps your array has fixed size. For example: int arr[3] = {0,1,2};
If this were the case you could use the fact that the size is known at compile time and use an std::bitset. [If not use your approach or one of the others given here.]
template <std::size_t N>
bool isPermutation(int const (&arr)[N]) {
std::bitset<N> bits;
for (int a: arr) {
if (static_cast<std::size_t>(a) < N)
bits.set(a);
}
return bits.all();
}
(live demo)
You don't have to pass the size because C++ can infer it at compile time. This solution also does not allocate additional dynamic memory but it will get into problems for large arrays (sat > 1 million entries) because std::bitset lives on automatic memory and therefore on the stack.

Sort Specific Column of 2D int array (C++)

I've got a bit of a conundrum. I'm currently trying to create a user-defined function to sort a column (in ascending order) of a 2D int array I created and populated in the main function. I feel like I'm close, but for some reason the final output is incorrect, it provides a number for the final value that isn't even in the array. Judging from the value provided and the extra few seconds it takes to compile, I'm assuming I've messed up my bounds/ gone beyond them at some point within the code, but I've been fighting this thing for hours to no avail and I feel fresh (and likely more experienced) eyes would be-be of some use. I'm still in my "Intro to" class for programming, so ripping me a new one for obvious errors is encouraged as my final is this Thursday and any and all pointers/tips are appreciated. Cheers!
#include <iostream>
using namespace std;
void sort2D(int arr[3][5], int rows, int columns) //the problem child
{
int userCol;
cout<<"Please enter the number of the column you'd like to sort: "<<endl;
cin>>userCol; //ask for appropriate column
for (int row_index=0; row_index<rows; row_index++) //start with first row and continue for all values in code
{
int temp;
if ((arr[row_index][userCol-1]<arr[row_index+1][userCol-1]))//if first value of selected column is less than next value
{
temp = arr[row_index+1][userCol-1];//create copy of second value
arr[row_index+1][userCol-1]=arr[row_index][userCol-1]; //replace second value with first value
arr[row_index][userCol-1]=temp;//set first equal to second's original value
}
}
for(int i=0; i<rows; i++)//print that shiz
{
for(int j=0; j<columns; j++)
{
cout<<arr[i][j]<<" ";
}
cout<<endl;
}
}
int main()
{
const int rows = 3;
const int columns = 5;
int arr[rows][columns];
for (int row_index=0; row_index<rows; row_index++)
{
for (int column_index=0; column_index<columns; column_index++)
{
arr[row_index][column_index] = (50+rand()%51);
cout << arr[row_index][column_index]<<" ";
}
cout << endl;
}
findMaxandIndex(arr, rows, columns);//i left my code for this out because it's working and isn't utilized in the problem code
cout << endl;
sort2D(arr, rows, columns);
return 0;
Your sort function is very close to bubble sort, one of the simplest sorting algorithms to understand and implement. With a little modification, your code will work :
void sort2D(int arr[3][5], int rows, int columns) //the problem child
{
//input userCol ...
//sorting start here ...
bool found = true; //we can quit the loop if the array is already sorted.
for (int bubble = 0; bubble < rows-1 && found ; bubble++)
{
found = false;
for (int row_index=0; row_index < rows - bubble - 1; row_index++)
{
int temp;
if ((arr[row_index][userCol-1] < arr[row_index+1][userCol-1]))//if first value of selected column is less than next value
{
//swap two elements.
temp = arr[row_index+1][userCol-1];//create copy of second value
arr[row_index+1][userCol-1]=arr[row_index][userCol-1]; //replace second value with first value
arr[row_index][userCol-1]=temp;//set first equal to second's original value
found = true; //we found something, continue to sort.
}
}
}
//print out the result ...
}
As you start in C++, an advice is to use C++ facilities if possible : std::vector for your array and std::qsort for sorting elements.
Issue 1: The int arr[3][5]; you declared in sort2D() is NOT the same as the int arr[rows][columns]; you declared in main().
lesson : check (or web search) on "pass by reference" & "pass by value" . For simplicity, I recommend pass by value.
Issue 2: The sort only compare 2 values and only run for 1 pass.. so {2,1,4,3} may get sorted to {1,2,3,4} but {1,4,3,2} will only get to {1,3,2,4} with 1 pass. #ZDF comment is helpful for this part.
Issue 3: at this line.. temp = arr[row_index+1][userCol-1]; when row_index is 2, this will refer to a location that is not in the arr[][] array. arr are only defined for row = 0,1,2 .. not 3 (when row_index is 2, row_index+1 is 3). This may answer :
it provides a number for the final value that isn't even in the array.
Solution.. hurm. I suggest you have a look and try.. and share where you stuck at. you may also test the sort2D in the main function before doing it as separate function. IMHO, you can start by 1st looking for the sorting algorithm that works (with sample data).. Then work on making it work in this project. ( :
p/s: I don't see my post as an answer.. more like a correction guide.

Pointers, dynamic arrays, and memory leak

I'm trying to create a program which allows for a dynamically allocated array to store some integers, increase the maximum size if need be, and then display both the unsorted and sorted array in that order.
Link to my full code is at the bottom.
The first issue I have is the dynamically allocated array going haywire after the size needs to be increase the first time. The relevant code is below.
while (counter <= arraySize)
{
cout <<"Please enter an integer number. Use 999999 (six 9's) to stop\n";
if (counter == arraySize) //If the counter is equal to the size of the array
{ //the array must be resized
arraySize +=2;
int *temp = new int[arraySize];
for (counter = 0; counter < arraySize; counter++)
{
temp[counter] = arrayPtr[counter];
}
delete [] arrayPtr;
arrayPtr = temp;
counter ++; //the counter has to be reset to it's original position
} //which should be +1 of the end of the old array
cin >> arrayPtr[counter];
if (arrayPtr[counter] == sentinel)
{
cout << "Sentinel Value given, data entry ending.\n";
break;
}
counter ++;
}
This produces the unintended operation where instead of waiting for the sentinel value, it just begins to list the integers in memory past that point (because no bounds checking).
The next issue is that my sorting function refuses to run. I tried testing this on 5 values and the program just crashes upon reaching that particular part of code.
The function is called using
sorting (arrayPtr);
but the function itself looks like this:
void sorting (int *arr)
{
int count = 0, countTwo = 0, tempVal;
for (count = 0; arr[count] != 999999; count++) //I figured arr[count] != 999999 is easier and looks better
{ //A bunch of if statements
for (countTwo = 0; arr[countTwo] != 99999; countTwo++)
{
if (arr[countTwo] > arr[countTwo+1])
{
tempVal = arr[countTwo];
arr[countTwo] = arr[countTwo+1];
arr[countTwo+1] = tempVal;
}
}
}
}
Any help on this issue is appreciated.
Link to my source code:
http://www.mediafire.com/file/w08su2hap57fkwo/Lab1_2336.cpp
Due to community feedback, this link will remain active as long as possible.
The link below is to my corrected source code. It is annotated in order to better highlight the mistakes I made and the answers to fixing them.
http://www.mediafire.com/file/1z7hd4w8smnwn29/Lab1_2336_corrected.cpp
The first problem I can spot in your code is in the for loop where counter goes from 0 to arraySize-1, the last two iteration of the loop will access arrrayPtr out of bounds.
Next, at the end of the if (counter == arraySize) there is a counter++; This is not required since at this moment counter is already indexing the array out of bound.
Finally in your sorting function the inner loop looks for the wrong value (99999 instead of 999999), so it never stop and goes out of bounds. To prevent this kind of error, you should define your sentinel as a const in an unnamed namespace and use it through the code instead of typing 999999 (which is error prone...).

C++ Array, How should i fix my array, it needs to remove all multiples of a variable?

I Have to write a function, named filter, that removes all multiples of a variable named num from the given list by calling a function i have written earlier named remove. Here are my two functions. Remove works properly however filter does not. Any input would be nice and i would greatly appreciate it. The filter function is supposed to remove all multiples of num from the program using remove. It currently does nothing and i do not think it entering the loop properly.
void remove(int vals[], int sz, int index)
{
for(int i = index ; i <(sz-1); ++i)
{
// shifts down the array once the index element has been removed
vals[i] = vals[i +1];
}
// adds -1 at the end of array once the element has been removed from a certain position.
vals[sz - 1] = -1;
}
void filter(int vals[], int sz, int startIndex, int num)
{
for(int i =2; i< num; i++)
{
if( num % i == 0)
{
remove( vals, sz, num );
}
else if( num % i != 0 );
{
cout << num << "is a prime number" << endl;
}
}
}
A list of problems:
You are looping up to num, you should be looping up to sz, as you want to be checking each entry in the array.
You aren't checking num against the values in vals. You need to be checking against vals[i]
If you remove an item from vals, it will be one item shorter, you need to update sz with the new count. You also need to work out how you are going to tell the caller that the array is now shorter (unless -1 in the array is OK as a flag).
If you remove an item from vals, it will be one item shorter, you need to take that into account with your i variable, otherwise you will skip an entry after a delete.
As #Jon says - you have a semicolon after your else if line.
Just because a number is not divisible by a certain other number does not make it prime.

How do I drop the lowest value?

I'm pretty new to C++, and I need help figuring out the code for dropping the lowest value of a randomly generated set of numbers. Here is my code so far:
//Create array and populate the array with scores between 55 and 10
// Drop lowest Score
#include <iostream>
#include <cstdlib>//for generating a random number
#include <ctime>
#include <iomanip>
#include <algorithm>
#include <vector>
using namespace std;
//function prototype
int *random (int);
int main()
{ int *numbers; //point to numbers
//get an array of 20 values
numbers = random(20);
//display numbers
for (int count = 0; count < 20; count++)
cout << numbers[count] << endl;
cout << endl;
system("pause");
return 0;
}
//random function, generates random numbers between 55 and 100 ??
int *random(int num)
{ int *arr; //array to hold numbers
//return null if zero or negative
if (num <= 0)
return NULL;
//allocate array
arr = new int[num];
//seed random number generator
srand(time (0));
//populate array
for (int count = 0; count < num; count++)
arr[count] = (rand()%(45) +55);
//return pointer
//
return arr;
}
For this piece of code, how would I sort or find the lowest score to drop it after the function returns the random numbers?
int main()
{ int *numbers; //point to numbers
//get an array of 20 values
numbers = random(20);
//display numbers
for (int count = 0; count < 20; count++)
cout << numbers[count] << endl;
cout << endl;
system("pause");
return 0;
}
Your suggestions are appreciated!
In general, to find the lowest value in an array, you can follow this psuedo-algorithm:
min = array[0] // first element in array
for (all_values_in_array)
{
if (current_element < min)
min = current_element
}
However, you can't "drop" a value out of a static array. You could look into using a dynamic container (eg. vector), or swapping the lowest value with the last value, and pretending the size of the array is 1 less. Another low level option would be to create your own dynamic array on the heap, however, this is probably more complicated than you are looking for.
Using an vector would be much easier. To drop the lowest element, you just have to sort in reverse order, then remove the last element. Personally, I would recommend using a vector.
The obvious approach to find the smallest element is to use std::min_element(). You probably want to use std::vector<T> to hold your elements but this isn't absolutely necessary. You can remove the smallest value from an array like this:
if (count) {
int* it = std::min_element(array, array + count);
std::copy(it + 1, array + count--, it);
}
Assuming you, reasonable used std::vector<int> instead, the code would look something like this:
if (!array.empty()) {
array.erase(std::min_element(array.begin(), array.end()));
}
First find the index of the lowest number:
int lowest_index=0, i;
for (i=0; i<20; i++)
if (arr[i]<arr[lowest_index])
lowest_index=i;
Now that we know the index, move the numbers coming after that index to overwrite the index we found. The number of numbers to move will be 19 minus the found index. Ie, if index 2 (the third number, since the first is at index 0) is lowest, then 17 numbers comes after that index, so that's how many we need to move.
memcpy(&arr[lowest_index],&arr[lowest_index+1],sizeof(int)*(19-lowest_index))
Good luck!
Sort the array ascending.
The lowest value will be at the beginning of the array.
Or sort the array descending and remove the last element.
Further to what others have said, you may also choose to use something like, perhaps a std::list. It's got sorting built-in, also offering the ability to define your own compare function for two elements. (Though for ints, this is not necessary)
First, I typically typedef the vector or list with the type of the elements it will contain. Next, for lists I typedef an iterator - though both of these are merely a convenience, neither is necessary.
Once you've got a list that will holds ints, just add them to it. Habit and no need to do otherwise means I'll use .push_back to add each new element. Once done, I'll sort the list, grab the element with the lowest value (also the lowest 'index' - the first item), then finally, I'll remove that item.
Some code to muse over:
#include <cstdio>
#include <cstdlib>
#include <list>
using namespace std;
typedef list<int> listInt;
typedef listInt::iterator listIntIter;
bool sortAsc(int first, int second)
{
return first < second;
}
bool sortDesc(int first, int second)
{
return first > second;
}
int main (void)
{
listInt mList;
listIntIter mIter;
int i, curVal, lowestScore;
for (i=1; i<=20; i++)
{
curVal = rand()%45 + 55;
mList.push_back(curVal);
printf("%2d. %d\n", i, curVal);
}
printf("\n");
mList.sort();
// mList.sort(sortAsc); // in this example, this has the same effect as the above line.
// mList.sort(sortDesc);
i = 0;
for (mIter=mList.begin(); mIter!=mList.end(); mIter++)
printf("%2d. %d\n", ++i, *mIter);
printf("\n");
lowestScore = mList.front();
mList.pop_front();
printf("Lowest score: %d\n", lowestScore);
return 0;
}
Oh, and the choice to use printf rather than cout was deliberate too. For a couple of reasons.
Personal preference - I find it easier to type printf("%d\n", someVar);
than cout << someVar << endl;
Size - built with gcc under windows, the release-mode exe of this example is 21kb.
Using cout, it leaps to 459kb - for the same functionality! A 20x size increase for no gain? No thanks!!
Here's an std::list reference: http://www.cplusplus.com/reference/stl/list/
In my opinion the most optimal solution to your problem would be to use a linked list to store the numbers, this way you can use an algorithm with complexity O(N) = N to find the smallest element in the list, it is a similar finding method given by user1599559 or Mikael Lindqvist, you only need stored together with the minimum value the pointer to the Item(ItemX) in the linked list that store it, then to eliminate Item X just tell Item X - 1 points to Item X + 1 and free memory allocated by Item X