I have learned recursion just recently and I was met with a question that I HAVE to approach it using recursion which says something like this, I need a function that takes an array and it's size using user input and checks if the array is ascending and if it is it returns 1 and if not it returns 0, now I know doing it without recursion is way easier but I had to do it with recursion, i tried different approaches to my base case and my if-else conditions and it didn't work out well I tried something like Array[Index] >= Array[Index-1] , and tried some other stuff alongside , but for some reason it just won't work and keeps giving me that it's descending
Here is what I tried: I have my main in which user inputs array and size(aka index here) and then calling this recursive function to try and see if it's ascending, now I assumed I'm starting from the most left of the array and go down gradually and check but it doesn't work, anyone got some tips on what's happening here?
int CheckIfAscending(int* Array, int Index)
{
if (Index < 0)
{
return 1;
}
if (Array[Index] > Array[Index - 1])
{
return CheckIfAscending(Array, Index - 1);
}
if (Array[Index] < Array[Index - 1])
{
return 0;
}
}
The most obvious vulnerability of your code is the lack of defined behaviour for arrays which can have the same value occur in two consecutive entries.
Because what do you return in case Array[Index] == Array[Index - 1]?
Your code does not specify, it does not have any return statement for that case.
You need to decide whether you want strictly ascending, i.e. two identical values are a failure, or only ascending, i.e. they are fine.
For strictly ascending do this
if (Array[Index] > Array[Index - 1])
{
return CheckIfAscending(Array, Index - 1);
} else
{
return 0;
}
otherwise use >=.
You also need to fix the first condition if (Index < 0), because for index 0 (actually size I think...) you need to already answer directly, otherwise Index - 1 is meaningless. So, use Index <= 0 instead.
Related
I am currently trying to solve this problem in Java, but I do not want to set myself onto a specific language since I think of this as a "general" problem.
The conditions for the function I am looking for are:
the only values that can be modified are the values inside the array to be iterated over. Thus, for example, you can not use other variables that store any kind of information, such as indices (which by the way also eliminates the possibility of looping through the array). This also applies to function parameters. The only argument that is passed to the function is the array itself.
additionally to the previous point: memory space must be consistent. Therefore, you cannot copy the current array onto a bigger/smaller array.
However:
the array is an integer array
the function might return an integer value
the elements inside the array might be changed, but only after they are iterated over
the array does not have to be iterated in any kind of order, but every element has to be "reached" exactly once.
there exists a function that returns the length of the array
the signature might look like this (again, no specific language, but since I am currently working in Java, the signature is in Java syntax):
int iterate(int[] integerArray)
Is it possible to write such a function?
One attempt of mine was to traverse the array from index 0 to length(array) - 1, storing the current index at array[0], and exit if array[0] (or array[prev]) is length(array) - 1. So, in order to get the next array element, I would do something like array[array[0]] and increment the counter in array[0]. The major problem with this is that I have to somehow catch the first function call to iterate() in order to initialize array[0] with 0.
This is not a variable but a parameter (the only thing we can work with, otherwise I don't see how it could work), here an example to find max:
function findMax(arr, index = 0, max = Number.MIN_VALUE) {
if (index < arr.length)
return findMax(arr, index + 1, arr[index] > max ? arr[index] : max)
return max
}
console.log(findMax([7,9,2,8,6]))
Or another example with modification, reverse array (without variable for the swap, alternatively you could just write a helper function to do the swapping):
function reverseArray(arr, index = 0, value = arr[0]) {
if (index < arr.length) {
reverseArray(arr, index + 1, arr[index + 1]) // iterate over the whole array
// any modification here will happen after the whole array was iterated
if (index < arr.length / 2) {
arr[index] = arr[arr.length - index - 1]
arr[arr.length - index - 1] = value
}
}
return arr
}
console.log(reverseArray([7,9,2,8,6]))
If you are using a language where you cannot specify predefined values, then you can just overload the method or create a helper, e.g. java:
public int findMax(int[] arr) {
findMax(arr, 0, arr[0]);
}
private int findMax(int[] arr, int i, int max) {
if (i < arr.length)
return findMax(arr, i + 1, arr[i] > max ? arr[i] : max);
return max;
}
We have to find mean median and mode for certain sets of observations we take last observation as -1 always and doesn't need to count it in the list
Sample input and ouput:
1 2 3 -1
2 2 -1(no mode)
My code
int mean,median,mode,i,sum=0,count=0,temp;
int obs[size];
for(i=0;i<size;i++)
{
scanf("%d",&obs[size] );
if(obs[size]==-1)
{
break;
}
sum=sum+obs[size];
count++;
}
mean=sum/count;
printf("%d",mean);
temp=count;
if(temp%2==0)
{
median=(obs[(temp)] /2 - obs[(temp - 1)/2])/2;
}
else
{
median=obs[(temp-1)/2];
}
printf("\t%d",median);
But here median condition doesn't work what's the problem?
Your problem is that your code doesn't find the median.
In fact, it finds nothing and will crash during runtime because the way you are reading inputs into your array causes an array index out of bound error.
Replace obs[size] with obs[i] in the loop where you are getting the inputs into your array.
I assume that you fill the array in ascending order while entering your observations, otherwise you have to sort the array before finding the median.
And I don't understand your need to introduce the temp variable. Use count and don't ruin the code readability. I think you have a false notion that operations on count will change its value; it won't unless you assign those values back to count.
You have declared median as of type int. Make it float for reasons you will find below.
Getting into your code for median,
if (count % 2 == 0)
{
// median=(obs[(count)] /2 - obs[(count - 1)/2])/2; --> Mistake
median = (obs[count / 2] - obs[(count / 2) - 1 ]) / 2;
// int median cannot handle this case because we divide two integers by 2
}
else
{
// median=obs[(count-1)/2]; --> Mistake
median = obs[(count / 2) + 1];
}
Be careful that you don't use count - 1 instead of count because you have incremented the value of count even while reading -1 into your obs. Since you have not posted that code for mode and if you think that that's not working as well then this might be the problem.
I want to remove a value from a array, at a set index.
this is the while loop i have
while (i < objects.length)
{
var index:int = get_index(objects[i]);
if (index != -1)
{
Quadtree_list[index].insert(objects[i]);
objects.slice(i, 1);
} else {
i++;
}
}
sooner or later i cannot get out the loop, so it crashes
but if i replace objects.slice with object.pop, it works (but its not removing the right index)
quick note objects.slice(i, 1) is not reducing the length of the array but objects.pop() is, how do i make .slice() reduce the size of the array?.
Array.slice(x,y) returns an Array containing the elements from index x to index y.
I believe what you're after is Array.splice(startIndex, deleteCount), this is a multi-purpose function. In your code objects.splice(i, 1);
Starting from index (startIndex)
Remove elements up to deleteCount (1)
return an Array containing removed elements
I am trying my best to get this code done. It's been well over 15 hours now at least over the course of a couple days, and I am still stuck. I am programming in C, and it is my first language, so I am a bit of a noob I'm sorry. Any kind of help would be very helpful.
A quick first question:
while (manStatus[i] == -1 || womanStatus[i] == -1)
What would be the proper syntax or way to say that I want to continuously check the elements of my array to see if any value inside there is "-1" (or in reality, that the men and women inside those arrays are single, so keep attempting to pair them).
I have more, but this one has stumped me for days. I'll keep struggling with the rest, but would love some help with this for starters if anyone has a moment.
In C one cannot simply expect manStatus[i] == -1 to check all the values within the array and return true if any value within matches -1.
Rather you need to write an algorithm which manually does the meticulous checking of each element in the array. It's actually very simple and uses a loop. I've implemented it here as a function:
bool checkArray(int array[],int arrayLength, int val)
{
int i;
for(i = 0; i < arrayLength; i++)
{
if(array[i] == val)
return true;
}
return false;
}
Now you can call this function in your statement:
while (checkArray(manStatus, LENGTH_OF_ARRAY, -1) || checkArray(womenStatus, LENGTH_OF_ARRAY, -1))
Well, there is lsearch that could be handy, but that is a non-standard function.
Define a helper function to check if a value is in an array.
int containsInt(int *array, size_t length, int value) {
size_t i;
for(i = 0; i < length; i++) {
if(array[i] == value) {
return 1;
}
}
return 0;
}
Then your check becomes,
while(!containsInt(manStatus, numMen, -1) && !containsInt(womanStatus, numWomen, -1))
If you want to check that any value in manStatus array is -1 you can do like this:
#define NON_WITH_MINUS_ONE 0
#define SOME_WITH_MINUS_ONE 1
int checkMarriage(int *manStatus,int N)
{
for(i=0;i<N;i++)
if(manStatus[i]==-1)
return SOME_WITH_MINUS_ONE
return NON_WITH_MINUS_ONE
}
where N is number of elements in the array. Then you can call this function e.g. by
if(checkMarriage(manStatus, 20)==1)
{//do something}
else
{ //do something else}
With the way you have done it, if you run out of either men or women before the other array has run out, then you are stuck in an infinite loop.
The best way to break out of the loop once there can be no more matches is:
while (manStatus[i] == -1` && `womanStatus[i] == -1)
Let me first answer on a math point of view. From my understanding, you have two finite sets (happily the number of human beings on earth is finite ... Hugh). The first one, which I will denote Sw is the set of women (ladies first guys !). The second is the men's one : Sm.
Now, you want to pair women from Sw with men from Sm. The cardinal number of each set is not guaranteed to be the same. I will denote them i = |Si|, where i ∈ {w, m}.
Suppose we have w > m (heh heh), then all you have to do is to choose a subset Sw,m of m women amongst the w that are in Sw (there are w! / ((w - m)!.m!) such subsets) and then set up a bijection between Sm and Sw,m. There are m! such bijections. Then you extend the bijection by setting the other women to the single status (which is -1 if I got it right).
From now on, you have two possibilities :
Generate one such "extended bijection" p and bind man i with women p(i) (the leftover poor little women to status -1).
You are given the two sets partially "paired" and you want to pair remaining singles as much as possible.
Before I go further, can you tell me which approach is the one that interests you ?
I made this binary search using reiteration, however, when I get the answer (boolean), I seem to stumble in my way out of the reiteration and cant get the correct answer out of the function.
Can anybody help? Please comment on the code.
// binary search
bool
search(int value, int array[], int n)
{
// the array has more than 1 item
if (n > 1)
{
int m = (n/2);
// compares the middle point to the value
if (value == array [m])
return true;
// if the value given is lower than the middle point of the array
if (value < array [m])
{
int *new_array = malloc (m * sizeof(int));
// creating a new array with the lower half of the original one
memcpy(new_array, array, m * sizeof(int));
// recalling the function
search (value, new_array, m);
}
// if the value given is greater than the middle point of the array
else
{
int *new_array = malloc (m * sizeof(int));
// creating a new array with the upper half of the original one
memcpy(new_array, array + (m + 1), (m * sizeof(int)));
// recalling the function
search (value, new_array, m);
}
}
else if (n==1)
{
// comparing the one item array with the value
if (array[0] == value)
return true;
else
return false;
}
if (true)
return true;
else
return false;
}
You need to return the value of recursive searches.
return search (value, new_array, m);
Otherwise when you call search you are just throwing away the answer
You should return search(...);, and not only invoke the search() method - otherwise the return value is not bubbled up.
In addition, note that this algorithm is O(n) (linear in the size of the array) and is leaking memory and very inefficient, since you copy half of the array in each iteration.
Actually, It probably makes the algorithm much slower then the naive linear search for an element.
A good binary search does not need to copy half of the array - it just "looks" at half of it. It can be achieved by sending array+m as the array (for the higher half), and only decreasing n is enough for the lower half.
As mentioned by amint copying the array completely defeats the purpose of doing a binary search. Second, I believe you mean recursion, not reiteration.
Things to think about: Instead of copying the array, think about how you could achieve the same result by passing in a set of indexes to the array (like beginning and end).
As to your actual question, how to return the boolean value through the recursion. The thing about returning values out of a recursive function is that each iteration has to pass along the value. You can think of it like a chain of responsibility delegation. The first call is like the head of the company. He doesn't do all of the work, so he delegates it to his assistant but he does one piece of the work first. Then the assistant has an assistant etc. Turtles all the way down ;)
In order to get a value back though, each person in the chain has to give it back to the person before them. Going back to programming, this means that every time you recursively call search, you need to return that value.
Lastly, once you have those things in order you need to get your base case better defined. I assume that's what you're trying to do with
if (true)
return true;
else
return false;
However, as pointed out by H2CO3, this doesn't make much sense. In fact, your previous if statement if (n == 1) ... should make sure that the code after that is never executed.