c# SIMPLE factorial program - c#

private void button1_Click(object sender, EventArgs e)
{
String UserNumber = this.textBox1.Text;
int NewUserNumber = Convert.ToInt32(UserNumber);
int result = 0;
int second = 0;
while (NewUserNumber >= 1)
{
result = NewUserNumber * (NewUserNumber - 1);
NewUserNumber--;
}
String i = Convert.ToString(result);
this.textBox2.Text = i;
}
}
While I understand this is homework for me, I am stuck. I really really don't want this solved, I want to do it myself.
I don't understand why it's not working.. It's outputting 2 no matter what I put in.
I could do this in Java easily but the converting gets to me..
Any help would be great.

Your problem is not in the conversion. Please look at
result = NewUserNumber * (NewUserNumber - 1);

while (NewUserNumber > 1)
{
result = result * NewUserNumber;
NewUserNumber--;
}

Initialize result as
int Result=1;
And write for loop as follows
while (NewUserNumber >= 1)
{
result = result * NewUserNumber;
NewUserNumber--;
}
OR
you can even use follwing
public int Factorial(int num)
{
if(num==1)
return 1;
return num * Factorial(num-1);
}

You need to look at your while loop structure and how you are setting the result value outside it and the multiplication
while (NewUserNumber >= 1)
{
result = NewUserNumber * (NewUserNumber - 1);
NewUserNumber--;
}
String i = Convert.ToString(result);
Also you have declared another int second = 0; - dont see why you are declaring that.

My advice is to try running over the code manually with different inputs.
You should run over the loop and try to figure what is the value of result and NewUserNumber is in each iteration.
Good luck...

You should try to run a debugger on your code then step through using the watch window. This is easy to do and will show you exactly what each value is at each point (you set break points). What IDE are you using?

int Factorial(int input)
{
int answer = 0;
if (input > 0)
{
count = 1;
while (count <= input)
{
if (count == 1)
{
answer= 1;
count++;
}
else
{
answer = count * answer;
count++;
}
}
}
else
{
MessageBox.Show("Please enter only a positive integer.");
}
return answer;
}

static void Main(string[] args)
{
int number, fact;
Console.WriteLine("enter the number for geting factorial");
number = Convert.ToInt32(Console.ReadLine());
fact = number;
for (int i = fact - 1; i > 0; i--)
{
fact = fact * i;
}
Console.WriteLine(fact);
Console.ReadLine();
}

Related

Nearest value from user input in an array C#

so in my application , I read some files into it and ask the user for a number , in these files there a lot of numbers and I am trying to find the nearest value when the number they enter is not in the file. So far I have as following
static int nearest(int close_num, int[] a)
{
foreach (int bob in a)
{
if ((close_num -= bob) <= 0)
return bob;
}
return -1;
}
Console.WriteLine("Enter a number to find out if is in the selected Net File: ");
int i3 = Convert.ToInt32(Console.ReadLine());
bool checker = false;
//Single nearest = 0;
//linear search#1
for (int i = 0; i < a.Length; i++)//looping through array
{
if(a[i] == i3)//checking to see the value is found in the array
{
Console.WriteLine("Value found and the position of it in the descending value of the selected Net File is: " + a[i]);
checker = true;
}
else
{
int found = nearest(i3,a);
Console.WriteLine("Cannot find this number in the Net File however here the closest number to that: " + found );
//Console.WriteLine("Cannot find this number in the Net File however here the closest number to that : " + nearest);
}
}
When a value that is in the file is entered the output is fine , but when it comes to the nearest value I cannot figure a way. I can't use this such as BinarySearchArray for this. a = the array whilst i3 is the value the user has entered. Would a binary search algorithm just be simpler for this?
Any help would be appreciated.
You need to make a pass over all the elements of the array, comparing each one in turn to find the smallest difference. At the same time, keep a note of the current nearest value.
There are many ways to do this; here's a fairly simple one:
static int nearest(int close_num, int[] a)
{
int result = -1;
long smallestDelta = long.MaxValue;
foreach (int bob in a)
{
long delta = (bob > close_num) ? (bob - close_num) : (close_num - bob);
if (delta < smallestDelta)
{
smallestDelta = delta;
result = bob;
}
}
return result;
}
Note that delta is calculated so that it is the absolute value of the difference.
Well, first we should define, what is nearest. Assuming that,
int nearest for given int number is the item of int[] a such that Math.Abs(nearest - number) is the smallest possible value
we can put it as
static int nearest(int number, int[] a)
{
long diff = -1;
int result = 0;
foreach (int item in a)
{
// actual = Math.Abs((long)item - number);
long actual = (long)item - number;
if (actual < 0)
actual = -actual;
// if item is the very first value or better than result
if (diff < 0 || actual < diff) {
result = item;
diff = actual;
}
}
return result;
}
The only tricky part is long for diff: it may appear that item - number exceeds int range (and will either have IntegerOverflow exceprion thrown or *invalid answer), e.g.
int[] a = new int[] {int.MaxValue, int.MaxValue - 1};
Console.Write(nearest(int.MinValue, a));
Note, that expected result is 2147483646, not 2147483647
what about LINQ ?
var nearestNumber = a.OrderBy(x => Math.Abs(x - i3)).First();
Just iterate through massive and find the minimal delta between close_num and array members
static int nearest(int close_num, int[] a)
{
// initialize as big number, 1000 just an example
int min_delta=1000;
int result=-1;
foreach (int bob in a)
{
if (Math.Abs(bob-close_num) <= min_delta)
{
min_delta = bob-close_num;
result = bob;
}
}
return result;
}

