I have used this function to find the maximum element
It works for some cases but it got wrong place in other cases and this is the case i call function with.
int maxElement=maxi(names,noOfTeams,0,1,sum,0)
this is the function :
int maxi(string names[],int sizee,int prev,int next,int scores[],int maxx)
{
if (sizee ==1)return 0;
if (scores[maxx]<scores[next]) maxx=next;
if ((next+1)==sizee)return maxx;
else return maxi(names,sizee,prev+1,next+1,scores,maxx);
}
You have couple of errors in your function.
The line
else if (scores[prev]<scores[next])maxx=next;
needs to be
else if (scores[maxx]<scores[next])maxx=next;
// ^^^^
You are missing a return in the recursive call. Instead of
else maxi(names,sizee,prev+1,next+1,scores,maxx);
it needs to be
else
return maxi(names,sizee,prev+1,next+1,scores,maxx);
Also, the function can be simplified.
The argument name is not used at all. It can be removed.
The argument prev can be removed too.
Couple of the checks you have can be combined into one.
You don't need a chain of if-else-else statements.
Here's a simplified version.
int maxi(int sizee, int next, int scores[], int maxx)
{
if ( sizee == next )
return maxx;
if (scores[maxx] < scores[next])
maxx=next;
return maxi(sizee, next+1, scores, maxx);
}
More importantly, it will be better to have an overload of the function:
int maxi(int sizee, int scores[]);
That should be the user facing function. The implementation of the user facing function can use the recursive function as an implementation detail.
int maxi(int sizee, int scores[])
{
return maxi(sizee, 0, scores, 0);
}
See it working at http://ideone.com/chvtPA.
Below could be a better approach:
Go through each element of the array, till there are elements left in the array which will be the base case.
Then in each function call check whether element at current index is greater than the element found at maxIndex if so update the max index and check for next array element by calling function again and so on.
Please find code below for both finding max element and max index recursively:
#include <iostream>
using namespace std;
int findMax(int arr[], int size,int index, int max);
int findMaxIndex(int arr[], int size,int index, int maxIndex);
int main()
{
int arr[] = {5,2,8,1,4};
int len = sizeof(arr) / sizeof(int);
cout << "Max is: " << findMax(arr, len, 0, arr[0]) << endl;
cout << "Max Index is: " << findMaxIndex(arr, len, 0, 0) << endl;
return 0;
}
int findMax(int arr[], int size, int index, int max)
{
if (index == size)
return max;
if (arr[index] > max)
max = arr[index];
return findMax(arr, size, index + 1, max);
}
int findMaxIndex(int arr[], int size, int index, int maxIndex)
{
if (index == size)
return maxIndex;
if (arr[index] > arr[maxIndex])
maxIndex = index;
return findMaxIndex(arr, size, index + 1, maxIndex);
}
You need to compare scores[maxx] with scores[next], aslo you dont need prev
Change your function to
int maxi(string names[],int sizee,int next,int scores[],int maxx)
{
if (sizee ==1)
return 0;
if (scores[maxx]<scores[next])
maxx=next;
if ((next+1)==sizee)
return maxx;
return maxi(names,sizee,next+1,scores,maxx);
//You need to return, else the function will be called but that
// value wont be returned.
}
Related
I'm testing a recursive function that returns the number of occurrence of a given number in an array. I get an unexpected result when I run the code.
#include <iostream.h>
int Occurence(int A[], int size, int n)
{
static int occur=0;
if(size == 0)
{
int occur2 = (int) occur;
return occur2;
}
else
{
if ( n == A[size-1])
occur++;
Occurence(A, size-1, n);
}
}
int main()
{
int A[] = {1,3,2,5,1,2, 3, 7,7, 8,8, 4, 6, 9,9, 0};
int size = sizeof(A)/sizeof(A[0]);
int n;
cout<< "Enter Number to Find : ";
cin >>n;
cout<<endl;
cout<<"Number of Occurence of "<< n << " is :"<< Occurence(A, size, n)<<endl;
return 0;
}
You are missing a return at the end of your function. If size is not 0 then the behaviour of your function is undefined. Adding the return should make it work:
int Occurence(int A[], int size, int n)
{
static int occur=0;
if(size == 0)
{
int occur2 = (int) occur;
return occur2;
}
else
{
if ( n == A[size-1])
occur++;
return Occurence(A, size-1, n);
}
}
Recursion is a very strange way to implement this problem so I assume this is some toy example to demonstrate how recursion works. Even if this is the case you really shouldn't be using a static variable in your implementation. Just make each call return the current sum instead:
int Occurence(int A[], int size, int n)
{
if(size == 0)
{
return 0;
}
else
{
return (n == A[size-1] ? 1 : 0) + Occurence(A, size-1, n);
}
}
This version will return the correct result when called multiple times whereas your original would add to the previous count each time.
In real code simply do:
#include <algorithm>
int Occurence(int A[], int size, int n)
{
return std::count(A, A+size, n);
}
There are some compilation problems in your code. First of all, in C++, the standard library files usually don't have an extension in the filename. So, including <iostream.h> is wrong. You should include <iostream>.
Other problem with your code is that you are using cout and cin without specifying their namespaces. So, instead of using cout and cin directly, use std::cout and std::cin or declare use namespace std after your includes.
EDIT: as Thomas Matthews pointed out, prefer using std::cout and std::cin over using namespace std.
#include <iostream>
#include <cstdlib>
using std:: cin;
using std:: cout;
using std:: endl;
const int N=10;
void readarray(int array[], int N);
int bubble_sort (int array[], int size, int round,
int place);
int main ()
{
int array[N];
readarray( array, N );
int round, place;
cout << bubble_sort(array, N, place, round);
return EXIT_SUCCESS;
}
void readarray(int array[], int N)
{
int i=0;
if (i < N)
{
cin >> array[i];
readarray(array+1, N-1);
}
}
int bubble_sort (int array[], int size, int round,
int place)
{
round =0;
place =0;
if (round < N-1) // this goes over the array again making sure it has
// sorted from lowest to highest
{
if (place < N - round -1) // this sorts the array only 2 cells at a
// time
if (array[0] > array[1])
{
int temp = array[1];
array[1]=array[0];
array[0]=temp;
return (array+1, size-1, place+1, round);
}
return (array+1, size-1, place, round+1);
}
}
I know how to do a bubble sort using two for loops and I want to do it using recursion. Using loops you require two for loops and I figured for recursion it might also need two recursive functions/calls. This is what I have so far. The problem is that its outputting only one number, which is either 1 or 0. I'm not sure if my returns are correct.
In c++11, you can do this:
#include <iostream>
#include <vector>
void swap(std::vector<int &numbers, size_t i, size_t j)
{
int t = numbers[i];
numbers[i] = numbers[j];
numbers[j] = t;
}
bool bubble_once(std::vector<int> &numbers, size_t at)
{
if (at >= numbers.size() - 1)
return false;
bool bubbled = numbers[at] > numbers[at+1];
if (bubbled)
swap(numbers, at, at+1);
return bubbled or bubble_once(numbers, at + 1);
}
void bubble_sort(std::vector<int> &numbers)
{
if ( bubble_once(numbers, 0) )
bubble_sort(numbers);
}
int main() {
std::vector<int> numbers = {1,4,3,6,2,3,7,8,3};
bubble_sort(numbers);
for (size_t i=0; i != numbers.size(); ++i)
std::cout << numbers[i] << ' ';
}
In general you can replace each loop by a recursive function which:
check the guard -> if fail return.
else execute body
recursively call function, typically with an incremented counter or something.
However, to prevent a(n actual) stack overflow, avoiding recursion where loops are equally adequate is good practice. Moreover, a loop has a very canonical form and hence is easy to read for many programmers, whereas recursion can be done in many, and hence is harder to read, test and verify. Oh, and recursion is typically slower as it needs to create a new stackframe (citation needed, not too sure).
EDIT
Using a plain array:
#include <iostream>
#include <vector>
#define N 10
void swap(int *numbers, size_t i, size_t j)
{
int t = numbers[i];
numbers[i] = numbers[j];
numbers[j] = t;
}
bool bubble_once(int *numbers, size_t at)
{
if (at >= N - 1)
return false;
bool bubbled = numbers[at] > numbers[at+1];
if (bubbled)
swap(numbers, at, at+1);
return bubbled or bubble_once(numbers, at + 1);
}
void bubble_sort(int *numbers)
{
if ( bubble_once(numbers, 0) )
bubble_sort(numbers);
}
int main() {
int numbers[N] = {1,4,3,6,2,3,7,8,3,5};
bubble_sort(numbers);
for (size_t i=0; i != N; ++i)
std::cout << numbers[i] << ' ';
}
Please read this post
function pass(i,j,n,arr)
{
if(arr[i]>arr(j))
swap(arr[i],arr[j]);
if(j==n)
{
j=0;
i=i+1;
}
if(i==n+1)
return arr;
return pass(i,j+1,n,arr);
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I've been learning c++ recently (coming from java) and I am attempting to count the number of repeating values in an array. For some reason the array is not being properly passed to my counter function.
#include <iostream>
#include <time.h>
using namespace std;
//quicksort for int arrays, left should be left index (0), right is right index(last one)
void quSort(int input[], int left, int right);
//binary search will return the index of the target or -1 if not found
int biSearch(int input[], int target, int iLeft, int iRight);
//count reapeats in the array with biSearch
int countRepeats(int input[], int target);
int main()
{
srand((unsigned int) time(0));
int test[1000];
//generate 100 random numbers under 1000
for(int i = 0; i < 1000; i++)
test[i] = rand()%1000;
//output test original
cout << "orig: ";
for(int i = 0; i < sizeof(test)/sizeof(*test); i++)
{
cout << test[i] << " ";
}
cout << endl << endl;
//sorting
quSort(test,0,( (sizeof(test)/sizeof(*test))-1));
cout << "sorted: ";
for(int i = 0; i < sizeof(test)/sizeof(*test); i++)
{
cout << test[i] << " ";
}
//binary search test
int target;
int iTarget;
cout << "\nenter target: ";
cin >> target;
iTarget = biSearch(test,target,0,sizeof(test)/sizeof(*test));
cout << "\n the target is at index: " << iTarget << " :: test[" << iTarget << "] = " << test[iTarget];
//count repeats
cout << "\nWith " << countRepeats(test,target) << " repeats";
system("pause");
return 0;
}
//quicksort function; effiecent array sorter; important for furture array analysis!!!
void quSort(int input[], int left, int right)
{
int pivot = input[(left+right)/2];
int l = left;//to control loop
int r = right;
while(l <= r)//will get smaller over iterations
{
int placeHold;// for use in swap, temp number
//finds value higher than the pivot from left
while(input[l] < pivot)
l++;
//find value lower than pivot on right
while(input[r] > pivot)
r--;
//swapper
if(l <= r)
{
//if the value greater than pivot is to the left of the value
//lessser than pivot
placeHold = input[l];
input[l] = input[r];
input[r] = placeHold;
l++;
r--;
}
//recursion to sort whole array until l=r
if(left<r)
quSort(input, left, r);
if(l < right)
quSort(input, l , right);
}
}
//binary search function; array MUST be sorted
int biSearch(int input[], int target, int iLeft, int iRight)
{
if(iLeft > iRight)
return -1;
else
{
int iMid = ((iLeft+iRight)/2);
if(input[iMid] > target)
return biSearch(input, target, iLeft, iMid-1);
else if(input[iMid] < target)
return biSearch(input, target, iMid+1, iRight);
else
return iMid;//target found
}
}
//Must be sorted
int countRepeats(int *input, int target)
{
int holder[sizeof(input)/sizeof(*input)];
int biSResult;
int counter = 0;
biSResult = biSearch(input,target,0,sizeof(input)/sizeof(*input));
//bug test
cout<<"c++" << biSResult << "c++";
//
while(biSResult != -1)
{
holder[biSResult] = target;
counter++;
input[biSResult] = 0;
quSort(input,0,( (sizeof(input)/sizeof(*input))-1));
biSResult = biSearch(input,target,0,sizeof(input)/sizeof(*input));
}
biSResult = biSearch(holder,target,0,sizeof(holder)/sizeof(*holder));
while(biSResult != -1)
{
input[biSResult] = target;
holder[biSResult] = 0;
quSort(holder,0,( (sizeof(holder)/sizeof(*holder))-1));
biSResult = biSearch(input,target,0,sizeof(holder)/sizeof(*holder));
}
return counter;
}
If anyone knows why this is happening it would be a great help
There are several issues in countRepeats():
(1) as already mentionned in other answers, there is an error in the way parameters are passed. There is no way to calculate the size of the array in the function whether you use int* or int[]. So best pass arguments to this function as you do in quSort() by giving not only the array address but also a start and an end counter.
(2) your programme will crash if the user would asks for a target of 0 : your while(biSResult != -1) would loop for ever.
(3) this function sorts again and again the array. This seems to be pretty bad for performance. Why don't you make use of the fact that the array is already sorted ? You could start counting from the found index . Just think that you'd have to count before and after this position, because you're not sure that iTarget is the very first occurence. This could look like:
int countRepeats(int input[], int pos, int start, int end )
{
if (pos<start || pos>=end) // you never know !
return 0;
int counter = 1;
for (int i=pos-1; i>=start && input[i]==input[pos]; i--)
counter++;
for (int i=pos+1; i<end && input[i]==input[pos]; i++)
counter++;
return counter;
}
By the way, I've tested it and it works. You just have to adapt the prototype and call it in your main function with
cout << "\nWith " << countRepeats(test, iTarget, 0,
sizeof(test)/sizeof(*test) ) << " repeats";
The first parameter of function countRepeats declared as
int countRepeats(int *input, int target)
that is it has type int *
So
sizeof(input)/sizeof(*input)
is equivalent to
sizeof( int * )/sizeof( int )
If for example sizeof( int * ) is equal to 4 and sizeof( int ) also is equal to 4 then the expression will be equal to 1. That is the value of the expression does not depend on how many elements the array that was passed to the function as argument has.
You should pass the size of the array explicitly as an argument of the function. So th function should be declared as
int countRepeats(int *input, int n, int target);
Or you could declare the first parameter of the function as a reference to array.
You can't calculate the size of an array inside a function that received a pointer to the array. This is because the value of sizeof(input) inside your counting function is just going to return the size of a pointer to an int. So sizeof(input)/sizeof(*input) will always be 1.
If you instead calculate the size of the array and store it as an int in main, then pass that to your counting function it should work. So changing your counting function call to:
cout << "\nWith " << countRepeats(test,target,sizeof(test)/sizeof(*test)) << " repeats";
And your countRepeats declaration to:
int countRepeats(int input[], int target, int size);
Then inside your countRepeats definition, everywhere you had (sizeof(input)/sizeof(*input)) you can just say size:
int countRepeats(int *input, int target, int size)
{
int holder[size];
int biSResult;
int counter = 0;
biSResult = biSearch(input,target,0,size);
//bug test
cout<<"c++" << biSResult << "c++";
//
while(biSResult != -1)
{
holder[biSResult] = target;
counter++;
input[biSResult] = 0;
quSort(input,0,(size-1));
biSResult = biSearch(input,target,0,size);
}
biSResult = biSearch(holder,target,0,size);
while(biSResult != -1)
{
input[biSResult] = target;
holder[biSResult] = 0;
quSort(holder,0,(size-1));
biSResult = biSearch(input,target,0,size);
}
return counter;
}
But you should really just use std::vector instead. Could have had std::vector<int> test (1000); and since your countRepeats changes your array through calls to quSort you can pass the vector as a reference (just as efficient as passing a pointer, allows changes to affect the original): int countRepeats(std::vector<int>&, int target); and you can always find its size by test.size()
I need to write a program that takes a given array and then splits it into two separate arrays with one array's elements being the positive elements of the main array and the other's elements being the negative elements of the main array.
After doing my best with the code, I got about a million lines of errors when trying to compile it. Is there a problem with how I am deleting the three dynamically allocated arrays? What huge error is preventing compiling?
Here is my code:
#include <iostream>
using namespace std;
void count(int ARRAY[], int SIZE, int& NEG, int& POS);
void split(int ARRAY[], int SIZE, int& NEG_ARRAY, int NEG, int& POS_ARRAY, int POS);
void print_array(int ARRAY[], int SIZE);
int main()
{
int SIZE(0);
int* ARRAY;
cout << "Enter number of elements: ";
cin >> SIZE ;
ARRAY = new int[SIZE];
int x(0);
int numEle(0);
cout << "Enter list: " << endl;
while (numEle < SIZE)
{
ARRAY[numEle] = x;
numEle++;
cin >> x;
}
int POS(0), NEG(0);
count(ARRAY, SIZE, NEG, POS);
int* NEG_ARRAY;
NEG_ARRAY = new int[NEG];
int* POS_ARRAY;
POS_ARRAY = new int[POS];
split(ARRAY, SIZE, NEG_ARRAY, NEG, POS_ARRAY, POS);
cout << "Negative elements: " << endl;
cout << print_array(NEG_ARRAY, NEG) << endl;
cout << "Non-negative elements: " << endl;
cout << print_array(POS_ARRAY, POS) << endl;
delete [] ARRAY;
delete [] NEG_ARRAY;
delete [] POS_ARRAY;
return 0;
}
void count(int ARRAY[], int SIZE, int& NEG, int& POS)
{
for (int x=0; x < SIZE; x++)
{
if (ARRAY[x] >= 0)
{
POS = POS + 1;
}
if (ARRAY[x] < 0)
{
NEG = NEG + 1;
}
}
}
void split(int ARRAY[], int SIZE, int& NEG_ARRAY, int NEG, int& POS_ARRAY, int POS)
{
NEG = POS = 0;
for (int x = 0; x < SIZE; x++)
{
if (ARRAY[x] < 0)
{
NEG_ARRAY[NEG++] = ARRAY[x];
}
else
{
POS_ARRAY[POS++] = ARRAY[x];
}
}
}
void print_array(int ARRAY[], int SIZE)
{
for (int i = 0; i < SIZE; i++)
{
cout << ARRAY[i] << " ";
}
cout << endl;
}
The code is supposed to read in the array and display a new negative and a new positive array. Thanks in advance!
There is a bunch of errors in your code. The worst one is passing the arrays by references in the declaration and definition of the split function. Change both to void split(int ARRAY[], int SIZE, int *NEG_ARRAY, int NEG, int *POS_ARRAY, int POS);, and most of the errors will be gone.
The rest is from the two lines in which you print the array in your main:
cout<<print_array(NEG_ARRAY, NEG) <<endl;
You don't want to print the function, you want to use the function to print inside it (which you do correctly). You need to change the calls to simply:
print_array(NEG_ARRAY, NEG);
And that'll make your code compile.
Hovewer there's one more error, which will make the whole app work in an improper way. In the place you input the values, you need to get the input from cin before inputting it in the array. Like this:
while(numEle<SIZE) {
cin>>x;
ARRAY[numEle] = x ;
numEle++;
}
You have the following bugs:
void split(int ARRAY[], int SIZE, int&NEG_ARRAY, int NEG, int&POS_ARRAY, int POS);
change to :
void split(int ARRAY[], int SIZE, int*NEG_ARRAY, int NEG, int*POS_ARRAY, int POS);
also the :
void split(int ARRAY[], int SIZE, int&NEG_ARRAY, int NEG, int&POS_ARRAY, int POS){..}
change to :
void split(int ARRAY[], int SIZE, int*NEG_ARRAY, int NEG, int*POS_ARRAY, int POS){..}
and
cout<<print_array(NEG_ARRAY, NEG) <<endl
cout<<print_array(NEG_ARRAY, POS) <<endl;
to :
print_array(NEG_ARRAY, NEG);
print_array(NEG_ARRAY, POS);
After fixed these bugs, it can compile and run well.
First of all, using a std::vector is almost always nicer than using dynamically allocated C arrays. You don't get the horrible mixture of pointers and square bracket array access, and you don't need to pass round extra size variables.
Secondly, the standard library has some nice algorithms to help do what you want to do. Let's assume that you write the given numbers into a vector called vec. You can then use std::partition to move all the elements less than zero to the first half of the vector, and all the elements greater than or equal to zero to the second half, like so:
inline bool less_than_zero(int a)
{
return a < 0;
}
std::vector<int>::iterator midpoint = std::partition(vec.begin(),
vec.end(),
less_than_zero);
(There are other ways of specifying the predicate, but a simple function definition like this is easiest for demonstration purposes.)
The returned iterator points to the first item in the vector which is non-negative. So now you can easily copy the values into two new vectors:
std::vector<int> negative(vec.begin(), midpoint);
std::vector<int> positive(midpoint, vec.end());
And that's it!
#include <cstdio>
#include <ctime>
int populate_primes(int array[])
{
const int max = 1000000;
char numbers[max+1];
int count=1;
array[0]=2;
for(int i=max;i>0;i-=2)numbers[i]=0;
for(int i=max-1;i>0;i-=2)numbers[i]=1;
int i;
for(i=3;i*i<=max;i+=2){
if(numbers[i]){
for(int j=i*i;j<max+1;j+=i)numbers[j]=0; array[count++]=i;
}
}
int limit = max/2;
for(;i<limit;i++) if(numbers[i])array[count++]=i;
return count;
}
int factorize(int number,int array[])
{
int i=0,factor=1;
while(number>0){
if(number%array[i]==0){
factor++;
while(number%array[i]==0)number/=array[i];
}
i++;
}
printf("%d\n",factor);
return factor;
}
int main()
{
int primes[42000];
const int max = 1000000;
int factors[max+1];
clock_t start = clock();
int size = populate_primes(primes);
factorize(1000,primes);
printf("Execution time:\t%lf\n",(double)(clock()-start)/CLOCKS_PER_SEC);
return 0;
}
I am trying to find the no. of factors using simple algo. The populate primes part is running okay , but the factorize part does not execute and gives the floating point exception error.
Please see the code and tell my mistake.
In your factorize method you access array[0], because the initial value of i is 0.
This array is the primes array which is populated by populate_primes. But populates prime doesn't write to primes[0], since the initial value of count is 1.
Thus the first element is not initialized and you probably get a div by 0 error.
You need to pass the size which you got from populate to factorize.
factorize(int number, int array[], int size);
problem is your array[] is not fully loaded, it is loaded only till size variable. So you may want to check for that.
Also the logic inside factorize is wrong. You need to check (number > 1) rather than (number >0).
Try with the function below to see some problems:
#define MAX_PRIMES 42000
int factorize(int number,int array[])
{
int i=0,factor=1;
for (i=0; number>0 && i< MAX_PRIMES; i++){
if (array[i] == 0 || array[i] == 1) {
printf("Error: array[%d] = %d\n", i, array[i]);
} else {
if(number%array[i]==0){
factor++;
while(number%array[i]==0 && number>0) {
printf("%d %d\n", number, array[i]);
number/=array[i];
}
}
}
}
printf("%d\n",factor);
return factor;
}