Frequency Table with Random Values
I am trying to write a frequency program that will represent a bar diagram (in console code). The problem is I have no idea how exactly to calculate this frequency or how do I exactly then give the bars different heights according to their frequency (trough calculation).
The frequency height is capped at 21, meaning the bars go from 1 to 21, so the max bar height would be for example 21 stars (* as display sign for the bar itself).
A calculation I have so far (although not sure if correct) for frequency is the following, where this array takes the random values generated:
for (int j = 0; j < T.Length; j++)
{
T[j] = (MaxHeight* T[j]) / Ber.GreatestElement(T);
Console.Write("{0,7}", T[j]);
}
This results in values between 0 and 21. Based on the values my bars 开发者_运维技巧should give a certain height compared to all the other frequency values. For example, 8000 could have 21 in height where 39 could have 1).
To represent this diagram I used 2 for
loops to display height and width (keep in mind I only wish to use using System;
to keep it to the "basics").
for (int height= 1; height<= 21; height++)
{
for (int width= 0; width<= 10; width++)
{
if(...??)
{
Console.Write("{0,7}", bar); // string bar= ("*");
}
else
{
Console.Write("{0,7}", empty);
}
}
Console.WriteLine();
}
So far I have an entire field filled with * and the random values generated along with their frequency value (although I have no idea if the freq value is properly calculated).
I assume I need an if (...)
in the second for
but I cannot seem to get further than this.
There are some bits of your code that aren't really defined for us to analyze, but you could try a basic linear interpolation function to achieve interpolated values along a range (e.g. mapping 0->8000 to 0->21).
public static float MapToRange(float valueMeasured, float minMeasured, float maxMeasured, float minMapped, float maxMapped)
{
float mappedValue = minMapped + ((valueMeasured - minMeasured)/(maxMeasured - minMeasured)) * (maxMapped - minMapped);
return mappedValue;
}
So let's say you measured a minimum frequency of 450, a maximum of 8000, and you want to map all values to a range of 0 to 21. You could call it along the lines of this (assuming your current measurement is, say, 2700):
float mappedValue = MapToRange(2700, 450, 8000, 0, 21);
This would yield: 0 + ((2700 - 450)/(8000 - 450)) * (21 - 0) = 6.25827815
So cast this value as an int and draw 6 stars.
EDIT: sorry I wrote in a hurry and my solution was wrong, bufferz wrote the correct one.
i.e. (in a less generic way)
int starsNum = (int)((currentValue - lowestValue)/(highestValue - lowestValue) * 21);
So, if you start with code like this, where T is the array of frequencies:
for (int j = 0; j < T.Length; j++)
{
T[j] = (MaxHeight* T[j]) / Ber.GreatestElement(T);
Console.Write("{0,7}", T[j]);
}
You would want to be able to take this code and represent it ina graph, correct?
To do so, you'll want to capture the largest T value, do a bit of math, then write the appropriate number of stars to the screen:
double max = 0.0;
for (int j = 0; j < T.Length; j++)
{
T[j] = (MaxHeight* T[j]) / Ber.GreatestElement(T);
if (T[j] > max) max = T[j];
}
Now that you have the max value, you can determine the number of stars through a SECOND for loop:
for (int j = 0; j < T.Length; j++)
{
int numStars = Convert.ToInt32((max / 21) * T[j]);
Console.Write("{0,7}", T[j]);
Console.WriteLine("".PadLeft(numStars, '*');
}
Hope that is what you're looking for.
精彩评论