我正在尝试编写一个表示条形图的频率程序(在控制台代码中)。问题是我不知道如何准确地计算这个频率,或者我如何确切地根据它们的频率给出不同的高度(通过计算)。
频率高度上限为21,意味着条形从1到21,因此最大条形高度将是例如21星(*作为条形本身的显示符号)。
到目前为止,我对频率的计算(尽管不确定是否正确)如下,其中此数组采用生成的随机值:
for (int j = 0; j < T.Length; j++)
{
T[j] = (MaxHeight* T[j]) / Ber.GreatestElement(T);
Console.Write("{0,7}", T[j]);
}
这导致0到21之间的值。基于这些值,我的条形应该与所有其他频率值相比具有一定的高度。例如,8000可以有21个高度,其中39个可以有1)。
为了表示此图表,我使用了2个for
循环来显示高度和宽度(请记住,我只希望使用using System;
将其保持为“基础”)。
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();
}
到目前为止,我有一个完整的字段填充*和随机值及其频率值(虽然我不知道是否正确计算了频率值)。
我假设我在第二个if (...)
中需要一个for
,但我似乎无法超越这个。
答案 0 :(得分:2)
您的代码中有一些部分并未真正定义供我们分析,但您可以尝试基本的线性插值函数来实现沿某个范围的内插值(例如,映射0-> 8000到0-> 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;
}
因此,假设您测量的最小频率为450,最大值为8000,并且您希望将所有值映射到0到21的范围。您可以按照此行调用它(假设您当前的测量值是,比方说,2700):
float mappedValue = MapToRange(2700, 450, 8000, 0, 21);
这将产生:0 +((2700 - 450)/(8000 - 450))*(21 - 0)= 6.25827815
因此将此值转换为int并绘制6颗星。
答案 1 :(得分:1)
编辑: 对不起,我匆忙写了,我的解决方案错了,bufferz写了正确的。
即。 (以不太通用的方式)
int starsNum = (int)((currentValue - lowestValue)/(highestValue - lowestValue) * 21);
答案 2 :(得分:0)
所以,如果你从这样的代码开始,其中T是频率数组:
for (int j = 0; j < T.Length; j++)
{
T[j] = (MaxHeight* T[j]) / Ber.GreatestElement(T);
Console.Write("{0,7}", T[j]);
}
您希望能够获取此代码并将其表示在图表中,对吗?
为此,您需要捕获最大的T值,进行一些数学运算,然后将适当数量的星号写入屏幕:
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];
}
现在您拥有最大值,您可以通过SECOND for循环确定星数:
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, '*');
}
希望这就是你要找的东西。