这两个练习虐了我好几天,这个程序的思路是先计算一共有多少个单词,然后找出最大值,然后计算需要打印多少个,最后是打印直方图。
前面的这些跟之前的单词计数差不多,只是改进了一点挺好理解的。
while ((c = getchar()) != EOF){
if (' ' == c || '\n' == c || ' \t' == c){ 这里判断是否是单词分隔符
state = OUT; 如果是就把状态改为OUT
if (nc > MAXWORD) 是否超出单个单词最大字符数
++wl[nc];如果没超过则对编号第nc的元素加一
else
++ovflow; 如果超出则对用于记录超出的变量加一。
}
else if (OUT == state){ 这里是如果上面的判断不成功也就是说不是上面的单词分隔符则进行此条判断。判断是否是单词的第一个字母,因为如果不是单词分隔符并且状态还是在单词外的话肯定就是第一个字母了。
state = IN; 如果上面判断成功也就是说是在单词外则将状态改成在单词内。
nc = 1; 然后将用于计算单词长度的变量变为1,因为是第一个字母所以长度就是1.
以上是统计所有输入的单词长度的。将各个长度出现的次数记录在wl数组内。
maxvalue = 0;
for (i = 1; i < MAXWORD; ++i)
if (wl[i] > maxvalue)
maxvalue = wl[i]
找出wl数组内的最大值也就是出现频率最高的那个。
这里之所以要找最大值,我在网上查了一下,是因为如果某个单词长度出现的次数太多,很有可能会超出整个屏幕。所以找出最长的那个将其定义为某个长度,之后就是将剩下的以最长的为基准按比例缩小。比如说某个长度的单词出现四次另一个长度的单词出现两次还有一个长度的单词出现一次,将出现四次的单词在打印的时候定义为长度20那么出现两次的长度就为10,出现一次的长度则为5.
貌似叫归一法?
if (wl[i] > 0){
if ((len = wl[i] * MAXHIST / maxvalue) <= 0)
len =1;
}
else
len = 0;
len = wl[i] * MAXHIST / maxvalue这个公式是对len进行赋值,赋值之后再判断,wl[i]是某个单词出现次数除以最大值maxvalue就是跟最多出现次数的比例是多少,然后再乘以直方图的最大长度就是这个公式了,把上面的例子代入就是wl[i]是1也就是出现一次,除以最多出现次数4.比例为1/4,再乘以直方图最大长度为20.等于5.这就是这个公式的意思。
对len进行赋值之后 <=0这个条件正常情况下应该为假,但是非正常情况下也会给len赋值为1。这是想单词出现了一次,那么至少打印店东西。
之后就是判断有len是多少。然后每打一个就减去1.
网友评论