How to Display the Largest and Smallest Values of an Array - c#

To start this is a homework assignment and I'm having a bit of trouble and would like some suggestions. So far I've created this application to take 10 inputted values from a user and store them into an array. I pass the array to the SmallAndLarge method where it displays derermines the smallest and largest of the 10 values using Sort() but now i have to display the smallest and largest of the 10 values the user entered and am having a trouble. Any help at all would be great!!
Also one other problem ive noticed that if the values 1 through 10 are entered 10 will be before 2 and after one when the array is sorted and displayed. Why is this?
namespace SmallAndLarge
{
class Program
{
static void Main()
{
int found = 0;
string[] numbers = new string[10];
for (int i = 0; i < numbers.Length; i++)
{
Console.Write("Enter ten numbers --> ");
numbers[i] = Console.ReadLine();
}
SmallestAndLargest(numbers);
}
public static int SmallestAndLargest(string[] numbers1)
{
int x;
Array.Sort(numbers1);
for (x = 0; x < numbers1.Length; ++x)
Console.Write("{0} ", numbers1[x]);
return x;
}
}
}

You can use Linq to cast and return the Largest/Smallest using Min/Max
string[] numbers = new string[] {"1","2","3","15","30","7" };
var converted = numbers.Select(int.Parse);
int largest = converted.Max();
int smallest = converted.Min();

You have the numbers as strings. That explains why "10" comes before "2", it's for the same reason that "am" comes before "i" in an alphabetic sort. The first character of "10" is '1' which comes before '2'.
So before you sort the array, or search for the max og min value, you need to convert the strings into some numeric type. It could be the int type, for example. You would hold them in an array of type int[], not string[].
To convert from the string given by Console.ReadLine into int, use an overload of int.Parse or int.TryParse methods, for example.
If the user should be allowed to type non-integral numbers like 3.14, you could use decimal instead of int.

It looks like you are iterating over the array. I would do the following:
Create two int variables (small and large, respectively)
Set them both equal to the first element of the array
Loop through the elements;
For each element[i], (convert the element to int using int.Parse() or equivalent).
if element[i] > large, large = element[i]; if element[i] < small, small = element[i]
There is no need for sort if you only need min and max. And I would store the ints into and int array rather than string array, make the conversion when the user inputs the value. That way, when an invalid value is input, your program fails right then.