New to c#, not understanding online compiler

so I wrote some C# code and I am trying to test it incrementally, do to something that would take a while to explain, but bottom line, I'm new to c# and not understanding the online compiler error messages. Here is the error message I get when I try and compile, but the strings look good to me.
string solutionSet = "white|black|beige|pink|green|blue|red|yellow|orange|cyan|purple|brown";
string[] solutionSetArray = new string[12];
string ret = "";
string delimeter = "|";
int tempPos = 0;
int counter = 0;
int successFlag = 0;
int patternLength = 5;
for (int index = 0; index < solutionSet.Length; index++)
{
if (solutionSet[index] == delimeter)
{
solutionSetArray[counter] = solutionSet.Substring(tempPos, index);
tempPos = index + 1;
counter++;
}
if (solutionSet.Length - index == 1)
{
solutionSetArray[solutionSetArray.Length-1] = solutionSet.Substring(tempPos, solutionSet.Length);
}
}
for (int i = 0; i < patternLength; i++)
{
Random rnd = new Random();
int randIndex = rnd.Next(solutionSetArray.Length);
if (i != patternLength - 1)
{
ret += solutionSetArray[randIndex] + "|";
successFlag++;
}
else
{
ret += solutionSetArray[randIndex];
}
}
if (successFlag == patternLength - 1)
{
Console.WriteLine(ret);
}
else
{
Console.WriteLine("ERROR");
}
The error (which, according to the message, is on line 1, column 11) is being caused by your very first line of code, which begins string.
I can't tell the context from just your post, but my guess is that you are declaring solutionSet in a block that is not inside of a class or function. You should enclose your code in a class or method, e.g.
public class MyClass
{
static public void Main()
{
string solutionSet = "white|black|beige|pink|green|blue|red|yellow|orange|cyan|purple|brown";
//Rest of code goes here
}
}
By the way, if you're trying to convert solutionSet to an array, you can just write
var solutionSetArray = solutionSet.Split("|");
the problem with your code is
solutionSetArray[counter] = solutionSet.Substring(tempPos, index);
after 6 iterations tempPos=34 and index=37 which is running out of bounds of solutionSet. I would suggest to use var solutionSetArray = solutionSet.Split("|"); and also use LinqPad which can be easy for you to debug if possible,.

C#: While condition on function with out parameter?

