This relates to another code I posted earlier but since this is a different question I decided to make a new post. I'm currently stuck with this code, I'm a c# beginner so this look complicated to me. I've been working on this code that is supposed to get an array from the user, calculate its average then display the results inside show(). I got this working to show the average of the array but now I need to actually display the array each value individually i.e. The 1st value you entered was : 12
The 2nd value you enteres was : 32
Thank guys!
private static int Array()
{
string inValue;
int[] score = new int[10];
int total = 0;
for (int i = 0; i < score.Length; i++)
{
Console.Write("Enter Value {0}: ", i + 1);
inValue = Console.ReadLine();
score[i] = Convert.ToInt32(inValue);
}
for (int i = 0; i < score.Length; i++)
{
total += score[i];
}
return total;
}
Change your GetValues() function to actually return the array of integers, then use the return value in your other functions.
i.e. change GetValues() to:
private static int[] GetValues()
{
string inValue;
int[] score = new int[5];
int total = 0;
for (int i = 0; i < score.Length; i++)
{
Console.Write("Enter Value {0}: ", i + 1);
inValue = Console.ReadLine();
score[i] = Convert.ToInt32(inValue);
}
return score;
}
EDIT: Here is how to use the GetValues() function above in a function to print out all the values. You should be able to work out the rest from here:
private static void PrintArray(int[] scoreArray)
{
for (int i = 0; i < scoreArray.Length; i++)
{
Console.WriteLine("Value #{0}: {1}", i + 1, scoreArray[i]);
}
}
Note how the scoreArray is passed in, as well as how each value is accessed, using scoreArray[i] (where i is a number from 0 to 4 inclusive).
Move int[] score out of GetValues and declare it at the class level making it static:
static int[] score = new int[5];
My next recommendation is that you don't do inside your functions more than what they claim to do from their name; for example, GetValues() should only get the values from user; not calculate totals (as you are doing) because it's misleading; it forces you to look at the implementation to know exactly what it does. Similarly for Show(); if the purpose is to show values entered by user, then call it ShowValues(); If the purpose is to show values entered by user as well as calculate the average, then name it something along the lines of ShowValuesAndAverage()
Here's a complete implementation of your program with my recommendations:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace testscores
{
class Program
{
static int[] score = new int[5];
//Get Values
private static void GetValues()
{
string inValue;
for (int i = 0; i < score.Length; i++)
{
Console.Write("Enter Value {0}: ", i + 1);
inValue = Console.ReadLine();
score[i] = Convert.ToInt32(inValue);
}
}
//FIND AVERAGE
private static double FindAverage()
{
double total = 0.0;
for (int i = 0; i < score.Length; i++)
{
total += score[i];
}
double average = total / 5.0;
return average;
}
//Show
static void ShowValuesAndAverage()
{
Console.WriteLine("The values are:");
for (int i = 0; i < score.Length; i++)
{
Console.WriteLine(string.Format("The {0} value you entered was {1}", i + 1, score[i]));
}
Console.WriteLine("The average is: {0}", FindAverage());
}
//Main
static void Main()
{
GetValues();
ShowValuesAndAverage();
Console.ReadKey();
}
}
}
Make one function for GetValues() and return the array. Then pass the array into a AddValues() function, and into Show().
Either that or read up on how to use pointers, but that might be overcomplicating things a little.
Related
I have implemented binary search algorithm in a console window application in C#. I am generating random values to the array and sorting them using Random() and Array.Sort() functions respectively.
The Problem - No matter what Key(item to be searched in the array) I give, the program is returning Key not found when the array items are generated using Random function
This does not happen if I enter the array elements manually using Console.ReadLine().
TLDR: Binary Search algorithm works fine when array items are entered manually, but does not work when array items are generated using Random function.
Can anyone point out what is the mistake I am doing?
My code - Random Generated array items.
namespace BSA
{
class Program
{
static void Main(string[] args)
{
var arr = new int[10];
Random rnd = new Random();
for (int i = 0; i < arr.Length; i++)
{
arr[i] = rnd.Next(1, 1000);
}
Array.Sort(arr);
for (int i = 0; i < arr.Length; i++)
{
Console.Write("{0}\n", i);
}
while (true)
{
Console.WriteLine("Enter the number to be searched in the array.");
var searchItem = Convert.ToInt32(Console.ReadLine());
var foundPos = Search(arr, searchItem);
if (foundPos > 0)
{
Console.WriteLine("Key {0} found at position {1}", searchItem, foundPos);
}
else
{
Console.WriteLine("Key {0} not found", searchItem);
}
}
}
public static int Search(int[] arr, int item)
{
var min = 0;
var N = arr.Length;
var max = N - 1;
int basicOperations = 0;
basicOperations++;
do
{
var mid = (min + max)/2;
if (arr[mid] == item)
return mid;
if (item < arr[mid])
max = mid - 1;
else
min = mid + 1;
basicOperations++;
} while (min <= max);
return basicOperations;
}
}
}
Please let me know if I am doing any silly mistake or I am committing a blunder in the above code. Any help would be really helpful.
Your search code works fine as far as I can see. However when you list the contents of the random array, you should write arr[i] rather than i to see what's in the array so you can pick a search value in it. Alternatively, pass arr[x] as the search item. It should return x.
Your code works correctly. You're just not looking for the right keys. The function that prints the values generated into the array prints the loop counter instead:
for (int i = 0; i < arr.Length; i++)
{
Console.Write("{0}\n", i);
}
You need to change it to:
for (int i = 0; i < arr.Length; i++)
{
Console.Write("{0}\n", arr[i]);
}
This will show you the values actually generated.
Comment too short for this so added answer to show how to set basicOperations and still return search position. You declare basicOperations as an out parameter which means the method can change it so the caller can see it when method returns.
public static void Main(string[] args)
{
... ... ...
int basicOperations;
int searchPos = IntArrayBinarySearch(arr, arr[5], out basicOperations);
Console.WriteLine("Found at {0} basic ops={1}", searchPos, basicOperations);
}
public static int IntArrayBinarySearch(int[] data, int item, out int basicOperations)
{
var min = 0;
var N = data.Length;
var max = N - 1;
basicOperations = 0;
basicOperations++;
and at bottom, you don't need to return out parameters, just return -1 to indicate failure as you did before
return -1;
This is the method im having issues with
this is the code with isssues
this is code im having issues with
static void FindDuplicates(int maxValue, int[]totalOfScores) {
int finalWinner = 0;
int i = 0;
int[] WinnerIndex = new int [totalOfScores.Length];
for (int g = 0; g < totalOfScores.Length; g++) {
if (totalOfScores[g] == maxValue)
for (i = 0; i < WinnerIndex.Length; i++) {
WinnerIndex[i] = g;
finalWinner = WinnerIndex[i];
Console.WriteLine("\n\nThe Highest Scoring comp was comp Number {0} With a total score of {1}", finalWinner + 1, maxValue);
}
}
}
If your question is on the dynamic array size, do not use array, use List instead. Or use Array.Resize(). But if I understand your goal correctly, you are trying to list all competitors that have the highest score, in this example competitors 3 and 4 you don't really need array for the results at all. Instead do:
static void FindDuplicates(int maxValue, int[] totalOfScores){
for (int i = 0; i < totalOfScores.Length; i++) {
if (totalOfScores[i] == maxValue){
Console.WriteLine("\n\nThe Highest Scoring comp was comp Number {0} With a total score of {1}", i+1, maxValue);
}
}
}
By the way, I would rename FindDuplicates as FindAllWinners (or then I have misunderstood your intentions).
I am trying to create a bowling program that when you enter in your name followed by your score, it will take the average, lowest, and highest scores of the players and print them. However for some reason I cannot get the lowest score to print, as when I hit enter twice, it will use the blank value instead of the lowest entered value and name. How can I fix this so that it will display the lowest score?
{
class Program
{
static void Main(string[] args)
{
const int SIZE = 10;
int i;
// create an array with 10 elements
string[] scoreInfo = new string[SIZE];
string[] names = new string[SIZE];
int[] scores = new int[SIZE];
for (i = 0; i < SIZE; i++)
{
// Prompt the user
Console.Write("Enter your first name and score on one line");
Console.WriteLine(" separated by a space.");
// Read one line of data from the file and save it in inputStr
string inputStr = Console.ReadLine( );
// if statement to break when the user enters a zero
if (inputStr == String.Empty)
{
break;
}
// The Split method creates an array of two strings
scoreInfo = inputStr.Split();
// Parse each element of the array into the correct data type
names[i] = scoreInfo[0];
scores[i] = int.Parse(scoreInfo[1]);
}
Console.WriteLine("The avarage score is {0}", AverageScore(scores, i));
Console.WriteLine("{0} scored the lowest at {1}", names[LowScore(scores, i--)], scores[LowScore(scores, i--)]);
Console.WriteLine("{0} scored the highest at {1}", names[HighScore(scores)], scores[HighScore(scores)]);
Console.ReadLine();
Console.ReadLine();
}
static int LowScore(int[] scores, int j)
{
int min = scores.Min();
return Array.IndexOf(scores, min);
}
static int HighScore(int[] scores)
{
int max = scores.Max();
return Array.IndexOf(scores, max);
}
static double AverageScore(int[] numbers, int j)
{
double average = 0;
for (int i = 0; i < j--; i++)
{
int product = 1;
product = numbers[i] * product;
average = product / j;
}
return average;
}
}
}
Use a different data structure and make less work for yourself.
Start with a dictionary that maps names to scores so that you don't have to mess around with indexes.
Then, LINQ is your friend, as you've already noticed. You don't need to create functions for things that already exist (like min/max/average).
eg.
Dictionary<string, int> ranking = new Dictionary<string, int>();
ranking.Add("adam", 20);
ranking.Add("bill", 10);
ranking.Add("carl", 30);
double avg = ranking.Average(kvp => (double)kvp.Value);
var sorted = ranking.OrderBy(kvp => kvp.Value);
var min = sorted.First();
var max = sorted.Last();
Console.WriteLine("Average: {0}", avg);
Console.WriteLine("Lowest: {0} with {1}", min.Key, min.Value);
Console.WriteLine("Highest: {0} with {1}", max.Key, max.Value);
Modify your Average function like this:-
static double AverageScore(int[] numbers, int j)
{
double sum = 0;
for (int i = 0; i < j; i++)
{
sum += numbers[i];
}
return (double)sum / j;
}
I am not sure why you were taking product of items for finding average of scores.
And Your Min function like this:-
static int LowScore(int[] scores, int j)
{
int min = scores.Where((v, i) => i < j).Min();
return Array.IndexOf(scores, min);
}
Here, you are passing the complete array of integer, so if only 3 players entered values, rest of the values will be initialized to default, i.e. 0 for int, Thus you were getting 0 as Min value.
Also, You need to change the method invocation like this:-
Console.WriteLine("{0} scored the lowest at {1}", names[LowScore(scores, i)], scores[LowScore(scores, i)]);
I've created a Dice program which rolls a dice dependant on how many times the user wishes to roll. The problem I'm having is being able to calculate how many times each number appears.
Example. Roll Twice - Number is 5.
Number is 4.
I want to be able to count that a 4 and a 5 has being rolled and display it back to the user.
My Code so far
using System;
namespace Dice
{
class Dice
{
private Random randy;
int total;
public static void Main()
{
Dice myDice = new Dice();
myDice.randy = new Random();
Console.Clear();
myDice.manyThrow();
myDice.throwDice();
Console.ReadKey();
}
//*******************************************************
public void throwDice()
{
double count = 0;
while(count != total)
{
count++;
Console.WriteLine("Throw No " + count + " is " + oneThrow());
}
}
//*******************************************************
public int oneThrow()
{
return randy.Next(6) + 1; // pick a number from 1 to 6 and return this
}
public int manyThrow()
{
Console.Write("How many times do you want to roll\t");
total = Convert.ToInt32(Console.ReadLine());
return total;
}
public void countEm()
{
// This is where I intend to place the code
}
}
}
I've being trying to solve this for hours.
Add an array to count roll results:
using System;
namespace Dice
{
class Dice
{
private Random randy;
int total;
int [] rolls = new int[7];
public static void Main()
{
Dice myDice = new Dice();
myDice.randy = new Random();
Console.Clear();
myDice.manyThrow();
myDice.throwDice();
myDice.countEm();
Console.ReadKey();
}
//*******************************************************
public void throwDice()
{
double count = 0;
while (count != total)
{
count++;
Console.WriteLine("Throw No " + count + " is " + oneThrow());
}
}
//*******************************************************
public int oneThrow()
{
var result = randy.Next(6) + 1; // pick a number from 1 to 6 and return this
this.rolls[result]++;
return result;
}
public int manyThrow()
{
Console.Write("How many times do you want to roll\t");
total = Convert.ToInt32(Console.ReadLine());
return total;
}
public void countEm()
{
for (int i = 1; i<7; i++)
{
Console.WriteLine("{0} rolled {1} times", i, rolls[i]);
}
}
}
}
Try this:
static int[] counts = new int[6];
And in oneThrow():
int result = randy.Next(6);
counts[result]++;
return result + 1;
Then in countEm():
for (int i = 0; i < counts.Length; i++)
{
Console.WriteLine("{0}: {1}", i + 1, counts[i]);
}
Keep an array of the possible outcomes count.
class Dice
{
private Random randy;
private int total;
private static const int NUM_SIDES = 6;
private int[] counts;
public Dice()
{
randy = new Random();
counts = new int[ NUM_SIDES ];
}
public static void Main()
{
Dice myDice = new Dice();
Console.Clear();
int throws = myDice.manyThrow(); // need to save the number of throws
myDice.throwDice( throws );
countEm();
Console.ReadKey();
}
public void throwDice( int throws )
{
double count = 0;
while(count != throws)
{
count++;
int result = oneThrow();
counts[ result - 1 ]++; // NOTE: result-1 because arrays are 0-based.
Console.WriteLine("Throw No " + count + " is " + oneThrow());
}
}
// ...
public void countEm()
{
for( int i = 0; i < counts.Count; ++i )
Console.WriteLine( (i+1) + " thrown " + counts[i] + " times." );
}
If you just want to keep track of the count of each number rolled, then you add to your class an array of integers to store the count of each number rolled. The number of the dice roll could be the index into the array.
If you need to keep track of the order of the numbers rolled. Your class could could use a linked list or other ordered list to keep track of the numbers.
This sort of sounds like a homework assignment, so I'll leave the implementation details to the reader :)
Modify the countEM like this:
public void countEm(int numberOfThrows)
{
List<int> Throws = new List<int>(); //Create list, where value of throws will be stored.
for(int i = 0; i < numberOfThrows) //Loop as many times as are given by parameter.
{
Throws.Add(OneThrow()); //Add return value of throw to the list.
}
//Show values in Throws list.
foreach(var diceValue in Throws)
{
Console.WriteLine(string.Format("Value of throw: {0}", diceValue ));
}
}
coutEM should be called with the number of times you want to throw like:
countEM(5);
Above represents 5 throws. The result for example could be filled with:
1, 4, 6, 3, 4
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I have been instructed to write a program that collects a bowling score (integer) and a name from the user, separated by a space, and sorts each of them into an array using the Split method. The output has to be formatted to find the average score and output it to the console, as well as sort the scores (and names) in order of lowest to highest.
I have been able to do everything except find a way to sort the names with their corresponding scores.
Here is what I have so far. To clarify, I need help writing a sorting algorithm for my array of names.
using System;
class Program
{
//class variables
const int MAX = 10;
static void Main()
{
//declare array
int[] score = new int[MAX];
string[] name = new string[MAX];
//program prologue
Console.WriteLine("****************Bowling Project****************");
Console.WriteLine("Please enter a name and a score for each player. For example 'John 145'.\nHit enter when you are done.");
//for loop to get input
for (int i=0; i<MAX; i++)
{
Console.Write("Enter a name and a score for player #{0}: ", (i + 1));
string input = Console.ReadLine();
if (input == "")
{
break; // if nothing is entered, it will break the loop
}
//split the user data into 2 arrays (integer and string)
string[] separateInput = input.Split();
name[i] = separateInput[0];
score[i] = int.Parse(separateInput[1]);
}
Console.WriteLine("\n****************Input Complete****************");
//calculate the average score and send to the console
CalculateScores(score);
Console.WriteLine("The scores for the game are:");
//sort the scores
BubbleSort(score);
Console.ReadLine();
}//End Main()
//CalculateScores Method
//Calculates the average score of an array of integers
//Takes an array of integers as parameters
//Returns void
//Outputs the average to the console
static void CalculateScores(int[] score)
{
int sum = 0;
int average = 0;
for (int i = 0; i < score.Length; i++)
{
sum += score[i];
average = sum / score.Length;
}
Console.WriteLine("The average score was {0}", average);
}//End calculateScores
//Swap method
//Takes 2 integers as parameters
//Switches the value of 2 integers (a and b)
static void Swap(ref int a, ref int b)
{
int temp = a;
a = b;
b = temp;
}
//BubbleSort method
//Sorts an array of integers
//Takes an array of integers as a parameter
//Returns void
//Outputs to the console
static void BubbleSort(int[] score)
{
for (int j = 0; j < score.Length -1; j++)
{
for (int i = 0; i < score.Length - 1; i++)
{
if (score[i] > score[i + 1])
{
Swap(ref score[i], ref score[i + 1]);
}
}
}
foreach (int a in score)
Console.WriteLine("{0}", a);
Console.ReadLine();
}
}//End class Program
Assuming that names[] corresponds 1 to 1 with score[]:
Just take your BubbleSort method, and pass both names[] and score[] into it
Then, you whenever you do an operation on score[] do it on names[] too.
something like this
static void BubbleSort(int[] score, string[] names)
{
for (int j = 0; j < score.Length -1; j++)
{
for (int i = 0; i < score.Length - 1; i++)
{
if (score[i] > score[i + 1])
{
Swap(ref score[i], ref score[i + 1]);
Swap(ref names[i], ref names[i + 1]);
}
}
}
foreach (int a in score)
Console.WriteLine("{0}", a);
Console.ReadLine();
}
you might have to make a swap method for strings
static void Swap(ref string a, ref string b)
{
string temp = a;
a = b;
b = temp;
}
you should make a separate class that will store a player with its score array.
then make an array of players that you can sort based upon their name
EDIT: I've updated my answer to be an implemented player class that builds upon your original code. If this is for a university project this may get seen by plagiarism checkers so I'd be wary to use it.
public class Player
{
public Player(){}
public Player(string name, int score)
{
m_name = name;
m_score = score;
}
public Player(Player p)
{
m_name = p.Name;
m_score = p.Score;
}
public string Name
{
get{return m_name;}
}
public int Score
{
get{return m_score;}
}
private string m_name
private int m_score
}
Player[] players = new Player[MAX];
static void BubbleSort(Player[] players)
{
for (int j = 0; j < players.Length -1; j++)
{
for (int i = 0; i < players.Length - 1; i++)
{
if (players[i].Score > players[i + 1].Score)
{
Swap(ref players[i], ref players[i + 1]);
}
}
}
foreach (Player a in players)
Console.WriteLine("{0}", a.Score);
Console.ReadLine();
}
static void Swap(ref Player a, ref Player b)
{
Player temp = a;
a = b;
b = temp;
}
Instead of using two collections of loosely associated values, use a single collection of a class:
public class BowlingScore {
public string Name { get; private set; }
public int Score { get; private set; }
public BowlingScore(string name, int score) {
Name = name;
Score = score;
}
}
Use a list rather than an array for the collection:
List<BowlingScore> scores = new List<BowlingScore>();
In your loop you can create instances of the class and add to the list:
BowlingScore item = new BowlingScore(separateInput[0], int.Parse(separateInput[1]);
scores.Add(item);
By using a list instead of an array, it will only contain the items that you actually add. Your current code would need another variable to keep track of how many items in the array was actually used, so that you don't include the ones left empty at the end.
Now, as you have the name and score as a single unit, you can sort the list using the same approach as you used for sorting an array, only you compare a property of the objects. As you swap the whole objects, the name will follow the score when you sort on scores, and vice versa.
The items in the list can be accessed using index just like an array, only the length of the list is in the Count property instead of Length.
No need to create two arrays because you are losing the semantic meaning between the player's name and its score. But also no need to create a new class for that. You can re-use built-in classes/structs like Tuple<...> or KeyValuePair<...>. For ordering, you can use linq-extension methods.
static void Main(string[] args)
{
// just some sample players
const string player1 = "David 100";
const string player2 = "Jennifer 1430";
const string player3 = "Eve 234";
// the string-array with information about players
var players = new[] { player1, player2, player3 };
// initialize the array: a tuple is the name of the player and the score
var scores = new List<Tuple<string, int>>(players.Length);
foreach (string player in players)
{
// split by whitespace
string[] info = player.Split(' ');
// be failure tolerant: split must result in at least 2 entries and second one must be integer
int score;
if (info.Length <= 2 && int.TryParse(info[1], out score))
scores.Add(new Tuple<string, int>(info[0], score));
}
// print average score
Console.WriteLine("Average score for {0} players is: {1}{2}", scores.Count, scores.Select(t => t.Item2).Average(), Environment.NewLine);
// print score of each single player (ordered from highest to lowest score)
foreach (Tuple<string, int> score in scores.OrderByDescending(t=>t.Item2))
Console.WriteLine("Player '{0}' => score: {1}", score.Item1, score.Item2);
Console.WriteLine();
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}