I have hard time writing a method which returns a fibonacci series using recursion.
My iterative method is as follows:
public static string Fibonacci(int n)
{
if (n < 2)
return "1";
int[] numbers = new int[n];
numbers[0]=0;
numbers[1]=1;
for (int i = 2; i < n; i++)
{
numbers[i] = numbers[i - 1] + numbers[i - 2];
}
return string.Join(" ", numbers);
}
I want above method to be changed to recursive call but with same signature ie return type is string and it returns Fibonacci series e.g 0,1,1,2,3,5,8,13,21,34,55
I googled but everywhere I see its done using Console.WriteLine() i.e. values are printed to screen but not returned as string from function.
Thanks
There are, of course, many examples of Fibonacci algorithms on the web, recursive and otherwise. Naturally, the key to a recursive implementation is to take the results from the recursive call, combine that with the current result, and then return that to the caller.
So let's start with the basic Fibonacci idea, with a recursive method that just writes out the numbers as they are generated:
void Fibonacci(int iMinus2, int iMinus1, int count)
{
if (count == 0) return;
int current = iMinus2 + iMinus1;
Console.WriteLine(current);
Fibonacci(iMinus1, current, count - 1);
}
So then the question is, how do we adjust the above so that it returns a string instead of just writing out the numbers one at a time. Again, remember that the key is to always have a way to combine the current result with the combined result of the previous calls. In this case, that means we want to convert the current number to a string, and prepend that string to the string returned by the recursive call (which is all the numbers after the current number:
string Fibonacci(int iMinus2, int iMinus1, int count)
{
if (count == 0) return null;
int current = iMinus2 + iMinus1;
string nextNumbers = Fibonacci(iMinus1, current, count - 1);
return nextNumbers != null ?
current.ToString() + ", " + nextNumbers : current.ToString();
}
Note: the above is a bit more complicated than I'd suggested, because it handles avoiding the addition of a comma when there are no more next numbers. There are other ways to implement this, but I prefer implementing recursive methods such that the terminating condition is handled by the callee rather than the caller.
I leave it as an exercise for the reader to deal with calling the above, and with how to deal with short sequences (i.e. the degenerate case where one is looking at only the first or first two numbers in the sequence). :)
Note: your question sounds a lot like a homework question. If so: these are appropriate on Stack Overflow, but I can't emphasize enough that Stack Overflow should not be considered a substitute for your teacher. We are happy to provide advice and help on homework questions, but it's important that you maintain a relationship with your teacher and seek advice from them so that they better understand where you are having trouble.
Related
I'm somewhat new to working with BigIntegers and have tried some stuff to get this system working, but feel a little stuck at the moment and would really appreciate a nudge in the right direction or a solution.
I'm currently working on a system which reduces BigInteger values down to a more readable form, and this is working fine with my current implementation, but I would like to further expand on it to get decimals implemented.
To better give a picture of what I'm attempting, I'll break it down.
In this context, we have a method which is taking a BigInteger, and returning it as a string:
public static string ShortenBigInt (BigInteger moneyValue)
With this in mind, when a number such as 10,000 is passed to this method, 10k will be returned. Same for 1,000,000 which will return 1M.
This is done by doing:
for(int i = 0; i < prefixes.Length; i++)
{
if(!(moneyValue >= BigInteger.Pow(10, 3*i)))
{
moneyValue = moneyValue / BigInteger.Pow(10, 3*(i-1));
return moneyValue + prefixes[i-1];
}
}
This system is working by grabbing a string from an array of prefixes and reducing numbers down to their simplest forms and combining the two and returning it when inside that prefix range.
So with that context, the question I have is:
How might I go about returning this in the same way, where passing 100,000 would return 100k, but also doing something like 1,111,111 would return 1.11M?
Currently, passing 1,111,111M returns 1M, but I would like that additional .11 tagged on. No more than 2 decimals.
My original thought was to convert the big integer into a string, then chunk out the first few characters into a new string and parse a decimal in there, but since prefixes don't change until values reach their 1000th mark, it's harder to tell when to place the decimal place.
My next thought was using BigInteger.Log to reduce the value down into a decimal friendly number and do a simple division to get the value in its decimal form, but doing this didn't seem to work with my implementation.
This system should work for the following prefixes, dynamically:
k, M, B, T, qd, Qn, sx, Sp,
O, N, de, Ud, DD, tdD, qdD, QnD,
sxD, SpD, OcD, NvD, Vgn, UVg, DVg,
TVg, qtV, QnV, SeV, SPG, OVG, NVG,
TGN, UTG, DTG, tsTG, qtTG, QnTG, ssTG,
SpTG, OcTG, NoTG, QdDR, uQDR, dQDR, tQDR,
qdQDR, QnQDR, sxQDR, SpQDR, OQDDr, NQDDr,
qQGNT, uQGNT, dQGNT, tQGNT, qdQGNT, QnQGNT,
sxQGNT, SpQGNT, OQQGNT, NQQGNT, SXGNTL
Would anyone happen to know how to do something like this? Any language is fine, C# is preferable, but I'm all good with translating. Thank you in advance!
formatting it manually could work a bit like this:
(prefixes as a string which is an char[])
public static string ShortenBigInt(BigInteger moneyValue)
{
string prefixes = " kMGTP";
double m2 = (double)moneyValue;
for (int i = 1; i < prefixes.Length; i++)
{
var step = Math.Pow(10, 3 * i);
if (m2 / step < 1000)
{
return String.Format("{0:F2}", (m2/step)) + prefixes[i];
}
}
return "err";
}
Although Falco's answer does work, it doesn't work for what was requested. This was the solution I was looking for and received some help from a friend on it. This solution will go until there are no more prefixes left in your string array of prefixes. If you do run out of bounds, the exception will be thrown and handled by returning "Infinity".
This solution is better due to the fact there is no crunch down to doubles/decimals within this process. This solution does not have a number cap, only limit is the amount of prefixes you make/provide.
public static string ShortenBigInt(BigInteger moneyValue)
{
if (moneyValue < 1000)
return "" + moneyValue;
try
{
string moneyAsString = moneyValue.ToString();
string prefix = prefixes[(moneyAsString.Length - 1) / 3];
BigInteger chopAmmount = (moneyAsString.Length - 1) % 3 + 1;
int insertPoint = (int)chopAmmount;
chopAmmount += 2;
moneyAsString = moneyAsString.Remove(Math.Min(moneyAsString.Length - 1, (int)chopAmmount));
moneyAsString = moneyAsString.Insert(insertPoint, ".");
return moneyAsString + " " + prefix;
}
catch (Exception exceptionToBeThrown)
{
return "Infinity";
}
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I am trying to get numbers that sum up 28.(this is just an example, however the target number can be changed). The below piece of code take approximately 4-5 min. Is there a way to make it a little faster to get combinations of numbers that sum up to "28"
output example 0,0,0,0,1,1,1,2,2,3,3,3
private void Button1_Click(object sender, EventArgs e)
{
int up = 28;
int rows = 12;
int[] chosen = new int[rows + 1];
CalculateCombination(chosen, 0, rows, 0, up - 1);
}
public void CalculateCombination(int[] chosen, int index, int r, int start, int end)
{
if (index == r)
{
return;
}
for (int i = start; i <= end; i++)
{
chosen[index] = i;
CalculateCombination(chosen, index + 1, r, i, end);
if (chosen.Sum() + chosen.Length == 28)
{
var ch = string.Join(",", chosen.Take(chosen.Length - 1));
Debug.Write(ch);
Debug.WriteLine("\t");
}
}
return;
}
First off, I assume you are doing this for an assignment. You are required to cite sources that helped you rather than passing off my work as your own in an academic context, so make sure to document in your assignment where you got help from. Don't just copy a solution and claim it as your own.
UPDATE: I misunderstood the problem from the description; I understood the problem to be to find the monotone nondecreasing sequences of length 12 that sum to 28. The problem has been clarified by the original poster in a comment; the problem is to find all non-negative sequences of a given length, say, 12 that sum to a given value, say, 28. There are 1676056044 such sequences, and enumerating them all will take some time. The answer which follows is addressed to the problem as I originally understood it.
Yes, this problem can be solved much more efficiently and clearly than you're doing here. Let's break it down.
First off, every recursive problem has one or more base cases. These are the cases that are so simple that they cannot be reduced to a simpler problem. Let's make an entrypoint and then list the base cases. What do we want? We want all the sequences of a given length, in order from smallest to largest, such that the sequence sums to a particular value.
public static IEnumerable<IEnumerable<int>> SumsTo(int sum, int least, int length)
{
OK, what are the base cases?
If length is zero and sum is zero then the empty sequence is the only solution.
If length is zero and sum is non-zero then there is no solution.
We can easily implement these rules:
if (length == 0)
{
if (sum == 0)
yield return Enumerable.Empty<int>();
yield break;
}
All right, that deals with length being zero. What about length non-zero? Are there any base cases there? Yes. If least * length is greater than sum then there cannot be any solution.
if (least * length > sum)
yield break;
All right. We know that length is at least 1 and that there is definitely a solution. What are the solutions? Well, there has to be a first number in the sequence, and it can be any value between least and sum, so let's write a loop.
for (int current = least; current <= sum; current += 1)
{
What is the solution given current? It is current followed by a sequence of size length-1 where the smallest item is current or larger that sums to sum - current. But we can compute that recursively!
var head = Enumerable.Repeat(current, 1);
foreach(var tail in SumsTo(sum - current, current, length - 1))
yield return head.Concat(tail);
}
}
And we're done:
Console.WriteLine(SumsTo(28, 0, 12).Count());
Prints out 3036, as expected and takes a fraction of a second; there are 3036 ways to sum 12 numbers from 0 to 28 to 28.
EXERCISE: make a type Sum that is either (1) empty, or (2) an integer, called the head, followed by a Sum (either empty or made of only larger elements) called the tail. Rewrite the solution so that it returns IEnumerable<Sum> rather than IEnumerable<IEnumerable<int>>.
EXERCISE: Make your Sum type implement IEnumerable<int> correctly.
EXERCISE: We generate some sums over and over again; for example, of the 3036 solutions to the length is 12, sum is 28 problem, over 100 of them end with "5, 5" so we're allocating that object many times. Memoize your solution so that it returns the same Sum object when given the same arguments.
EXERCISE: Compute the approximate amount of computation you save with this memoized solution; contrast that with the amount of memory you use. Did memory usage go up or down? Did computation speed go up or down? What does this tell you about the efficiency of memoization for this problem? Can you propose a better memoization algorithm?
EXERCISE: I have a particular pattern for strings in mind; we'll call them frob strings. It goes like this: () is a frob string, and (XY) where X and Y are replaced with frob strings is a frob string. So for example (()()) is a frob string, as is (()(()())). Make a method static IEnumerable<string> AllFrob(int s) that gives all frob strings with s pairs of parentheses. So AllFrob(1) is just (). AllFrob(2) is empty; there are no frob strings with two pairs of parentheses. AllFrob(3) is (()()), AllFrob(4) is empty, AllFrob(5) is (()(()())) and ((()())()).
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
I create a random number and then I check if it exists in a database table. If it does, I generate another one and check again, so would the following work?
public int GenerateNumber()
{
Random r = new Random();
int num = r.Next(1000);
//Psuedo-code
if(num is in table)
GenerateNumber();
return num;
}
It seems based on the answers below that recursion should be avoided here and I should auto-increment the number, so would a good alternative be to either start the auto-increment at 1 and pad with 0's until is is 8 characters long or start at 10,000,000.
Also, what if the datatype has to be a varchar(8). How can I auto-increment a number, but store in it in a varchar(8)?
There are numerous problems with your approach here that have been addressed by others, so instead I'll answer a question you should have asked but didn't:
What are the characteristics that a problem must have in order to correctly use recursion?
You must not use recursion unless your solution exhibits all of the following characteristics:
There is a "trivial" version of the problem that can always be solved without recursion.
Every non-trivial problem can be reduced to one or more strictly smaller problems.
Repeatedly reducing a problem to a smaller problem eventually results in an attempt to solve a trivial problem, after a small number of steps, where by "small" we mean, say, a few hundred steps, not a few million. (This condition can be relaxed in "tail recursive" languages; C# is not a tail recusive language.)
The solutions to the smaller problems can always be efficiently combined into a solution to the larger problem.
Your sample code exhibits none of these characteristics; use of recursion requires that you exhibit all of these characteristics, so under no circumstances should you use recursion.
Let me give you an example of a problem that is well solved by recursion:
A tree is either empty or consists of a left and right sub-tree; the tree never contains loops. The height of an empty tree is zero; the height of a non-empty tree is the length of the longest path from the root to the "deepest" empty sub-tree. Write a method that determines the height of a tree, assuming that the height is less than 200.
This problem exhibits all the characteristics of a problem that can be solved with recursion, so we can do so. Every recursive program has the pattern:
Solve the trivial problem if you can.
Otherwise, split up the problem into smaller problems, solve them recursively, and compose the solutions.
So let's do that:
int Height(Tree tree)
{
// Trivial case:
if (tree.IsEmpty) return 0;
// Non-trivial case: reduce the problem to two smaller problems:
int leftHeight = Height(tree.Left);
int rightHeight = Height(tree.Right);
int height = Math.Max(leftHeight, rightHeight) + 1;
return height;
}
This is not a problem that needs to be solved by recursion. Not to mention the fact that if you have a fair few numbers in your database, and this loops lots of times, you'll quickly get a Stack overflow error. Why not change it to an iterative function:
public int GenerateNumber()
{
Random r = new Randon();
int num = r.Next(1000);
while(num is in database)
{
num = r.Next(1000);
}
return num;
}
A different approach, while I'm here
Why not implement some transitive difference between these values? I.e: The first number is one, then two etc. Then all you need to do is get the most recent entry, and add one to it. No need to consistently keep making database queries.
This could result in a very bad performance. Use, for ex, Guid, for this
var rand = Guid.NewGuid().ToString()
Not quite.
if (num is in table)
return GenerateNumber();
else
return num;
would work, but it's easier/safer to just loop:
int num;
do
{
num = r.Next(1000);
} while (num is in table);
return num;
No it won't. You need to get the number you get from calling GenerateNumber again.
public int GenerateNumber()
{
Random r = new Randon();
int num = r.Next(1000);
//Psuedo-code
if(num is in table)
num = GenerateNumber(); //num = added.
return num;
}
Now you don't need to recursively solve this, and in C# it isn't a good idea, because C# doesn't do tail optimization like other languages (it doesn't change a recursive call to an iterative one for you during compile time). This will work, but your doing extra work on the stack, and you could get a stack overflow error. However, since you asked, this is how you fix the code to work.
You can easily change it to not use recursion by doing:
while(num is in table){ //I always use brackets to be clear.
num = r.Next(1000);
}
Use iteration to avoid crashing with a StackOverFlow exception which will inevitably happen if your table is of sufficient size.
public int GenerateNumber()
{
bool match = false;
while (!match) {
Random r = new Randon();
int num = r.Next(1000);
//Psuedo-code
if(num is not in table)
//insert
}
return num;
}
You don't specify what your database is. If it is just a in memory list of used numbers your code can simply done like this:
private HashSet<int> _usedNumbers = new HashSet<int>();
Random r = new Random(); //Search "Random is not random" on SO to see why I moved this out here.
public int GenerateNumber()
{
int MaxNum = 1000;
int num = r.Next(MaxNum);
if(_usedNumbers.Count == MaxNum)
throw new Exception("I ran out of numbers :(");
while(_usedNumbers.Add(num) == false) //Add will return false if the number already was used.
{
num = r.Next(MaxNum );
}
return num;
}
How many parameters can you pass to a string.Format() method?
There must be some sort of theoretical or enforced limit on it. Is it based on the limits of the params[] type or the memory usage of the app that is using it or something else entirely?
OK, I emerge from hiding... I used the following program to verify what was going on and while Marc pointed out that a string like this "{0}{1}{2}...{2147483647}" would succeed the memory limit of 2 GiB before the argument list, my findings did't match yours. Thus the hard limit, of the number of parameters you can put in a string.Format method call has to be 107713904.
int i = 0;
long sum = 0;
while (sum < int.MaxValue)
{
var s = sizeof(char) * ("{" + i + "}").Length;
sum += s; // pseudo append
++i;
}
Console.WriteLine(i);
Console.ReadLine();
Love the discussion people!
Not as far as I know...
well, the theoretical limit would be the int32 limit for the array, but you'd hit the string length limit long before that, I guess...
Just don't go mad with it ;-p It may be better to write lots of small fragments to (for example) a file or response, than one huge hit.
edit - it looked like there was a limit in the IL (0xf4240), but apparently this isn't quite as it appears; I can make it get quite large (2^24) before I simply run out of system memory...
Update; it seems to me that the bounding point is the format string... those {1000001}{1000002} add up... a quick bit of math (below) shows that the maximum useful number of arguments we can use is 206,449,129:
long remaining = 2147483647;// max theoretical format arg length
long count = 10; // i.e. {0}-{9}
long len = 1;
int total = 0;
while (remaining >= 0) {
for(int i = 0 ; i < count && remaining >= 0; i++) {
total++;
remaining -= len + 2; // allow for {}
}
count *= 10;
len++;
}
Console.WriteLine(total - 1);
Expanding on Marc's detailed answer.
The only other limitation that is important is for the debugger. Once you pass a certain number of parameters directly to a function, the debugger becomes less functional in that method. I believe the limit is 64 parameters.
Note: This does not mean an array with 64 members, but 64 parameters passed directly to the function.
You might laugh and say "who would do this?" which is certainly a valid question. Yet LINQ makes this a lot easier than you think. Under the hood in LINQ the compiler generates a lot of code. It's possible that for a large generate SQL query where more than 64 fields are selected that you would hit this issue. Because the compiler under the hood would need to pass all of the fields to the constructor of an anonymous type.
Still a corner case.
Considering that both the limit of the Array class and the String class are the upper limit of Int32 (documented at 2,147,483,647 here: Int32 Structure), it is reasonable to believe that this value is the limit of the number string of format parameters.
Update Upon checking reflector, John is right. String.Format, using the Red Gate Reflector, shows the ff:
public static string Format(IFormatProvider provider, string format, params object[] args)
{
if ((format == null) || (args == null))
{
throw new ArgumentNullException((format == null) ? "format" : "args");
}
StringBuilder builder = new StringBuilder(format.Length + (args.Length * 8));
builder.AppendFormat(provider, format, args);
return builder.ToString();
}
The format.Length + (args.Length * 8) part of the code is enough to kill most of that number. Ergo, '2,147,483,647 = x + 8x' leaves us with x = 238,609,294 (theoretical).
It's far less than that of course; as the guys in the comments mentioned the string hitting the string length limit earlier is quite likely.
Maybe someone should just code this into a machine problem! :P
I have a decimal number (let's call it goal) and an array of other decimal numbers (let's call the array elements) and I need to find all the combinations of numbers from elements which sum to goal.
I have a preference for a solution in C# (.Net 2.0) but may the best algorithm win irrespective.
Your method signature might look something like:
public decimal[][] Solve(decimal goal, decimal[] elements)
Interesting answers. Thank you for the pointers to Wikipedia - whilst interesting - they don't actually solve the problem as stated as I was looking for exact matches - more of an accounting/book balancing problem than a traditional bin-packing / knapsack problem.
I have been following the development of stack overflow with interest and wondered how useful it would be. This problem came up at work and I wondered whether stack overflow could provide a ready-made answer (or a better answer) quicker than I could write it myself. Thanks also for the comments suggesting this be tagged homework - I guess that is reasonably accurate in light of the above.
For those who are interested, here is my solution which uses recursion (naturally) I also changed my mind about the method signature and went for List> rather than decimal[][] as the return type:
public class Solver {
private List<List<decimal>> mResults;
public List<List<decimal>> Solve(decimal goal, decimal[] elements) {
mResults = new List<List<decimal>>();
RecursiveSolve(goal, 0.0m,
new List<decimal>(), new List<decimal>(elements), 0);
return mResults;
}
private void RecursiveSolve(decimal goal, decimal currentSum,
List<decimal> included, List<decimal> notIncluded, int startIndex) {
for (int index = startIndex; index < notIncluded.Count; index++) {
decimal nextValue = notIncluded[index];
if (currentSum + nextValue == goal) {
List<decimal> newResult = new List<decimal>(included);
newResult.Add(nextValue);
mResults.Add(newResult);
}
else if (currentSum + nextValue < goal) {
List<decimal> nextIncluded = new List<decimal>(included);
nextIncluded.Add(nextValue);
List<decimal> nextNotIncluded = new List<decimal>(notIncluded);
nextNotIncluded.Remove(nextValue);
RecursiveSolve(goal, currentSum + nextValue,
nextIncluded, nextNotIncluded, startIndex++);
}
}
}
}
If you want an app to test this works, try this console app code:
class Program {
static void Main(string[] args) {
string input;
decimal goal;
decimal element;
do {
Console.WriteLine("Please enter the goal:");
input = Console.ReadLine();
}
while (!decimal.TryParse(input, out goal));
Console.WriteLine("Please enter the elements (separated by spaces)");
input = Console.ReadLine();
string[] elementsText = input.Split(' ');
List<decimal> elementsList = new List<decimal>();
foreach (string elementText in elementsText) {
if (decimal.TryParse(elementText, out element)) {
elementsList.Add(element);
}
}
Solver solver = new Solver();
List<List<decimal>> results = solver.Solve(goal, elementsList.ToArray());
foreach(List<decimal> result in results) {
foreach (decimal value in result) {
Console.Write("{0}\t", value);
}
Console.WriteLine();
}
Console.ReadLine();
}
}
I hope this helps someone else get their answer more quickly (whether for homework or otherwise).
Cheers...
The subset-sum problem, and the slightly more general knapsack problem, are solved with dynamic programming: brute-force enumeration of all combinations is not required. Consult Wikipedia or your favourite algorithms reference.
Although the problems are NP-complete, they are very "easy" NP-complete. The algorithmic complexity in the number of elements is low.
I think you've got a bin packing problem on your hands (which is NP-hard), so I think the only solution is going to be to try every possible combination until you find one that works.
Edit: As pointed out in a comment, you won't always have to try every combination for every set of numbers you come across. However, any method you come up with has worst-case-scenario sets of numbers where you will have to try every combination -- or at least a subset of combinations that grows exponentially with the size of the set.
Otherwise, it wouldn't be NP-hard.
You have described a knapsack problem, the only true solution is brute force. There are some approximation solutions which are faster, but they might not fit your needs.
While not solving the problem of brute force (as others already mentioned) you might want to sort your numbers first, and then go over the possible ones left (since once you passed Sum value, you can't add any number larger than Goal - Sum).
This will change the way you implement your algorithm (in order to sort only once and then skip marked elements), but on the average would improve performance.
public class Logic1 {
static int val = 121;
public static void main(String[] args)
{
f(new int[] {1,4,5,17,16,100,100}, 0, 0, "{");
}
static void f(int[] numbers, int index, int sum, String output)
{
System.out.println(output + " } = " + sum);
//System.out.println("Index value1 is "+index);
check (sum);
if (index == numbers.length)
{
System.out.println(output + " } = " + sum);
return;
}
// include numbers[index]
f(numbers, index + 1, sum + numbers[index], output + " " + numbers[index]);
check (sum);
//System.out.println("Index value2 is "+index);
// exclude numbers[index]
f(numbers, index + 1, sum, output);
check (sum);
}
static void check (int sum1)
{
if (sum1 == val)
System.exit(0);
}
}