I am working with an API that uses functions that use out parameters. I want to use the value in one of these out parameters in a while loop. For example:
static int counter = 0;
static void getCounterValue(out int val)
{
val = counter;
counter++;
}
static void Main()
{
// Right now, I'm having to do this:
int checkVal = 0; // I have to figure out an appropriate starting value.
while (checkVal < 10)
{
getCounterValue(out checkVal);
Console.WriteLine("Still waiting.");
}
Console.WriteLine("Done.");
}
Is there a simpler syntax to do this? I want something more classic like while (getCounterValue() < 10), but I have to deal with the out parameters because it's an API that I can't change.
You can't do anything directly, the return value of the method call is what while will use and that can't be the value you want. If this is causing you problems, you can always wrap the method call:
int wrappedGetCounterValue()
{
int i;
getCounterValue(out i);
return i;
}
Or with C# 7:
int wrappedGetCounterValue()
{
getCounterValue(out int i);
return i;
}
And use that in your while loop.
while (wrappedGetCounterValue() < 10)
....
do
{
getCounterValue(out checkVal);
Console.WriteLine("Still waiting.");
} while (checkVal < 10)
You can use the infinite loop with break condition:
while (true)
{
int checkVal;
getCounterValue(out checkVal);
if (10 <= checkVal)
break;
Console.WriteLine("Still waiting.");
}
Note the difference between do..while (checkVal < 10) option is that you will not output "Still waiting" message if first counter value will be greater or equal to 10. You cannot do that with do..while loop unless you will duplicate loop break condition (checkVal < 10).
Another option (but with the cost of code duplication) is to use for loop:
int checkVal;
for (getCounterValue(out checkVal); checkVal < 10; getCounterValue(out checkVal))
{
Console.WriteLine("Still waiting.");
}
Console.WriteLine("Done.");
If you want to completely hide the out functionality you must use a wrapper method. If you care only for "valid" values and the validity is well-defined by the <10 expression, then you can hide the <10 expression in that wrapper, and use a Nullable<int> in your code. That would be semantically correct.
static int counter = 0;
static void getCounterValue(out int val)
{
val = counter;
counter++;
}
static Nullable<int> getValidCounterValue()
{
int outResult;
getCounterValue(out outResult);
if (outResult < 10)
{
return null;
}
else
{
return outResult;
}
}
static void Main()
{
Nullable<int> checkVal = new Nullable<int>();
while (!checkVal.HasValue)
{
checkVal = getValidCounterValue();
Console.WriteLine("Still waiting.");
}
Console.WriteLine("Done. Valid value is:" + checkVal.Value.ToString());
}

StreamReader using arraylist or array

