Having trouble with recursive methods in c# - c#

Having trouble with recursive methods in c#. When compiled it should just display the total sumUpToo of all number for the given int, i.e
- input 10
- output 55 (10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + 0)
Im not able to find any info anywhere so if someone has a link to a website that can teach me how to go through it, would be greatly appreciated.
class Program
{
static void Main(string[] args)
{
public static int sum(int x)
{
Console.WriteLine("num");
x = Console.ReadLine();
int sum = 0, i = 0;
for (i = 0; i <= x; i++)
{
sum = sum + i;
}
Console.WriteLine("{0}", sum);
}
public static int recursivesum(int x)
{
if (x <= 1)
Console.WriteLine("{0}", x);
else
(x + Recursivesum(x - 1));
}
edit * This is the adjustment seems to be working fine now, if im not mistaken. Thanks for all the help
class Program
{
static void Main(string[] args)
{
int x;
Console.Write("Please enter an integer value to sum up to: ");
x = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("The sum of all numbers up to and including {0} is {1}",x, recursivesum(x));
}
public static int sum(int x)
{
int sum = 0, i = 0;
for (i = 0; i <= x; i++)
{
sum = sum + i;
}
return sum;
}
public static int recursivesum(int x)
{
if (x <= 1)
return x;
else
return x + recursivesum(x-1);
}
}
}

Beginners often have trouble with recursive functions. Follow this pattern strictly and you will be less likely to go wrong:
ReturnType RecursiveFunction(ArgumentType argument)
{
if (the argument is such that the problem can be trivially solved)
return the trivial solution;
// The problem could not be trivially solved.
// Break it down into one or more smaller problems.
ArgumentType smallerProblemArgument = whatever;
ReturnType smallerProblemSolution = RecursiveFunction(smallerProblemArgument);
// We have solved the smaller problem.
ReturnType bigProblemSolution = ...
// ... use the smaller problem solution to solve the bigger problem...
return bigProblemSolution;
}
So in your case:
public static int SumOfFirstNIntegers(int n)
{
if (n <= 0) // trivial case
return 0;
// We have a harder problem to solve. Make the problem simpler:
int smallerProblem = n-1;
int smallerSolution = SumOfFirstNIntegers(smallerProblem);
// We have solved the smaller problem. Use it to solve the big problem.
int bigSolution = smallerSolution + n;
return bigSolution;
}

A recursive function is a function that calls it self. You need a base case that will exit the function and a recursive case where the function calls itself with modified parameters. Your function should look something like this:
public static int recursivesum(int x)
{
if (x <= 1)
return x; // this is the base case
else
return x + recursivesum(x-1);
}
So to use this function, you simple call it like this:
recursivesum(10);
If you follow the logic of the function you will see this will return 10 + recursivesum(9). recursivesum(9) will return 9 + recursivesum(8). So now we have 10 + 9 + recursivesum(8).
This will carry on until we reach the point where we have 10+9+8+7+6+5+4+3+2+recursivesum(1). Now if you look at the function again, recursivesum(1) doesn't call itself again. Instead it just returns x. So now the function will unwind and you'll get the result you expect.
One final note on recursion. Recursion can be a wonderful elegant way to implement some algorithms, but it has it's dangers. This site isn't called stack overflow for nothing!

Related

Fibonacci in recursive and normal fibonacci?

So I have made 2 versions of Fibonacci calculator, one is in normal way and one is in recursion.
public static int Fib(int n)
{
if (n == 0) { return 0; }
if(n == 1) { return 1; }
int a = 0;
int b = 1;
int res = 0;
for (int i = 0; i <= n-1; i++)
{
res = a + b;
a = b;
b = res;
}
return res;
}
public static int FibRec(int n)
{
if((n == 0) || (n == 1)) { return n; }
else
{
return FibRec(n-1) + FibRec(n-2);
}
}
When i run both the same time, the recursive version is incorrect.
static void Main()
{
Console.WriteLine(Fib(7)); //return 21
Console.WriteLine(FibRec(7)); //return 13
}
I tried to check for a correct version ones on the internet but strangely all the answer is quite the same as mine. I'm very weak at recursive and I absolutely have no idea what wrong with, so I'd be very grateful if any expert can point out the problem.
Your loop in Fib is incorrect in terms of the number of iterations - and this isn't helped by using non-descript names. FibRec is correct, contrary to your assertion in the question. Note that one way of determining that is to print out (say) the first 10 values of the sequence, which I'd expect to be 0, 1, 1, 2, 3, 5, 8, 13, 21, 34. That helps to find where the problem starts.
I would advice using current (as in, the current result) and next (the next number), and looping n times. That way you don't even need the base conditions, because it all just drops out. You also don't need to keep three variables outside the loop - you can just introduce a third variable inside the loop instead:
static int Fib(int n)
{
int current = 0;
int next = 1;
for (int i = 0; i < n; i++)
{
int tmp = current + next;
current = next;
next = tmp;
}
return current;
}
Note that deconstruction assignment in modern C# allows you to write it even more clearly, reassigning both current and next in a single statement, based on the previous values:
static int Fib(int n)
{
int current = 0;
int next = 1;
for (int i = 0; i < n; i++)
{
(current, next) = (next, current + next);
}
return current;
}
Your case base should return 1, not n
public static int FibRec(int n)
{
if((n == 0) || (n == 1)) { return 1; }
else
{
return FibRec(n-1) + FibRec(n-2);
}
}
When i run both the same time, the recursive version is incorrect.
Fibonacci(7) is 13, so your recursive FibRec method is correct.
I absolutely have no idea what wrong with
There is nothing wrong with it.
I'd be very grateful if any expert can point out the problem.
There is no problem.
There are only some possible stylistic improvements: you could protect against a caller passing a negative number as an argument and you could use a guard clause or a conditional expression.
If you change the condition to n <= 1 or n < 2, then FibRec will not run into an infinite loop if a caller passes a negative number. While that is an elegant way of solving the problem, FibRec will return a wrong result in that case. A better way would be to throw an appropriate Exception, in particular an ArgumentOutOfRangeException in that case:
if (n < 0)
throw new ArgumentOutOfRangeException(
nameof(n),
n,
"Argument must be non-negative."
);
Since throw terminates the method, there is no need for an else. The rest of the method will only be executed if the argument value is valid.
The same applies to return: if you return from the method, the rest of the method will not be executed, therefore, it is not necessary to wrap the rest of the method into an else branch:
public static int FibRec(int n)
{
if (n < 0)
throw new ArgumentOutOfRangeException(
nameof(n),
n,
"Argument must be non-negative."
);
if (n < 2) return n;
return FibRec(n-1) + FibRec(n-2);
}
This is sometimes called a guard clause.
Alternatively, you could use a conditional expression:
public static int FibRec(int n)
{
if (n < 0)
throw new ArgumentOutOfRangeException(
nameof(n),
n,
"Argument must be non-negative."
);
return n < 2 ? n : FibRec(n-1) + FibRec(n-2);
}
In your original version, where you had no error checking, you could then also use an expression-bodied method:
public static int FibRec(int n) =>
n < 2 ? n : FibRec(n-1) + FibRec(n-2);
But in this case, you lose the error checking.
See this .NET Fiddle with all the different variants.

problems with a for-loop in C#

I am very new to C# programming (2 days in so far), after learning intermediate python and doing a few small projects, I am trying to learn C#
But because me knowing python, I am finding C# a little confusing, arrays always throw me off, while in python initializing a list is as easy as declaring a variable with empty lists x = [], C#'s way of declaring arrays is confusing.
My issue is, I encountered an error, which I did google but found nothing (there was one question similar to mine but no one had answered on it)
I was on a site called https://codewars.com/ and was solving Katas (problems) [lvl 7 (beginner)]
The question stated that for any input integer n, I have to return an array with a factor of the number n where n > 1
In python, the code will be like this:
def findFactors(n):
return [x for x in range(2, n) if n % x == 0]
So I converted the code to the best of my abilities this:
public class Kata
{
public static int[] Divisors(int n)
{
int counter = 0;
int[] myNum = {};
for (int i=2; i == n; i++) {
int calculate = n % i;
if (calculate==0) {
myNum.CopyTo(i, counter);
counter++;
}
}
if (myNum.Length == 0) {
return null;
}
else {
return myNum;
}
}
}
The error I got was:
src/Solution.cs(10,20): error CS1503: Argument 1: cannot convert from 'int' to 'System.Array'
Compared to error tracebacks in python, C# Tracebacks are a little harder to comprehend
So how can I fix this error?
To fix your code you'd need to do this:
public static int[] Divisors(int n)
{
int[] myNum = { };
for (int i = 2; i < n; i++)
{
int calculate = n % i;
if (calculate == 0)
{
int[] x = new int[myNum.Length + 1];
myNum.CopyTo(x, 0);
x[x.Length - 1] = i;
myNum = x;
}
}
return myNum;
}
But the direct equivalent to your original code is this:
public static int[] Divisors(int n)
=> Enumerable.Range(2, n - 2).Where(x => n % x == 0).ToArray();
Or using an iterator:
public static IEnumerable<int> Divisors(int n)
{
for (int i = 2; i < n; i++)
{
if (n % i == 0)
{
yield return i;
}
}
}

c# need to find the sum of all ints from a loop

I'm kinda new to c# and I'm doing some projects on my own. In this project I need to find the values of the arithmetic a + (a + b) + (a + 2b) and so on. Then I need to add all the answers together. I have the first part done but I'm unsure how to add all the values I get from the loop.
class Program
{
static void Main(string[] args)
{
int a = 22;
int b = 8;
int answer;
Console.WriteLine(a);
for (int i = 1; i <= 43; i++)
{
answer = a + b * i;
Console.WriteLine(answer);
}
}
}
You need to accumulate the answer is some way. You can do that be defining another variable to hold the summation. If the loop is many iterations you may have to worry about overflow.
int total;
for (int i = 1; i <= 43; i++)
{
answer = a + b * i;
total += answer;
Console.WriteLine(answer);
}
Start with i=0
Use += operator for answer.
Consider Sum extension method from System.Linq
Using Linq you can use the Enumerable.Range() method to get a list of integers, then you can sum them.
var total = Enumerable.Range(1, 43).Sum();

Factorials and finding the even factorial of them

I'm trying to get my factorial program to work which takes a number from the user and calculates its even factorial. i.e 6! is 720 and its even factorial is 6x4x2 = 48 except I've figured out how to do the factorial part but whenever I try to add more code so I can try calculate the rest I get "Operator % cannot be applied to operands of type method group and int" or "Unexpected symbol { in class, struct, or interface member declaration" and I cant seem to see what I'm doing wrong. Any advice would be helpful
using System;
namespace Factorial
{
class Factorial
{
public static void Main()
{
Console.WriteLine("Enter a number");
int i =int.Parse(Console.ReadLine());
long fact = GetFactnum(i);
Console.WriteLine("{0} factorial is {1}", i, fact);
Console.ReadKey();
}
public static long GetFactnum(int i)
{
if (i == 0)
{
return 1;
}
return i * GetFactnum(i-1);
}
// public static void EvenFact()
// {
// int sumofnums =0;
// if((GetFactnum % 2) ==0)
// sumofnums += GetFactnum;
// }
}
}
This is one way of finding the factorial of odd numbers:
int number = int.Parse(Console.ReadLine());
Console.WriteLine("Vlera e variables m: {0} \n", number);
long factorial = 1;
int i = 1;
Console.WriteLine(" x f");
Console.WriteLine("---------------------------------");
while (i <= number)
{
factorial *= i;
if (i % 2 != 0)
{
Console.WriteLine(" {0} {1}", i, factorial);
}
i++;
}
Console.WriteLine("----------------------------------");
Edit
You had the basic idea but two things were incorrect.
First your GetFactnum % 2 part is incorrect syntax. You need to have the form int % int and you basically gave it a method group % int. Which is why you got the error message. So you have to use the result (or return value) of GetFactun(int i) instead of the method name itself, like so:
int result = GetFactnum(i);
if((result % 2) == 0)
or you could use the return value immediately:
if((GetFactnum(i) % 2) == 0)
Secondly, I think you want to first check if the value is even or odd. What happens if you pass in an odd value of i does it still compute the even factorial? Or does it throw an error?
The way i would code the method is very similar to what you did for GetFactnum(int i). But this time you check the input to see it it is odd or not. And secondly, if it is even, then you know that an even number minus 2 will equal another even number.
public static long GetEvenFactorial(int i) {
if((i % 2) != 0)
{
throw new ArgumentException("Input must be even!");
}
if (i <= 0)
{
return 1;
}
return i * GetEvenFactorial(i - 2);
}

Programmatically check if a number is a palindrome

This sounds like homework, yes it is (of someone else), I asked a friend of mine who is learning C# to lend me some of his class exercises to get the hang of it.
So as the title says: How can I check if a number is a Palindrome?
I'm not asking for source code (although its very useful), but rather that someone explained how should the code should work, so that it can be applied to many different languages.
The Solution:
#statikfx searched SO for this and found the solution.
n = num;
while (num > 0)
{
dig = num % 10;
rev = rev * 10 + dig;
num = num / 10;
}
// If (n == rev) then num is a palindrome
I check for palindromes by converting the integer to a string, then reversing the string, then comparing equality. This will be the best approach for you since you're just starting out.
Since you're working in C# and this is homework, I'll use very obscure-looking Python that won't help you:
def is_palindrome(i):
s = str(i)
return s[::-1] == s
Convert that to C# and you'll have your answer.
Main idea:
Input number: 12321
Splitting the digits of the number, put them into an array
=> array [1, 2, 3, 2, 1]
Check if array[x] = array[arr_length - x] for all x = 0..arr_length / 2
If check passed => palindrome
There are many ways. Probably the simplest is to have 2 indexes, i at beginning and j at end of number. You check to see if a[i] == a[j]. If so, increment i and decrement j. You stop when i > j. When looping if you ever reach a point where a[i] != a[j], then it's not a palindrome.
Here's some working code. The first function tests if a number is palidromic by converting it to a string then an IEnumerable and testing if it is equal to its reverse. This is enough to answer your question. The main function simply iterates over the integers testing them one by one.
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
public static bool IsPalindromic(long l)
{
IEnumerable<char> forwards = l.ToString().ToCharArray();
return forwards.SequenceEqual(forwards.Reverse());
}
public static void Main()
{
long n = 0;
while (true)
{
if (IsPalindromic(n))
Console.WriteLine("" + n);
n++;
}
}
}
Update: Here is a more direct method of generating palindromes. It doesn't test numbers individually, it just generates palindromes directly. It's not really useful for answering your homework, but perhaps you will find this interesting anyway:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
public static void Main()
{
bool oddLength = true;
ulong start = 1;
while (true)
{
for (ulong i = start; i < start * 10; ++i)
{
string forwards = i.ToString();
string reverse = new string(forwards.ToCharArray()
.Reverse()
.Skip(oddLength ? 1 : 0)
.ToArray());
Console.WriteLine(forwards + reverse);
}
oddLength = !oddLength;
if (oddLength)
start *= 10;
}
}
}
My solution:
bool IsPalindrome(string str)
{
if(str.Length == 1 || str.Length == 0) return true;
return str[0] == str[str.Length-1] && IsPalindrome(str.Substring(1,str.Length-2));
}
Here's some pseudocode:
function isPalindrome(number) returns boolean
index = 0
while number != 0
array[index] = number mod 10
number = number div 10
index = index + 1
startIndex = 0;
endIndex = index - 1
while startIndex > endIndex
if array[endIndex] != array[startIndex]
return false
endIndex = endIndex - 1
startIndex = startIndex + 1
return true
Note that that's for base 10. Change the two 10s in the first while loop for other bases.
The following function will work for both numbers as well as for strings.
public bool IsPalindrome(string stringToCheck)
{
char[] rev = stringToCheck.Reverse().ToArray();
return (stringToCheck.Equals(new string(rev), StringComparison.OrdinalIgnoreCase));
}
zamirsblog.blogspot.com
in theory you want to convert the number to a string. then convet the string to an array of characters and loop the array comparing character (i) with character (array length - i) if the two characters are not equal exit the loop and return false. if it makes it all the way through the loop it is a Palindrome.
Interesting. I'd probably convert the number to a string, and then write a recursive function to decide whether any given string is a palendrome.
int n = check_textbox.Text.Length;
int check = Convert.ToInt32(check_textbox.Text);
int m = 0;
double latest=0;
for (int i = n - 1; i>-1; i--)
{
double exp = Math.Pow(10, i);
double rem = check / exp;
string rem_s = rem.ToString().Substring(0, 1);
int ret_rem = Convert.ToInt32(rem_s);
double exp2 = Math.Pow(10, m);
double new_num = ret_rem * exp2;
m=m+1;
latest = latest + new_num;
double my_value = ret_rem * exp;
int myvalue_int = Convert.ToInt32(my_value);
check = check - myvalue_int;
}
int latest_int=Convert.ToInt32(latest);
if (latest_int == Convert.ToInt32(check_textbox.Text))
{
MessageBox.Show("The number is a Palindrome number","SUCCESS",MessageBoxButtons.OK,MessageBoxIcon.Information);
}
else
{
MessageBox.Show("The number is not a Palindrome number","FAILED",MessageBoxButtons.OK,MessageBoxIcon.Exclamation);
}
public class Main {
public static boolean Ispalindromic(String word) {
if (word.length() < 2) {
return true;
}
else if (word.charAt(0) != word.charAt(word.length() - 1)) {
return false;
} else {
Ispalindromic(word.substring(1, word.length() - 1));
}
return true;
}
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
String word = sc.nextLine();
System.out.println(Ispalindromic(word) ? "it is palidromic" : "it is not palidromic");
}
}
This is my solution coming from a beginner:
Console.Write("Enter a number to check if palindrome: ");
bool palindrome = true;
int x = int.Parse(Console.ReadLine());
/* c is x length minus 1 because when counting the strings
length it starts from 1 when it should start from 0*/
int c = x.ToString().Length - 1;
string b = x.ToString();
for (int i = 0; i < c; i++)
if (b[i] != b[c - i])
palindrome = false;
if (palindrome == true)
Console.Write("Yes");
else Console.Write("No");
Console.ReadKey();
You need to reverse the number then compare the result to the original number.
If it matches, you have a palindrome. It should work irrespective of the number being even, odd or symmetric.
public static bool IsNumberAPalindrome(long num)
{
return long.Parse(string.Join("", num.ToString().ToCharArray().Reverse().ToArray())) == num ? true : false;
}
The implementation is bellow:
public bool IsPalindrome(int x) {
string test = string.Empty;
string res = string.Empty;
test = x.ToString();
var reverse = test.Reverse();
foreach (var c in reverse)
{
res += c.ToString();
}
return test == res;
}
You have a string, it can have integers, it can have characters, does not matter.
You convert this string to an array, depending on what types of characters the strings consist of, this may use to toCharArray method or any other related method.
You then use the reverse method that .NET provides to reverse your array, now you have two arrays, the original one and the one you reversed.
You then use the comparison operator (NOT THE ASSIGNMENT OPERATOR!) to check if the reversed one is the same as the original.
something like this
bool IsPalindrome(int num)
{
var str = num.ToString();
var length = str.Length;
for (int i = 0, j = length - 1; length/2 > i; i++, j-- ){
if (str[i] != str[j])
return false;
}
return true;
}
you could even optimise it

Categories