Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I have an assignment that requires a lot conversions between different units of measure. I have all of the work done except the math part. My question is, and if anyone has a better solution im all ears, would it be best to do these calculations using a switch or an if statement? Here is a little background info about my program. I have a text file that contains 9 different units of measurement along with their lengths in terms of feet separated by a comma that looks like as follows:
inch,.083333
fathom,6
foot,1
furlong,660
kilometer,3281.5
meter,3.2815
mile,5280
rod,16.5
yard,3
So, i have successfully dumped all of the information into a string array. From there i split the string array twice. The first time i split the string array, i created a new string array that would hold only the names for each unit of measure. The second time i split the string array, i did it so i could create a double array to hold all of the numeric values for each unit of measurement. Now i need to do the math portion. My program is going to display the nine different units of measure, request the unit to convert from, requests the unit to convert to, request the quantity (or total measurement) to convert, and then display the converted quantity. SO far this is what i have:
private void SandC_Load(object sender, EventArgs e)
{
splitContainer1.Panel1Collapsed = false;
splitContainer1.Panel2Collapsed = true;
string[] lengths = File.ReadAllLines("Units.txt");
int count=0;
string[] unitName=new string[count];
while (!(count==10))
{
count++;
lbLengths.Items.Add(count+"."+" "+lengths[count-1].Split(new Char[]{','})[0]);
}
}
private void btnConvert_Click(object sender, EventArgs e)
{
string orginalunits = tborginalUnits.Text;
int orginalunits1;
string desiredunits = tbDesiredunits.Text;
int desiredunits1;
string lenghttoConvert = tbConvert.Text;
double lenghttoConvert1;
string[] lengths = File.ReadAllLines("Units.txt");
int count = lengths.Length;
double[] units = new double[lengths.Length];
for (int i = 0; i < lengths.Length;i++)
{
units[i] = Convert.ToDouble(lengths[i].Split(new Char[] { ',' })[1]);
}
if ((double.TryParse(lenghttoConvert, out lenghttoConvert1)) && (Int32.TryParse(orginalunits, out orginalunits1)) && (Int32.TryParse(desiredunits, out desiredunits1)))
{
if ((desiredunits1==3)&&(orginalunits1==1))
{
double answer;
answer = units[0] * lenghttoConvert1;
Math.Round(answer, 3);
mtbOutput.Text = Convert.ToString(answer);
lblConversion.Text = "Converted to foot length";
}
}
else
MessageBox.Show("In the'Orginal and Desired Units' boxes, please enter only the numbers 1 -9, and in the 'Length to Covert' Box, please enter only numbers");
}
So as you can see in the button click event, i am at the part where the conversions should take place. My question, once again, is what would be the best method i should use to handle all of these calculations? I already have 1 if statement, and if i am going to do if statements, i feel as if it will be very tedious and was wondering if there was a more efficient way of doing this. Thanks for your help guys, i really do appreciate it.
The best approach is to use a little math to avoid conditionals altogether.
No matter what's the original and target units are, you can do the conversion through by converting the original units to feet and then converting feet to the target unit.
Let's say you want to go from X units at index i to units at index j. All you need to do is dividing X by units[i], and multiplying by units[j]. No conditionals or switches are required.
How would the program know which unit to choose?
This depends on the organization of your program. This could be a very simple task if you use drop-down boxes for unit names in your UI, because the index of the selected item will be the same as the index of the conversion rate in the units[] array.
Given this specific example, if statements and switch statements are both redundant.
Another way to solve this would be to create a mapping table (two dimensional array) where you specify the conversion multiplier between both units especially that your code already uses digits to represent units instead of their actual names.
For example
C[1][1] = 1;
C[1][2] = 3.1;
C[1][3] = 5;
C[1][4] = 0.33;
C[2][1] = 1/C[1][2];
....
....
C[4][1] = 1/C[1][4];
After creating that array, you can simply plugin the numbers depending on the source and destination currencies to do the conversion.
You can further improve on the above by creating one or two if statement that check whether the first parameter for the array is less than the second or not. If yes, then take the value as it is, if not take the reciprocal of the value. Therefore, you dont have to fill the entire array with values such as:
C[2][1] = 1/C[1][2];
C[4][1] = 1/C[1][4];
Hope that helped.
Related
This question already has answers here:
Edit a specific Line of a Text File in C#
(6 answers)
Closed 3 years ago.
I'm making a small game and I'm having trouble saving the result of the game into a text file.
I have tried reading only the needed line but with little success:
List<string> a = File.ReadLines(path).Skip(2).Take(2).ToList();
Text file has 4 lines inside it:
PlayerTag
Wins: 0
Losses: 0
Draws: 0
After the player wins I want increase the amount of wins by 1.
What would be the ideal way to do this?
With the current format, you could do the following.
var str = File.ReadAllLines(filePath);
str[WinPosition] = Update(str[WinPosition]);
File.WriteAllLines(filePath);
Where WinPosition is a constant defined as
const int WinPosition = 1;
const int LossesPosition = 2;
const int DrawsPosition = 3;
And Update is defined as
private string Update(string source)
{
var data = source.Split(':');
data[1] = (Int32.Parse(data[1])+1).ToString();
return string.Join(":",data);
}
The Update method would read the string, split it based on the delimiter (":") and then update the numeric part. Together, the constants and common update method would allow you to update Losses and Draws in the same way as Wins (and perhaps more readable than using 1/2/3 indices directly).
str[LossesPosition] = Update(str[LossesPosition]);
str[Draws] = Update(str[Draws]);
Having said so, If you have the option changing the format of the file, I would suggest you opt for Json or Xml. This would be a better approach than using the current format.
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'm doing a counting program and i need to multiple all digits of x number by it self.
for example: number 123456789;
1*2*3*4*5*6*7*8*9=362,880
A good solution is provided in the comments, but it isn't very easy to follow if you are trying to figure out what you are actually doing. The following code is a bit more verbose, but shows you what is actually happening each step of the way:
using System;
class MainClass {
public static void Main () {
int myNumber = 123456789; //store original number
int newNumber = (int)Math.Abs(myNumber); //changes the number to positive if it is negative to prevent string formatting errors.
int product = 1; //store product start point
string myString = newNumber.ToString(); //convert number to string
foreach(char number in myString){ //loop through string
string numberString = number.ToString(); //convert chars to strings to ensure proper output
int oneDigit = Convert.ToInt32(numberString); //convert strings to integers
product = product*oneDigit; //multiply each integer by the product and set that as the new product
}
if(myNumber < 0){product = -product;}
//if the number is negative, the result will be negative, since it is a negative followed by a bunch of positives.
//If you want your result to reflect that, add the above line to account for negative numbers.
Console.WriteLine(product); //display product
}
}
Output>>> 362880 //The output that was printed.
So we start by converting our number into a string so we can iterate through it. Then we have a foreach loop that goes through each character in the string, converts it into an integer, and multiplies it by the product of the previous numbers. Each time a new multiplication is performed, the product is updated, until, when you reach the end of the number, you have the product of all digits. This is a good project to become familiar with looping. I would recommend playing around with variations of it such as multiplying each number by the original number, multiplying together only multiples of 3, only multiplying numbers less than 5, or only multiplying the first 5 numbers to get a better handle on what's happening in a loop.
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 4 years ago.
Improve this question
Hi I need to work out the average of 10 integers stored in a database.
This is what I've got so far.
private void getAverage()
{
StudentsDataSet.StudentsRow courseMarks = studentsDataSet.Students.Course[10];
average = 0;
int[] array;
for (int index = 0; index < 10 ; index++)
{
average += array[index];
}
average = average / 10;
averageBox.Text = average.ToString();
}
As you can see I have no idea what I'm doing... any pointers??
There are a couple of issues with your code, which I will address one by one:
You are always getting the data from row 11 of your data table (studentsDataSet.Students.Course[10]). That's probably not what you want.
You are declaring your array but you are not initializing it.
You need to fill the array before you loop over it.
You are repeating the number of courses (10) in many places in your code (e.g. the for loop and the divisor of the average). This will be a source of errors when the number of courses changes.
Be careful to choose good names for your variables. average should be sum (that's what it actually stores) and array is a poor choice, because it does not describe the content of the variable, but its format.
According to the C# naming convention methods are in PascalCase.
Here is some code that will do the job. I have added comments to explain exactly what is happening:
//The method that will add the average to the text box. You need to provide the row index.
//One common way to get the row index would be the SelectedIndex of your data grid
private void GetAverage(int rowIndex)
{
//Get the row whose data you want to process
DataRow courseMarks = studentsDataSet.Students.Rows[rowIndex];
//Initialize an array with the names of the source columns
string[] courseColumnNames = { "Course1", "Course2", "Course3", "Course4", "Course5",
"Course6", "Course7", "Course8", "Course9", "Course10" };
//Declare and initialize the array for the marks
int[] markValues = new int[courseColumnNames.Length];
//Fill the array with data
for (int index = 0; index < courseMarks.Length ; index++)
{
//Get the column name of the current course
string columnName = courseColumnNames[index];
//Copy the column value into the array
markValues[index] = (int)courseMarks[columnName];
}
//Calculate the sum
int sum = 0;
for (int index = 0; index < courseMarks.Length ; index++)
{
sum += markValues[index];
}
//Calculate the average from the sum
//Note: Since it's an integer division there will be no decimals
int average = sum / courseMarks.Length;
//Display the data
averageBox.Text = average.ToString();
}
Note that of course you could merge the two loops into one (and even drop the array, since you could just directly add to the sum variable). I have not done that to keep every step of the process clearly separated. You could also use the LINQ method Average, but that would quite miss the point here.
Instead of all your codes, you may try this:
private double GetAverage()
{
StudentsDataSet.StudentsRow courseMarks = studentsDataSet.Students.Course[10];
var average=courseMarks.Average(x =>(double) x["*YourDataColumnName*"]);
return average;
}
Where YourDataColumnName is the column of your row which contains the value you want to get average of that
You could do the following :
int average = studentsDataSet.Students.Course.Average();
You would have to add using System.Linq; for this to work.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I read knuth's algorithm in wikipedia and I wonder about the 3rd step. If I understand correct for each option (even if not removed in step 2), we calculate how many possible guesses would have removed for every ffedback. for that step we take minimum. after, we find the maximum on the minimums and take the code the max belong to it. that will be our second guess. Im not sure what can be done next because,each time we dont change the max on the minimums (or what is the minimum). In addition, how can I implement this step in c# for example. How can I procceed and how can I implement that step? What does the minimum on the feedbacks really mean?
You need a constant collection of all possible outcomes, a collection of the remaining alternatives, and a method that can compute the outcome given a guess and a solution.
First, model the relevant domain objects:
public class Outcome
{
public int White { get; set; }
public int Black { get; set; }
}
public class Combination
{
// however you like to model this
}
Then, create the method that checks the guess against the secret:
public static Outcome Check(Combination guess, Combination solution)
{
// your implementation
}
Now the algorithm is as follows:
Outcome[] outcomes = new[] { new Outcome { White = 0, Black = 0 },
new Outcome { White = 1, Black = 0 },
// ... all other possibilities
};
// assume we have some list of combinations
int min = Integer.MaxValue;
Combination minCombination = null;
foreach (var guess in combinations)
{
int max = 0;
foreach (var outcome in outcomes)
{
var count = 0;
foreach (var solution in combinations)
{
if (Check(guess, solution) == outcome)
count++;
}
if (count > max)
max = count;
}
if (max < min)
{
min = max;
minCombination = guess;
}
}
At the end of the loop, minCombination is your next guess.
EDIT I messed up min and max in the first version, that is fixed now. The inner count gives the number of remaining options, provided the chosen combination and the assumed outcome. We want the maximum over the outcomes (the worst possible result for the chosen combination is the one that leaves most options remaining). After that we want the minimum over the combinations (the best possible combination is the one that leaves least options remaining in the worst case).
If you like Linq, you could also write the algorithm as
combinations.MaxBy(guess =>
outcomes.Min(outcome =>
combinations.Count(solution =>
Check(guess, solution) == outcome)));
in which I used MaxBy from the MoreLinq project.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I’m no programmer but I’m learning C# to build a foreign exchange trading system and Arrays are being a struggle…
The problem I have is the following…
I have a one dimensional Array with, let’s say, 100 elements in it.
Now I need to build another one dimensional array with a 10 elements rolling average based on the first Array.
Said in another way, I need to take the elements from the first Array starting in i = 0 up to i = 9 and average them and save the average in a new array. Than move one step forward and take i = 1 up to i = 10 from the original Array and average them and save the result in the new Array….and so forth….in Excel this would be extremely easy….
My need to have the data in Arrays is because later I will need to compare the last 10 elements rolling average with historical data….
Please, can anyone build a sample code that I can work with?
Many thanks
Paulo
Maybe something like this could work... Did this on my mac in sublime text so you'll still have to work with. Should get the point though.
public class Foo
{
List<int> main = new List<int>(100);
List<int> rollingAverages = new List<int>(100);
public void Add(int score)
{
main.Add(score);
if(main.Count > 10)
{
int rollingAverage = AverageLast10();
rollingAverages.Add(rollingAverage);
}
}
public int AverageLast10()
{
int sum = 0;
for(int i = main.Count - 10; i < 10; i++)
{
sum += main[i];
}
return sum / 10;
}
}
Somewhere else in the code
Foo foo = new Foo();
foo.Add(94);
foo.Add(94);
...
yadda yadda yadda