I've searched extensively online but all solutions I've found use two parameters to keep track of the size of the area being used. This would be easy if I was allowed to do that, but I'm not. As you can see below, the code lacks a stop value, because I have no idea how to retain the original information.
This is the code on Wikipedia, you can see they use imin and imax for tracker variables: http://en.wikipedia.org/wiki/Binary_search_algorithm#Recursive
My (very incorrect) code is below. The mid variable doesn't mean anything, because I don't know how to set low and high correctly if I'm not allowed to have any extra arguments in the function.
public static int findRecursiveB( String s, char c)
{
int low = 0;
int high = s.length()-1;
int mid = (low+high)/2;
if (s.charAt(mid) < c) {
return findRecursiveB(s.substring(low, mid), c);
}
else if (s.charAt(mid) >= c) {
return findRecursiveB(s.substring(mid+1, high), c);
}
else return mid;
}
One crucial point here is what does the original String s contain? For this to work, it has to be a sorted String, meaning that the characters in the String must be in order. Specifically, it looks like you've written code that expects s to be sorted in reverse order. Otherwise, unless I'm totally missing something, your code does exactly what it is supposed to: no need to pass extra params because you are passing in the substring on each recursive call.
Otherwise, good job.
Related
I am trying to write a recursive method which gives me the biggest-sum-pairs of integer (neighbors) within an array. It works perfectly, but only for the first run, because i cannot reset my static int maxSum; "counter" which I use to check, if the current sum is bigger than the biggest sum of previous runs. maybe you can give me an hint, its the first time I work with static counters in a recursion
static int maxSum = 0;
private static int getMaxPairSum(int[] workArray, int start, int end) {
while(start < end){
if (workArray[start] + workArray[start+1] > maxSum){
maxSum = workArray[start] + workArray[start+1];
return getMaxPairSum(workArray,start +1,end);
}
else return getMaxPairSum(workArray,start +1,end);
}
return maxSum;
}
A very simple way to do this could be:
Creating a temporary variable
Assigning the value of maxSum to the variable
Resetting maxSum
Returning the temporary variable
Would be like this:
while(start < end){
if (workArray[start] + workArray[start+1] > maxSum){
maxSum = workArray[start] + workArray[start+1];
return getMaxPairSum(workArray,start +1,end);
}
else return getMaxPairSum(workArray,start +1,end);
}
int tempMaxSum = maxSum;
maxSum = 0;
return tempMaxSum;
Hope this helped!
Thank you for your help! I decided to write a new code, it works perfectly and is recursive :D
private static int getMaxPairSum(int[] workArray, int start, int end) {
if (start==end)
return 0;
return Math.max((workArray[start] + workArray[start+1]), getMaxPairSum(workArray,start+1,end));
I feel like you’re still thinking too much in an iterative programming mindset. In recursion, you shouldn’t really need a global variable to keep track of changes. Instead, the changes should instead propagate either up (still very iterative thinking) or down (proper recursion!) your recursion stack, with the operation (in this case a comparison) being performed at each function call in that stack.
It should be the case that transitivity of the greater than operator applies here, so the max will be the largest regardless of when in the list it happens, so it doesn’t really matter when we find it. Try to come up with some concrete examples and walk through a few iterations of your method if that seems unclear.
An example of it being passed up your recursion stack would be adding a new argument to your method, such as “maxSum” and passing that through to each call, keeping track of the max at each call. Returning from this would still feel a bit "off", though, as you'd have the value of your result once you reach the end of the list, but then would still need to return it through all the recursive calls you made to the method until it got back to the first call.
The “most recursive” approach, here, would be to let your method work with a value that hasn't been determined yet but that it knows will be determined in the future, and to do that until it reaches the end case. Once it reaches the end, it will have gotten a concrete value, which allows an undetermined value for the previous call to now be determined, which allows an undetermined value for the call before that to be determined, etc., until the first call.
Here, the comparison would be Math.max(currentSum, nextSum), where currentSum = workArray[i] + workArray[i+1] and nextSum is the value returned by the next call to getMaxPairSum, which won’t actually be determined until you get to the end of the array (your terminating case for the recursion) which will return a value to the call before it, which in returns a value to the call before it, which returns a value to the call before it, and so on until you get back to the first call and so have your final value.
For a visualization based in data structures, this means that the calculations will propagate down the recursive function call stack until the very first call, which is the bottommost item in the stack.
The task was to write a method to return the least value of an array.
Would someone quickly look over my code?
public static int findMinimum (int [] array) {
for (int kohlrabi = 0; kohlrabi < array.length; kohlrabi++) {
for (int zwiebel= 0; zwiebel < array.length; zwiebel ++) {
if (array [zwiebel] < array [kohlrabi]) {
kohlrabi = zwiebel -1;
break;
}
int spinat = array [kohlrabi];
if (zwiebel == array.length-1) {
return spinat;
}
}
}
}
Exception in thread "main" java.lang.Error: Unresolved compilation
problem: This method must return a result of type int
at Abgabe7.ArrayExercises.findMinimum(ArrayExercises.java:38)
It's a homework for my school and I definitely understood the logic behind it but cannot find my fault.
Thanks Max
I don't think you need to have two loops. One loop would work.
Simply loop though the array keeping a variable which is the lowest you've found.
You should declare a global variable before the loop then use only one for loop in your code as follows:
int zwiebel= 0;
for (int kohlrabi = 0; kohlrabi < array.length; kohlrabi++) {
if (kohlrabi == 0){
zwiebel = array[kohlrabi];
}
if (array[kohlrabi] < zwiebel) {
zwiebel = array[kohlrabi];
}
}
The lowest value in your array is now stored in the variable zwiebel.
The real mistake is that you are not taking the possibility of an empty array into account. One thing to learn in programming is to think of all possibilities (maybe you’ve discovered that already). An array in Java (and most other languages) can have length 0, that is, have no elements in it. When array.length is 0, your outer for loop doesn’t execute, so we get down to the bottom of the method without having returned anything and without having anything to return.
Java is dumb, but nevertheless smart enough to discover this problem for you. When your method is declared to return an int, it insists that it too can see that it will return an int in all cases. In your method it cannot, which is what the following message is trying to tell you:
This method must return a result of type int
One possible fix — and I may be showing you something that you haven’t learned in school yet — is to insert the following statement in the end of your method:
throw new IllegalArgumentException("Cannot find the minimum of an empty array");
Throwing an exception is an alternative to returning a value, so this statement will make Java happy. If you actually try to find the minimum of an empty array, your program will crash and give you the message “Cannot find the minimum of an empty array”. But finding the minimum of an array that has numbers in it should work now.
That said the others are correct: Your way of finding the minimum is overly complex. I have been staring at your code and still have not understood how it works. Such code is not good. In real life you will be writing code that others will need to read and change after you, and no one can change code they don’t understand, so your code would not be useful. More important than writing code that works correctly is writing readable code.
Edit: There are variations on how to do this in a simple way. For a school exercise using a for loop I would write:
public static int findMinimum (int [] array) {
if (array.length == 0) {
return 42; // or whichever value is desired in this case
}
int niedrichsteSoWeit = array[0];
for (int index = 1; index < array.length; index++) {
if (array[index] < niedrichsteSoWeit) {
niedrichsteSoWeit = array[index];
}
}
return niedrichsteSoWeit;
}
For production code I probably would not write a method but use the built-in functionality, for example:
IntStream.of(myIntArray)
.min()
.ifPresentOrElse(min -> {
// do something with min
}, () -> {
// do whatever you want to do when the array is empty
});
Don’t worry if you don’t understand a bit of this snippet. It’s mostly for more experienced programmers who might happen to read this answer.
I am trying to learn recursion in Java and have an array that takes in continuous input until the Scanner reads in a 0.
From there I have a method that (attempts) to calculate the number of positive integers in the array using recursion. This is the first recursive function I have ever written and I keep getting a stackoverflow error.
I have read tutorials and I still can't wrap my head around the basic understanding of recursion.
public class reuncF {
private static int start = 0;
private static int end = 98;
public static void main(String[] args) {
input = input.nextDouble();
list[i] = numInput;
computeSumPositive(numList, count);
}
}
return positives += solve(numbers, count++);
}
}
You forgot to stop your recursion!
There has to be some case where computeSumPositive returns without calling itself again. Otherwise it'll just keep going forever, never getting back to you.
If you did it with a loop, the loop would look like this:
int positives = 0;
for (int i = 0; i < numList.length; ++i) {
if (numList[i] > 0) {
positives++;
}
}
To do that recursively, you just find out what are the variables used in the loop. They are i, numList and positives.
computeSumPositive(int i, double[] numList, int positives)
Then we take a look at what the loop does. First, it checks whether we went too far,
so our recursive function should do that too. It'll have to return instead of just falling through like the loop does. And obviously, it must return the result:
{
if (! (i < numList.length))
return positives;
The loop then does the test and maybe increments positives, so the recursive function should also do that:
if (numList[i] > 0) {
positives++;
}
At the end of the loop, i is updated:
i++;
The loop just starts over, but the recursive function will have to call itself. Of course, we want it to use the new value of i and positives, but fortunately we updated those, so now we can just do:
return computeSumPositives (i, numList, positives);
}
The tricky bit is that the values i, numList, and are local to each call. Each invocation of computeSumPositives can see only the arguments it were given. If it changes them, none of the other invocation can see that change.
EDIT: So if we, for reasons we can only speculate about, wanted desperately for computeSumPositive to take only 2 parameters, we would have to "split up" positives across each invocation. Each invocation knows whether or not its number was positive or not; all we have to do is add them. Then it looks like this:
computeSumPositive(int i, double[] numList)
{
if (! (i < numList.length))
return 0; // I didn't find any at index i
if (numList[i] > 0) {
// Theres one I found + however many my later
// invocations will find.
return 1 + computeSumPositive (i+1, numList);
} else {
// I didn't find any, but my later invocations might.
return computeSumPositive (i+1, numList);
}
}
I find it helpful, when dealing with recursion, to figure out the termination case first.
It looks like you are treating 'count' as an index. So you could check if your at the last index in the array, if so and if the value is positive return a 1, if the value is non-positive return a 0 - dont recurse anymore.
If your not at the last index, and the value is positive return a 1 + the recursive function call, or if the value is non-positive just continue to recurse.
This will still cause a stack overflow for large arrays.
The value of count++ is the same as the value of count; the program uses the value and then increments it. But the result is that computeSumPositive keeps calling itself with the same value of count, which leads to infinite recursion. Note that each time computeSumPositive calls another computeSumPositive, each call has its own copy of the parameters (like count) and the local variables; so incrementing one computeSumPositive's copy of count has no effect on the value of count used by other recursive calls.
Change count++ to count + 1, and also add a way to halt the recursion. (At some point, you will be calling computeSumPositive to look at zero integers, and at that point, it should just return 0 and not call itself. You need to think about: how do you test whether you've reached that point?)
So, I have to make a random number generator to get numbers ranging from 0 to 400. I'm putting these into an array and then sorting them later on. I just am not sure how to go about doing this. I was given something along the lines of;
public int nextInt(400) //gives me errors
{
random.setSeed(12345L);
for (int i = 0; i < arr.size; i++)
{
val = random.nextInt(400);
a[i] = val;
}
}
I've already called the random class, since the directions indicated that. I just don't know why this is not working. It's giving me errors especially with the first part; class, interface, or enum expected. Could somebody steer me in the right direction please?
Functions in Java (all programming languages) have "variables" in their definition.
You've got:
public int nextInt(400)
Over here, you want your 400 to be a value that is passed to the function.
Think of this as math. I'm sure you've dealt with something like f(x) = 2 * x. Here, x is the variable, and you "evaluate" f(x) with a value for x. Similarly, in programming, we'd have something like :
public int nextInt(int x)
As you see, our function defines x to be of type int. This is necessary in a language like Java because you're telling the compiler that this function will only accept integers for x.
Now that you've done that, you can use x as a variable in the body of your function.
Note that whenever you use a variable, it first has to be defined. A line such as:
int variable;
defines variable as an int.
Your program is missing these for random, val, arr, and a. Note here that arr and a are arrays (and somehow I get the feeling that they should not be two separate variables).
You should really brush up on variables definitions, arrays, and functions before attempting this question. Your best resource would be your textbook, because it'll explain everything in an organized, step-by-step manner. You can also try the many tutorials that are available online. If you have specific questions, you can always come back to StackOverflow and I'm sure you'll find help here.
Good luck!
You need to define this function within a class definition
even you have specified :
public int nextInt(400)
in this line function returns int and in your whole body u didn't have any return statement.
and yes as Kshitij Mehata suggested dont use 400 directly as value use variable over there.
this should be your function:
public int[] nextInt(int x) //gives me errors
{
random.setSeed(12345L);
int[] a=new int[arr.size];
for (int i = 0; i < arr.size; i++)
{
val = random.nextInt(400);
a[i] = val;
}
return a;
}
even there is some issue with arr from where this arr come?
I have a function that is recursively calling itself, and i want to detect and terminate if goes into an infinite loop, i.e - getting called for the same problem again. What is the easiest way to do that?
EDIT: This is the function, and it will get called recursively with different values of x and y. i want to terminate if in a recursive call, the value of the pair (x,y) is repeated.
int fromPos(int [] arr, int x, int y)
One way is to pass a depth variable from one call to the next, incrementing it each time your function calls itself. Check that depth doesn't grow larger than some particular threshold. Example:
int fromPos(int [] arr, int x, int y)
{
return fromPos(arr, x, y, 0);
}
int fromPos(int [] arr, int x, int y, int depth)
{
assert(depth < 10000);
// Do stuff
if (condition)
return fromPos(arr, x+1, y+1, depth + 1);
else
return 0;
}
If the function is purely functional, i.e. it has no state or side effects, then you could keep a Set of the arguments (edit: seeing your edit, you would keep a Set of pairs of (x,y) ) that it has been called with, and every time just check if the current argument is in the set. That way, you can detect a cycle if you run into it pretty quickly. But if the argument space is big and it takes a long time to get to a repeat, you may run out of your memory before you detect a cycle. In general, of course, you can't do it because this is the halting problem.
You will need to find a work-around, because as you've asked it, there is no general solution. See the Halting problem for more info.
An easy way would be to implement one of the following:
Pass the previous value and the new value to the recursive call and make your first step a check to see if they're the same - this is possibly your recursive case.
Pass a variable to indicate the number of times the function has been called, and arbitrarily limit the number of times it can be called.
You can only detect the most trivial ones using program analysis. The best you can do is to add guards in your particular circumstance and pass a depth level context. It is nearly impossible to detect the general case and differentiate legitimate use of recursive algorithms.
You can either use overloading for a consistent signature (this is the better method), or you can use a static variable:
int someFunc(int foo)
{
static recursionDepth = 0;
recursionDepth++;
if (recursionDepth > 10000)
{
recurisonDepth = 0;
return -1;
}
if (foo < 1000)
someFunc(foo + 3);
recursionDepth = 0;
return foo;
}
John Kugelman's answer with overloading is better beacuse it's thread safe, while static variables are not.
Billy3
Looks like you might be working on a 2D array. If you've got an extra bit to spare in the values of the array, you can use it as a flag. Check it, and terminate the recursion if the flag has been set. Then set it before continuing on.
If you don't have a bit to spare in the values, you can always make it an array of objects instead.
If you want to keep your method signature, you could keep a couple of sets to record old values of x and y.
static Set<Integer> xs;
static Set<Integer> ys;//Initialize this!
static int n=0;//keeps the count function calls.
int fromPos(int [] arr, int x, int y){
int newX= getX(x);
int newY= getY(y);
n++;
if ((!xs.add(Integer.valueOf(newX)) && !ys.add(Integer.valueOf(newY))){
assert(n<threshold); //threshold defined elsewhere.
fromPos(arr,newx,newy);
}
}
IMHO Only loops can go into an infinite loop.
If your method has too many level of recursion the JVM will throw a StackOverflowError. You can trap this error with a try/catch block and do whatever you plan to do when this condition occurs.
A recursive function terminates in case a condition is fulfilled.
Examples:
The result of a function is 0 or is 1
The maximum number of calls is reached
The result is lower/greater than the input value
In your case the condition is ([x0,y0] == [xN,yN]) OR ([x1,y1] == [xN,yN]) OR ([xN-1,yN-1] == [xN,yN])
0, 1, ...N are the indexes of the pairs
Thus you need a container(vector, list, map) to store all previous pairs and compare them to the current pair.
First use mvn findbugs:gui to open a gui which point to the line where this error is present.
I also faced the same problem and I solved it by adding a boolean variable in the loop verification.
Code before ->
for (local = 0; local < heightOfDiv; local = local + 200) { // Line under Error
tileInfo = appender.append(tileInfo).append(local).toString();
while (true) {
try {
tileInfo = appender.append(tileInfo).append(getTheTextOfTheElement(getTheXpathOfTile(incr))).toString();
incr++;
} catch (Exception e) {
incr = 1;
tileInfo = appender.append(tileInfo).append("/n").toString();
}
}
To Solve this problem, I just added a boolean variable and set it to false in the catch block. Check it down
for (local = 0; local < heightOfDiv; local = local + 200) {
tileInfo = appender.append(tileInfo).append(local).toString();
boolean terminationStatus = true;
while (terminationStatus) {
try {
tileInfo = appender.append(tileInfo).append(getTheTextOfTheElement(getTheXpathOfTile(incr))).toString();
incr++;
} catch (Exception e) {
incr = 1;
tileInfo = appender.append(tileInfo).append("/n").toString();
terminationStatus = false;
}
}
This is how i Solved this problem.
Hope this will help. :)