代码改变世界

Getting started with the basics of programming exercises_1

2015-04-23 16:07  星星之火✨🔥  阅读(266)  评论(0)    收藏  举报

1、编写一个将输入复制到输出的程序,并将其中连续的多个空格用一个空格代替

  使用if 结构:

#include<stdio.h>
#define NONBLANK 'a'; 
// repalce string of blanks with a single blank
int main(void)
{ 
	int c, lastc; // c负责记录当前输入字符的ASCII值, lastc记录前一个输入字符的ASCII值

	lastc = NONBLANK; // 符号常量NONBLANK负责把lastc初始化为一个任意的非空格字符
	while((c = getchar()) != EOF)
	{
		if(c != ' ')
			putchar(c);
		if(c == ' ')
			if(lastc != ' ') // 输出一个或一串空格中的第一个空格
				putchar(c);
		lastc = c;
		
	}
	return 0;
}

  使用if-else 语法结构:

#include<stdio.h>
#define NONBLANK 'a'; 
int main(void)
{ 
	int c, lastc; 

	lastc = NONBLANK; 
	while((c = getchar()) != EOF)
	{
		if(c != ' ')
			putchar(c);
		else if(lastc != ' ')
			putchar(c);
		lastc = c;
		
	}
	return 0;
}

  使用逻辑或(||)操作符:

#include<stdio.h>
#define NONBLANK 'a'; 
int main(void)
{ 
	int c, lastc; 

	lastc = NONBLANK; 
	while((c = getchar()) != EOF)
	{
		if(c != ' ' || lastc != ' ')
			putchar(c);
		lastc = c;
		
	}
	return 0;
}

2、单词计数

  要求统计行数、单词数与字符数,这里单词的定义比较宽松,它是任何其中不包含空格、制表符或换行符的字符序列。

#include<stdio.h>
#define IN 1 // inside a word
#define OUT 0 // outside a word
/* count lines, words, and characters in input */
int main(void)
{
	int c, nl, nw, nc, state;

	state = OUT;
	nl = nw = nc = 0;
	while((c = getchar()) != EOF)
	{
		++nc;
		if(c == '\n')
			++nl;
		if(c == ' ' || c == '\n' || c == '\t')
			state = OUT;
		else if(state == OUT) // 每当遇到单词的第一个字符, 它就作为一个新单词加以统计
		{
			state = IN;
			++nw;
		}
	}
	printf("%d %d %d\n", nl, nw, nc);
	return 0;
}

 Question: 如何测试程序?

 首先进行常规测试,然后测试边界条件,对于该程序而言,边界条件有:

  没有输入

  没有单词(只有换行符)

  没有单词(只有空格、制表符和换行符)

  每个单词各占一行(没有空格和制表符)

  单词出现于文本行行首

  单词出现于一串空格之后的情况

 3、编写一个程序,以每行一个单词的形式打印其输入

#include<stdio.h>
#define IN 1 // inside a word
#define OUT 0 // outside a word
// print input one word per line
int main(void)
{
	int c, state; // state: 记录程序的处理过程是否正处于某个单词的内部
	
	state = OUT;
	while((c = getchar()) != EOF)
	{
		if(c == ' ' || c == '\n' || c == '\t')
		{
			if(state == IN)
			{
				putchar('\n'); // finish the word
				state = OUT;
			}
		}
		else if(state == OUT)
		{
			state = IN; // beginning of word
			putchar(c);
		}
		else 
			putchar(c); // inside a word
		state = IN;
	}
}

 下面是我画的一个流程图:

4、编写程序,打印输入中单词长度的直方图

  水平方向的直方图:

#include<stdio.h>
#define MAXHIST 15 // max length of histogram
#define MAXWORD 11 // max length of a word
#define IN 1 // inside a word
#define OUT 0 // outside a word
// print horizontal histogram
int main(void)
{
	int c, i, nc, state;
	int len; // length of each bar
	int maxvalue; // maximum value for wl[]
	int ovflow; // number of overflow words
	int wl[MAXWORD]; // word length counters
	
	state = OUT;
	nc = 0; // number of chars in a word
	ovflow = 0; // number of words >= MAXWORD
	for(i = 0; i < MAXWORD; ++i)
		wl[i] = 0;
	while((c = getchar()) != EOF)
	{
		if(c == ' ' || c == '\n' || c == '\t')
		{
			state = OUT;
			if(nc > 0)
				if(nc < MAXWORD)
					++wl[nc];
				else
					++ovflow;
			nc = 0;
		}
		else if(state = OUT)
		{
			state = IN;
			nc = 1; // beginning of a new word
		}
		else
			++nc; // inside a word
	}

	maxvalue = 0;
	for(i = 1; i < MAXWORD; ++i)
		if(wl[i] > maxvalue)
			maxvalue = wl[i];
	
	for(i = 1; i < MAXWORD; ++i)
	{
		printf("%5d - %5d : ", i, wl[i]);
		if(wl[i] > 0)
		{	// 变量len根据MAZHIST和maxvalue的值计算得出的wl[i]所对应的直方图长度, 如果wl[i]大于零,就至少打印一个星号
			if((len = wl[i] * MAXHIST / maxvalue) <= 0) // 收获: <= 之间不能有空格
				len = 1;
		}
		else 
			len = 0;
		while(len > 0)
		{
			putchar('*');
			--len;
		}
		putchar('\n');
	}
	if(ovflow > 0)
		printf("There are %d words >= %d\n", ovflow, MAXWORD);
	return 0;
}

  由于垂直方向的所有直方图需要同步打印,所以垂直方向的比较难控制,注意与上述程序的区别:

#include<stdio.h>
#define MAXHIST 15 // max length of histogram
#define MAXWORD 11 // max length of a word
#define IN 1 // inside a word
#define OUT 0 // outside a word
// print horizontal histogram
int main(void)
{
	int c, i, j, nc, state;
	int len; // length of each bar
	int maxvalue; // maximum value for wl[]
	int ovflow; // number of overflow words
	int wl[MAXWORD]; // word length counters
	
	state = OUT;
	nc = 0; // number of chars in a word
	ovflow = 0; // number of words >= MAXWORD
	for(i = 0; i < MAXWORD; ++i)
		wl[i] = 0;
	while((c = getchar()) != EOF)
	{
		if(c == ' ' || c == '\n' || c == '\t')
		{
			state = OUT;
			if(nc > 0)
				if(nc < MAXWORD)
					++wl[nc];
				else
					++ovflow;
			nc = 0;
		}
		else if(state = OUT)
		{
			state = IN;
			nc = 1; // beginning of a new word
		}
		else
			++nc; // inside a word
	}

	maxvalue = 0;
	for(i = 1; i < MAXWORD; ++i)
		if(wl[i] > maxvalue)
			maxvalue = wl[i];
	
	for(i = MAXHIST; i > 0; --i)
	{
		for(j = 1; j < MAXWORD; ++j)
			if(wl[j] * MAXHIST / maxvalue >= i)
				printf("   * ");
			else 
				printf("     ");
		putchar('\n');
	}
	for(i = 1; i < MAXWORD; ++i)
		printf("%4d ", i);
	putchar('\n');
	for(i = 1; i < MAXWORD; ++i)
		printf("%4d ", wl[i]);
	putchar('\n');
	if(ovflow > 0)
		printf("There are %d words >= %d\n", ovflow, MAXWORD);
	return 0;
}