100 Days of Code-day6-C programming language

练习1-13

编写一个程序,打印输入中单词长度的直方图(水平方向)。
方法1

int main()
{
	int c,wlen,state,nw;
	int word[10] = { 0 };
	wlen = 1;
	state = OUT;
	nw = -1;//解决了Word[0]=0的问题
	while ((c=getchar())!=EOF)
	{
		if (c == ' ' || c == '\n' || c == '\t')
		{
			state = OUT;
		}
		else if (state == OUT)
		{
			state = IN;
			nw++;
			word[nw]++;
		}
		else
		{
			word[nw]++;
		}
	}
	for (nw = 0; nw < 10; nw++)
	{
		printf("%d ", word[nw]);
	}
	int i,j;
	printf("\n");
	for ( j = 0; j < 10; j++)
	{
		for (i = 1; i <= 7; i++)
		{
			printf(" ");
		}
		printf("|");
		for ( i = 1; i <= word[j]; i++)
		{
			printf("_");
		}
		printf("\n");
		printf("word %d |", j);
		for ( i = 1; i <= word[j]; i++)
		{
			printf("_");
		}
		printf("|");
		printf("\n");
	}
	return 0;
}

方法2

#include<stdio.h>
#define IN 1
#define OUT 0
#define MAXNUMBER 11
#define MAXHIST 15
int main()
{
	int c,i,nc,state;
	int overflow;
	int maxvalue;
	int nl[MAXNUMBER];
	nc = 0;
	state = OUT;
	overflow = 0;
	for (i=0;i< MAXNUMBER;i++)
	{
		nl[i] = 0 ;
	}
	while ((c=getchar())!=EOF)
	{
		if (c==' '||c=='\n'||c=='\t')
		{
			state = OUT;//在结束时,开始记录对应单词长度的个数
			if (nc > 0)
			{
				if (nc <= MAXNUMBER)
				{
					nl[nc]++;
				}
				else
				{
					overflow++;
				}
			}
			nc = 0;
		}
		else if (state==OUT)
		{
			state = IN;
			nc++;
		}
		else
		{
			nc++;
		}

	}
	maxvalue = 0;
	int len = 0;
	for (i=1;i< MAXNUMBER;i++)//find nl[i] maxvalue
	{
		if (nl[i] > maxvalue)
		{
			maxvalue = nl[i];
		}
	}
	for (i = 1; i < MAXNUMBER; i++)
	{
		if (nl[i] > 0)
		{
			if ((len = nl[i] * MAXHIST / maxvalue) <= 0)//此处将程序编的更加简单
				//len = nl[i] * MAXHIST / maxvalue这样的赋值操作是一个表达式
				//因此可以作为更大表达式的一部分出现,所以说len并不是只在if分支语句中起作用的局部变量。
				//这里进行完该操作语句后,持续进行while循环语句。

				//同时,该语句可以看成len = nl[i] / maxvalue * MAXHIST,nl[i]表示长度为i单词的个数
				//maxvalue表示最大频数,两者之比再乘以直方图最大高度,所以得到的便是相应高度。
				//同时这样也起到了限制打印长度的作用
			{
				len = 1;
			}
		}
		else
		{
			len = 0;
		}
		while (len > 0)
		{
			putchar('*');
			len--;
		}
		putchar('\n');
	}
	if (overflow > 0)
	{
		printf("there are %d words >=%d\n",overflow,MAXNUMBER);
	}
	return 0;
}

注意:上面程序中的这部分程序段,此处是为了防止nl[i] * MAXHIST的结果溢出.也就是说int类型值的范围是-231 ~ 231-1即-2147483648~2147483647。当nl[i]>2147483647/MAXHIST=143165576时,就会出现溢出。此时len<0,表明长度为i的行出现的次数已经超出int类型的限制。
改进:可以直接定义一个符号常量限制一下nl[i]的最大值maxvalue。

if (nl[i] > 0)
		{
			if ((len = nl[i] * MAXHIST / maxvalue) <= 0)
			{
                len = 1;
            }
 }

C programming language 练习1-16

#define MAXLINE 1000
int getline(char s[], int lim);
void copy(char to[], char from[]);
int main()
{
	int len=0;
	int max=0;
	char line[MAXLINE];
	char longest[MAXLINE];
	while ((len=getline(line, MAXLINE))>0)
	{
		printf("%d,%s", len,line);
		if (len > max)
		{
			max = len;
			copy(longest,line);
		}
	}
	if (max > 0)
	{
		printf("%d\n", max);
		printf("%s\n", longest);
	}
	return 0;
}
int getline(char s[], int lim)
{
	int c,i,j;
	j = 0;
	for (i=0;(c=getchar())!=EOF && c != '\n';i++)
			//由于题目当中说要可以打印任意长度的输入行长度,并尽可能打印其文本
			//所以不用检查字符数是否超出数组s的限制,变量i记录输入行的长度,其值完全可以大于lim-1
			//这里的变量j只是为了防止数组s发生数据溢出。也就是因为要为'\0','\n'这两个字符留下存储空间
			//所以在下标为lim-2的元素处不能再填入输入内容,但依旧可以计入输入行的长度
			//只不过多出来的输入内容不放在数组s中罢了
	{
		if (i<lim-2)
		{
			s[j] = c;//还能读入字符,表明行目前还在边界内
			j++;
		}
	}
	if (c == '\n')
	{
		s[j] = c;
		j++;
		i++;
	}
	s[j] = '\0';
	return i;
}
void copy(char to[], char from[])
{
	int i = 0;
	while ((to[i]=from[i])!='\0')
	{
		i++;
	}
}

练习1-18

#define MAXLINE 1000
int getline(char s[], int lim);
int remove(char s[]);
int main()
{
	int len = 0;
	char line[MAXLINE];
	while ((len=getline(line,MAXLINE))>0)
	{
		if (remove(line) > 0)
		{
			printf("%d,%s", remove(line),line);
		}
		else
		{
			printf("%d\n", remove(line));
		}
	}
	return 0;
}
int remove(char s[])
{
	int i=0;//变量i代表字符长度,末尾的字符为'\0',所以不能计入在长度内
			//所以变量i初始值为0,而不是1。getline函数同理。
	while (s[i]!='\n')//首先找到换行符
	{
		i++;
	}
	i--;//从'\n'往回倒退一个位置
	while (i >= 0 && (s[i] == ' ' || s[i] == '\t'))//循环读取,直到读取的数组元素不是空格或者是制表符
												   //同时字符串还要有元素可以读取
	{
		i--;
	}//若一行都是空格或制表符,则返回的长度为-1
	//while循环条件中的i >= 0若改为i>0,返回值为0。而正常情况最终系统也返回0
	//为了区分这两种情况,所以这里是i >= 0
	if (i >= 0)
	{
		i++;
		s[i] = '\n';
		i++;
		s[i] = '\0';
	}
	return i;
}
int getline(char s[], int lim)
{
	char c;
	int i = 0;
	int j = 0;
	while ((c = getchar())!=EOF && c != '\n')
	{
		i++;
		if (i<lim-2)
		{
			s[j] = c;
			j++;
		}
	}
	if (c == '\n')
	{
		s[j] = '\n';
		j++;
		i++;
	}
	s[j] = '\0';
	return i;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值