So for one of my homework assignments we were asked to create a hailstonesequence and I'm completely stuck. I have a hard time figuring out how to break down segments of a function containing loops, and then trying to essentially translate it into a recursive function. Any help would be greatly appreciated. Down below I have the original for-loop function, and then the (Attempted) recursive function.
// startingValue function with For-Loop
// Takes in an int value n and returns the
// start value k from 1 to n, that has the longest length.
int startingValue (int n) {
int length = 0;
int k;
for ( int i = 1; i <= n; i++ ) {
int currentLength = largestHailstoneLength(i);
if (currentLength > length) {
length = currentLength;
k = i;
}
}
return k;
}
Here's my attempt for a recursive version of the function above:
int startingValue (int n) {
int length = 0;
int n = 0;
int currentLength = largestHailstoneLength(i);
if (currentLength < length) {
return 0;
} else {
length = currentLength;
n = i;
}
return (startingValue(i));
}
Here's something simple, and probably inefficient, that should get you started:
int startingValue(int n) {
if (n == 1) {
return n;
}
int m = startingValue(n - 1);
return largestHailstoneLength(n) > largestHailstoneLength(m) ? n : m;
}
I'm not going to do your homework, but I'll show you what a solution looks like in Ruby, a language that's about as readable as pseudo-code. Anything after a #
is a comment.
# Ruby equivalent to your C++ loop version
def start(n)
biggest = 0
k = -1
(1..n).each do |i| # loop from 1 to n, inclusive...
# don't have access to your largestHailstoneLength(i) function,
# so I'm using a random number on the range [0,1000)
current = rand(1000)
biggest, k = current, i if current > biggest
end
return k
end
# Using default argument values. Alternatively, you can build
# a single-argument front end function and a recursive back end
# with these args the state info.
def start_recursive(n, i = 1, biggest = 0, k = -1)
current = rand(1000) # same as above
biggest, k = current, i if current > biggest
return i < n ? start_recursive(n, i + 1, biggest, k) : k
end
srand 12345 # explicit seed to RNG for reproducibility of sequence
p start(1000) # => 301
srand 12345 # reseed RNG sequence to show recursive version yields same result
p start_recursive(1000) # => 301
After thinking about it a bit, and playing with larger ranges, I came up with the following variant which is much less likely to suffer from stack overflow—it uses a divide and conquer strategy to partition the range of candidates. I've also replaced the random number evaluation with a call to your largestHailstoneLength(i)
:
def start_recursive(upper_index, lower_index = 1)
return lower_index if lower_index >= upper_index
mid = (lower_index + upper_index) / 2
lower_max = start_recursive(mid, lower_index)
upper_max = start_recursive(upper_index, mid + 1)
if largestHailstoneLength(lower_max) < largestHailstoneLength(upper_max)
return upper_max
else
return lower_max
end
end
There are a few problems in your code
i
inside your recursive function If I got it right, startingValue()
should return a value to which largestHailstoneLength()
is the greatest possible.
So what we follow here is an induction principle:
n
values n
is 1
, i don't have to run any comparisons, just return n
. Otherwise
n
is the greatest, it should be greater than the greatest between 1
and n - 1
. 1
and n - 1
. n - 1
is the greatest, it should be greater than the greatest between 1
and n - 2
Well then, the fisrt thing to do is check for n
// Stop here, no need to go compare
if (n == 1) return n;
What we need to do inside the recursion is to compare the current n
with the greatest from 1
to n - 1
. that is:
// If current n is greater then the best case for n - 1
int k = startingValue(n - 1);
if (largestHailstoneLength(n) > largestHailstoneLength(k))
{
// n is greater
}
else // startingValue(n - 1) is greater
Knowing which is the greater one, we simply return it.
To understand things better, read a little bit more. You can begin here .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.