Here's a very simple, though long winded answer. Add the values to a List and use Min/Max returns. Your already using a for loop to iterate through the list, no reason to do it twice.
static void Main(string[] args)
{
string[] StringValues = new string[] { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10","Not Number" };
List<int> ConvertedStrings = new List<int>();
foreach (string S in StringValues)
{
ConvertedStrings = ParseStringToInt(S, ConvertedStrings);
}
Console.WriteLine();
Console.WriteLine("Max Value: " + ConvertedStrings.Max().ToString());
Console.WriteLine("Min Value: " + ConvertedStrings.Min().ToString());
Console.ReadLine();
}
static private List<int> ParseStringToInt(string Input, List<int> ConvertedStrings)
{
int ConvertedValue = 0;
if (int.TryParse(Input, out ConvertedValue))
{
Console.WriteLine(Input + " sucessfully parsed and added...");
ConvertedStrings.Add(ConvertedValue);
return ConvertedStrings;
}
else
{
Console.WriteLine(Input + " failed to parse...");
}
return ConvertedStrings;
}
sa_ddam213 has got the killer answer though :P

Related

I can't figure out why I'm reading wrong input in reading array elements in codechef problem for reverse array problem

I'm getting different user input instead of getting real inputs given by user in codechef
User Input:
4
1 2 3 4
Expected Output:
4 3 2 1
using System;
public class Test
{
public static void Main()
{
int N = Convert.ToInt32(Console.ReadLine());
int[] arr = new int[N];
for(int i=0;i<N;i++){
arr[i] = Convert.ToInt32(Console.Read());
}
for(int j=N-1;j>=0;j--){
Console.Write(arr[j]);
Console.Write(" ");
}
}
}
Output I got:
32 50 32 49
Since you said you want to do it without ReadLine, let's work with your current code. There are two issues at hand.
You should skip the spaces
You get the character codes instead of the values
To skip the spaces, you can simply read them and do nothing with the read character. I implemented this below in a way that assumes after every number (one digit long) there will be a single space to ignore. But you could also do that in a less hacky way by checking what the read character actually is before you discard it.
To get the character code into the value, I first perform a conversion into a char by casting it. Then I get the numeric value, which might be a double. But because you know that your numbers are integers, we can cast that to int.
using System;
class Program {
static void Main(string[] args) {
int N = Convert.ToInt32(Console.ReadLine());
int[] arr = new int[N];
for(int i=0;i<N;i++){
arr[i] = (int)Char.GetNumericValue((char)Console.Read());
Console.Read();
}
for(int j=N-1;j>=0;j--){
Console.Write(arr[j]);
Console.Write(" ");
}
}
}

Rearranging a string of numbers from highest to lowest C#

What I'm trying to do is to create a function that will rearrange a string of numbers like "1234" to "4321". I'm certain that there are many much more efficient ways to do this than my method but I just want to see what went wrong with what I did because I'm a beginner at programming and can use the knowledge to get better.
My thought process for the code was to:
find the largest number in the inputted string
add the largest number into a list
remove the largest number from the inputted string
find the largest number again from the (now shorter) string
So I made a function that found the largest number in a string and it worked fine:
static int LargestNumber(string num)
{
int largestnumber = 0;
char[] numbers = num.ToCharArray();
foreach (var number in numbers)
{
int prevNumber = (int) char.GetNumericValue(number);
if (prevNumber >= largestnumber)
{
largestnumber = prevNumber;
}
}
return largestnumber;
}
Now the rearranging function is what I am having problems with:
static List<int> Rearrange(string num)
{
List<int> rearranged = new List<int>(); // to store rearranged numbers
foreach (var number in num) //for every number in the number string
{
string prevnumber = number.ToString(); // the previous number in the loop
if (prevnumber == LargestNumber(num).ToString()) // if the previous number is the larges number in the inputted string (num)
{
rearranged.Add(Convert.ToInt32(prevnumber)); // put the previous number into the list
// removing the previous number (largest) from the inputted string and update the inputted string (which should be now smaller)
StringBuilder sb = new StringBuilder(num);
sb.Remove(num.IndexOf(number), 1);
num = sb.ToString();
}
}
return rearranged; // return the final rearranged list of numbers
}
When I run this code (fixed for concatenation):
var rearranged = Rearrange("3250");
string concat = String.Join(" ", rearranged.ToArray());
Console.WriteLine(concat);
All I get is:
5
I'm not sure what I'm missing or what I'm doing wrong - the code doesn't seem to be going back after removing '5' which i s the highest number then removing the next highest number/
Your issue is your if statement within your loop.
if (prevnumber == LargestNumber(num).ToString()
{
rearranged.Add(Convert.ToInt32(prevnumber));
//...
}
You only ever add to your List rearranged if the value of prevnumber is the largest value, which is false for every number but 5, so the only value that ever gets added to the list is 5.
That's the answer to why it's only returning 5, but I don't think that will make your method work properly necessarily. You're doing a very dangerous thing by changing the value of the collection you are iterating over (the characters in num) from within the loop itself. Other answers have been written for you containing a method that rearranges the numbers as you've described.
Your Rearrange method is returning List<int> when you try to write that to the console, the best it can do is write System.Collections.Generic.List1[System.Int32] (its type)
Instead of trying to write the list, convert it first into a data type that can be written (string for example)
eg:
var myList = Rearrange("3250");
string concat = String.Join(" ", myList.ToArray());
Console.WriteLine(concat);
Building on pats comment you could iterate through your list and write them to the console.
e.g.
foreach(var i in Rearrange(3250))
{
console.writeline(i.ToString());
}
or if you want to see the linq example.
using system.linq;
Rearrange(3250).foreach(i => console.writeline(i.ToString()));
--edit after seeing you're only getting '5' output
This is because your function only adds number to the list if they are the largest number in your list, which is why 5 is only being added and returned.
Your Rearrange method can be written easily using Array.Sort (or similar with (List<T>) :
int[] Rearrange(int num)
{
var arr = num.ToString ().ToCharArray ();
Array.Sort (arr, (d1, d2) => d2 - d1);
return Array.ConvertAll (arr, ch => ch - '0');
}
Just reading your first sentence
Does not test for integers
static int ReversedNumber(string num)
{
char[] numbers = num.ToCharArray();
Array.Sort(numbers);
Array.Reverse(numbers);
Debug.WriteLine(String.Concat(numbers));
return (int.Parse(String.Concat(numbers)));
}
Because your foreach loop within Rearrange method only loop through the original num. The algorithm doesn't continue to go through the new num string after you have removed the largest number.
You can find the problem by debugging, this foreach loop in Rearrange goes only 4 times if your input string is "3250".

Splitting Multiple Numbers

I'm just getting into learning c#, and I'm a little bit over my head. I'm trying to let a user input a list of 5 grades, and then split them to calculate the highest, lowest, and average.
I can't use int and split together, but I'm not sure how to get this to work.
Thanks!
Console.WriteLine("Enter 5 Grades; Whole Integers Only, 0-100; One Space Between Grades");
int allgrades = int.Parse(Console.ReadLine());
string[] splitgrades = allgrades.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
g1.Name = name + "'s GradeBook";
Console.WriteLine(g1.Name);
Console.WriteLine("Press Any Key to Calculate Gradebook Statistics");
Console.ReadKey();
GradeBook book = new GradeBook();
book.AddGrade(splitgrades[0]);
book.AddGrade(splitgrades[1]);
book.AddGrade(splitgrades[2]);
book.AddGrade(splitgrades[3]);
book.AddGrade(splitgrades[4]);
Thank you all for your help; I changed it around to
Console.WriteLine("Enter 5 Grades; Whole Integers Only, 0-100; One Space Between Grades");
string[] splitgrades = Console.ReadLine().Split(new char[] {' '}, StringSplitOptions.RemoveEmptyEntries);
int grade = int.Parse(splitgrades[0]);
int grade1 = int.Parse(splitgrades[1]);
int grade2 = int.Parse(splitgrades[2]);
int grade3 = int.Parse(splitgrades[3]);
int grade4 = int.Parse(splitgrades[4]);
In the second line, you're trying to parse the entire input into a single int. You want to first split the string into different ints, then parse each separately.
You're asking the user for a space-delimited list of integers, then trying to parse that string into a single integer. That will cause much sadness during runtime. Instead, you want something like this:
string allGrades = Console.ReadLine();
string[] splitGrades = allGrades.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
This will leave you with an array of (hopefully) 5 integer grades you can add to your GradeBook. When doing so would be the proper time to parse integers from the individual strings in the array.
// Use a foreach instead to allow the user to enter as many grades as they want.
for (int i = 0; i < 5; ++i)
book.AddGrade(int.Parse(splitGrades[i]);

Get the sum of an array in C# but receiving int32 error

In general, I know that int32 errors mean that a string value is not getting converted for the console program. I have seen a lot of code trying to find the answer to this including the following stackoverflow questions (seen much more but these were most useful:
How to sum up an array of integers in C#
Error CS1501: I'm not overloading a Sum() method correctly
CS0019 Operator cannot be applied to operands of type 'bool' and 'int'
That being said, this is also a homework assignment, titled UsingSum.cs as seen in a couple of these links. The difference in mine and these is that I am trying to make it so that the user enters however many Integers they want, then they are added up. The entire assignment is written in link 2....
The problem: I keep getting either 0 or System.Int32[] instead of the sum, despite the changes I make.
I cannot use Linq.
Here is the code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace UsingSum
{
class Program
{
static void Main(string[] args)
{
int i;
int usrInput;
bool running = true;
//Enter Question Asking Loop w/ running=true
while (running)
{
Console.Write("Enter a number or enter 999 to exit: ");
int[] array1 = new int[0];
for (i = 0; i < array1.Length; i++)
{
usrInput = Convert.ToInt32(Console.ReadLine());
array1[i] = Convert.ToInt32(usrInput);
}
for (i = 0; i < array1.Length; i++)
{
Console.WriteLine(array1[i]);
}
/*If the user enters 999, calls Sum() and asks user to press any key to exit.
changes 'running' from true to false to exit the question loop*/
int exit = Convert.ToInt32 (Console.ReadLine());
if (exit == 999)
{
running = false;
Sum(array1);
}
}
//Loop complete
Console.WriteLine("Press any key to exit.");
Console.ReadLine();
}
public static void Sum(int[] numbers)
{
int [] sum1 = new int [0];
int sum2 = 0;
//Program accepts user responses with or w/o this loop...Int.32 error present both ways
//for (int a = 0; a < numbers.Length; ++a)
//sum1[a] = a;
//additional loop tried w/o the loop above/below;
//when used in the WriteLine w/ sum2 it displays 0, when used with sum1 or numbers Int.32 error
//Array.ForEach(sum1, delegate(int i) { sum2 += i; });
foreach (int i in numbers)
sum2 =+ i;
Console.WriteLine("The sum of the values in your array is: " + sum1);
/*tried changing 'numbers' to sum1, sum2, sum1.Convert.ToString(),sum2.Convert.ToString()
numbers.Convert.ToString(), also tried converting sum2 to a string.*/
}
}
}
Here is my final solution!
static void Main(string[] args)
{
AskUserForNumbers();
Console.WriteLine("Press any key to exit");
Console.ReadLine();
}
public static List<Int32> AskUserForNumbers()
{
bool running = true;
List<int> numbers = new List<int>();
while (running)
{
Console.Write("Enter a number or enter 999 to exit: ");
int inputValue;
var inputString = Console.ReadLine();
//Check for "999" which indicates we should display the numbers entered, the total and then exit our loop.
if (inputString == "999")
{
Console.WriteLine("The sum of the values in your array is: " + numbers.Sum());
running = false;
}
else if (Int32.TryParse(inputString, out inputValue) && inputValue > 0)
{
numbers.Add(inputValue);
}
else
{
Console.WriteLine("Please enter a whole number greater than 0");
}
}
return numbers;
}
}
}
A few problems:
First, you're always declaring your arrays as int[] array1 = new int[0];. This means that your code for actually getting the user input will never hit. Maybe you should try using a different collection type (List<int> maybe).
Second, you never perform any error checking when parsing the integer. That's bad practice. You should be using int.TryParse(string input, out result) to verify it was a valid number before adding it to the array.
Third, you are looping over the length of the array for inputs, meaning you will loop through however long the array is, and will continue doing so until the last input you have is the exit number (999).
Fourth, the input you get for the exit code is discarded (not added to the array to sum).
Just remember that programming is very procedural. There should be clear (logical) steps from point a to point b. In fact, imagine you are the program and you're asking a friend to give you numbers to sum up for him. Give him whatever information you think might be useful (such as the exit condition). Diagram the steps, and then try to translate that to code.
Edit: The main point is that an array (which has a fixed size) is NOT the tool for the job here. You're not actually filling the array with any data, so that's why the sum never happens. The culprit is here:
int[] array1 = new int[0]; // Instantiate a zero-length array? Can't hold any values
// Will never hit inside the loop here, because i < array1.Length (which is zero) will always be false.
for (i = 0; i < array1.Length; i++)
You need to either increase the size of the array to begin with (and either reuse the indexes or resize the array) or use an non-fixed collection (List, for example). Finally, when you pass array1 to the Sum method, array1 is empty because you declared it as a zero element array. That is why you always get a zero printing out. Like I said before, imagine you are the program, and actually run through all these steps, LINE BY LINE.
For example, you start in the loop. You prepare a miniature notebook to write down all the numbers your friend is telling you with no pages in it. For every page (and realize there are none) in the notebook, you ask your friend for a number. After you've gone through every page, you now go through every page again to read all the values he gave you (keep in mind he couldn't give you any numbers, since the notebook was empty). Then you ask him one more time for a number, and if it's 999 you tell him you're done and give him the sum of all the numbers you wrote down. If he didn't give you 999 as the number, you repeat the cycle.
Do you understand WHY it's not working now?
public static void Sum(int[] numbers)
{
int sum2 = 0;
foreach (int i in numbers)
sum2 =+ i;
Console.WriteLine("The sum of the values in your array is: " + sum2);
}
foreach (int i in numbers)
sum2 =+ i;
should become
foreach (int i in numbers)
sum2 += i;
Your problem is with your first for loop. You never will add items to your array because your
for (i = 0; i < array1.Length; i++)
Since you only add to your array1 array when you enter the loop, it won't ever increment. Since i = 0 and the array1.Length is 0 to start, i will never be less than the length.
Here is what I would suggest you do.
private static void Main(string[] args) {
var running = true;
var numbers = new List<int>();
//Enter Question Asking Loop w/ running=true
while (running) {
Console.Write("Enter a number or enter 999 to exit: ");
int inputValue;
var inputString = Console.ReadLine();
//Check for "999" which indicates we should display the numbers entered, the total and then exit our loop.
if (inputString == "999") {
//Display the numbers entered
foreach (var number in numbers) {
Console.WriteLine(number);
}
Console.WriteLine("The sum of the values in your array is: " + numbers.Sum());
running = false;
}
else if (Int32.TryParse(inputString, out inputValue) && inputValue > 0) {
//We have valid input, append it to our collection
numbers.Add(inputValue);
}
else {
//The user entered invalid data. Let them know.
Console.WriteLine("Please enter a whole number greater than 0");
}
}
//Loop complete
Console.WriteLine("Press any key to exit.");
Console.ReadLine();
}
You have several small mistakes here.
In your Sum method you are no longer using the array sum1, you're summing the values into sum2, but you're printing sum1. Your sum method should be (as described by Wiktor):
public static void Sum(int[] numbers)
{
int sum2 = 0;
foreach (int i in numbers)
sum2 += i;
Console.WriteLine("The sum of the values in your array is: " + sum2);
}
Also note that you used sum2 =+ i rather than sum2 =+ i. What that's saying is "set sum2 to be equal to the positive value of i" rather than, "add i to sum2.
Next, you have some issues in how you gather your input from the user. First off, arrays don't have a mutable size. The size that they have is fixed when they are created, and the array that you create to hold onto the values to sum up from the users is initialized to a size of 0. (int[] array1 = new int[0];) If you want to get a fixed number of values from the user you can put something other than 0 there for the array size, but based on the context it appears that you want the users to be able to add values until they enter 999 at which point you end. Since you don't know the size before hand you'll want to use a List<int> rather than an array, as you can just add items to it and it will magically grow to support the new items.
I would also suggest making a new method to get all of the values from the user, rather than embedding it in your Main method.
public static List<int> AskUserForNumbers()
{
List<int> numbers = new List<int>();
while(...)//todo determine end condition
{
string userInput = Console.ReadLine();
if(...)//todo determine if user is done
{
}
else
{
int nextNumber = ...;//todo parse user input
numbers.Add(nextNumber);
}
}
return numbers;
}
I'm not sure if it's a requirement for you to stop asking for numbers when the user enters 999 or if that's just what you did. if you have a choice, I would suggest using something different such as a blank line, 0, "quit", "exit", etc. 999 is a number that someone might want to sum.
As mentioned by SPFiredrake, it's best to use int.TryParse() to parse user input, that way if they enter a number that's not an int it won't crash, and you can tell the user that it was no good and they need to try again.

Arrays in C# getting user input and passing to a different class

I am working on a project, Yes its for school. I'm having a hard time understanding how to pass the user input and store it with a array. The project is to get high and low temps for seven days and store in different arrays then compute the ave high etc. how do I collect the input and store it in a array in a different class? I think I almost have it but not sure where I'm going wrong
I have this so far but get a error:
Cannot implicitly convert type 'int' to 'int[]'
namespace Project_Console_3
{
class Program
{
static void Main(string[] args)
{
WeeklyTemperature Temp = new WeeklyTemperature();
int Count = 0;
while (Count < 7)
{
Console.WriteLine("Enter The High Temperature for Day {0}", Count+1);
Temp.HTemp1 =Console.ReadLine(); // save the number as a string number
Temp.HTemp = Convert.ToInt32(Temp.HTemp1); // change the string number to a integer as HTemp
Console.WriteLine("--------------------------------");//Draws a line
Console.WriteLine("Enter The Low Temperature for Day {0}", Count+1);
Temp.LTemp1 =Console.ReadLine(); // save the number as a string number
Temp.LTemp = Convert.ToInt32(Temp.LTemp1);
Console.WriteLine("--------------------------------");//Draws a line
Count = Count + 1;
Console.Clear();
}
}
}
}
WeeklyTemperature.cs
namespace Project_Console_3
{
class WeeklyTemperature
{
public int[] HTemp = new int[7];
public int[] LTemp = new int[7];
public string HTemp1;
public string LTemp1;
}
}
It looks like all you need to do is change this line:
Temp.HTemp = Convert.ToInt32(Temp.HTemp1);
to
Temp.HTemp[Count] = Convert.ToInt32(Temp.HTemp1)
Your error message tells you that you have a mismatch in the assignment of variables.
in this line:
Temp.HTemp = Convert.ToInt32(Temp.HTemp1);
The return value is of type int but the variable Temp.HTemp is of type int[] which is an array that holds individual integer.
To store values in an array the compiler has to know at which position it has to put the value.
Indexing an array works with the [] operators:
int pos = 0;
Temp.HTemp[pos] = 5;
will store a 5 on the first position.
Since you have a counting variable in your while loop you can use it to index the position where the numbers should be stored, as Jim Ross already showed in his answer.
More on the topic of indexing you can find here, and a tutorial is here

Categories