Here's my code:
StreamReader reader = new StreamReader("war.txt");
string input = null;
while ((input = reader.ReadLine()) != null)
{
Console.WriteLine(input);
}
reader.Close();
The program above reads and prints out from the file “war.txt” line-by-line. I need to re-write the program so that it prints out in reverse order, i.e., last line first and first line last. For example, if “war.txt” contains the following:
Hello.
How are you?
Thank you.
Goodbye.
The program should prints out:
Goodbye.
Thank you.
How are you?
Hello.
I am very new in C# please help! Thanks!
To do that, you are going to have to buffer the data anyway (unless you do some tricky work with the FileStream API to read the file backwards). How about just:
var lines = File.ReadAllLines("war.txt");
for(int i = lines.Length - 1; i >= 0; i--)
Console.WriteLine(lines[i]);
which just loads the file (in lines) into an array, and then prints the array starting from the end.
A LINQ version of that would be:
foreach(var line in File.ReadLines("war.txt").Reverse())
Console.WriteLine(line);
but frankly the array version is more efficient.
You can do it using recursion with something like this:
void printReverse(int n)
{
String line = reader.readLine();
if (n > 0)
printReverse(n-1);
System.out.println(line);
}
Have a look at adding the lines to a List, then using Reverse on the list and then maybe the ForEach to output the items.
Another option: store each line into a Stack as you read them. After reading the file, pop the stack to print the lines in reverse order.
with the enumerable extension functions, this can be done shorter:
foreach(var l in File.ReadAllLines("war.txt").Reverse())
Console.WriteLine(l);
try
File.ReadAllLines(myFile)
.Reverse();
full code
var list = File.ReadAllLines(filepath).Reverse().ToList();
foreach (var l in list)
Console.WriteLine(l);
Implementation detail
Enumerable.Reverse Method - Inverts the order of the elements in a sequence
File.ReadAllLines Method (String) - Opens a text file, reads all lines of the file, and then closes the file.
here is a example mate, remember to add "using System.IO"
try
{
const int Size = 7;
decimal[] numbers = new decimal[Size];
decimal total = 0m;
int index = 0;
StreamReader inputfile;
inputfile = File.OpenText("Sales.txt");
while (index < numbers.Length && !inputfile.EndOfStream)
{
numbers[index] = decimal.Parse(inputfile.ReadLine());
index++;
}
inputfile.Close();
foreach (decimal Sales in numbers)
{
outputlistBox1.Items.Add(Sales);
total = total + Sales;
}
textBox1.Text = total.ToString();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
Here is another example from a textbook i bought few years ago, this has highest/lowest/average scores..(remember to use 'using System IO;)
private double Average(int[] iArray)
{
int total = 0;
double Average;
for (int index = 0; index < iArray.Length;
index++)
{
total += iArray[index];
}
Average = (double) total / iArray.Length;
return Average;
}
private int Highest(int[] iArray)
{
int highest = iArray[0];
for (int index = 1; index < iArray.Length; index++)
{
if (iArray[index] > highest)
{
highest = iArray[index];
}
}
return highest;
}
private int Lowest(int[] iArray)
{
int lowest = iArray[0];
for (int index = 1; index < iArray.Length; index++)
{
if (iArray[index] < lowest)
{
lowest = iArray[index];
}
}
return lowest;
}
private void button1_Click(object sender, System.EventArgs e)
{
try
{
const int SIZE = 5;
int[] Scores = new int [SIZE];
int index = 0;
int highestScore;
int lowestScore;
double averageScore;
StreamReader inputFile;
inputFile = File.OpenText("C:\\Users\\Asus\\Desktop\\TestScores.txt");
while (!inputFile.EndOfStream && index < Scores.Length)
{
Scores[index] = int.Parse(inputFile.ReadLine());
index++;
}
inputFile.Close();
foreach (int value in Scores)
{
listBox1.Items.Add(value);
}
highestScore = Highest(Scores);
lowestScore = Lowest(Scores);
averageScore = Average(Scores);
textBox1.Text = highestScore.ToString();
textBox2.Text = lowestScore.ToString();
textBox3.Text = averageScore.ToString("n1");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void button2_Click(object sender, EventArgs e)
{
this.Close();
}
}
}

comparing strings, one from an array other from an entered value

Basically comparing a string that is entered, and trying to get that position from the array.
If I initialize position to 0 then it returns the position zero of the array, if I initialize to 1 then it gives me the item in slot 1, so it's skipping the compare statement.
I also tried using (custStatus == cardStatus[i])
public static int discount(string []cardStatus, int []pDiscount, string custStatus)
{
int position= 0;
int discount;
for(int i = 0; i < 2; i++)
{
if (string.Equals(custStatus, cardStatus[i]))
position = i;
}
discount = pDiscount[position];
return discount;
}
With your code, there's no way to tell if position = 0 means custStatus was found in your cardStatus array or if no match was made at all and the default value is being used. I'd recommend either using a boolean matchFound variable or setting position = -1 and adding an extra if statement at the end either way. Either:
boolean matchFound = false;
...
if(matchFound)
{
discount = pDiscount[position];
}
or else
int position = -1;
...
if(position >= 0)
{
discount = pDiscount[position];
}
Give this a try:
public static int discount(string[] cardStatus, int[] pDiscount, string custStatus) {
var position = Array.IndexOf(cardStatus, custStatus);
return (position == -1) ? -1 : pDiscount[position];
}
public static int discount(string []cardStatus, int []pDiscount, string custStatus)
{
for(int i = 0; i < Math.Min(cardStatus.Length, pDiscount.Length); i++)
{
if (string.Equals(custStatus, cardStatus[i]))
{
return pDiscount[i];
}
}
return -1;
}
Don't be afraid to return directly from FOR-loop, it is old-school that teaches to have only one return point from method. You can have as many returns as it helps you to keep your code clean and easy to read.
And perhaps it would be better to use the following expression in for-loop as it will guard you from possible different lengths of arrays:
for (int i = 0; i < Math.Min(cardStatus.Length, pDiscount.Length; i++)
This looks ok, even though this is somewhat more straightforward:
for(int i = 0; i < cardStatus.Length; i++)
{
if (custStatus == cardStatus[i])
{
position = i;
break;
}
}
Given your question it appears to be the case that all cardStatus[i] match custStatus - did you check the input?
Also given your code what happens if there is no match? Currently you would return pDiscount[0] - that doesn't seem to be correct.

Categories

Resources