对终端输入的行内容进行字典排序并把结果输出出来

案例描述:从终端输入一些字符,每行不超过1000个,一共不超过5000行,对输入的行进行字典排序,并把排序的结果按照顺序输出出来。

案例关键:1.指针数组和二维指针的应用;2.字典排序的算法,用快速排序。3.对输入输出的处理。

实现代码如下:

/***********************************************************************
    Copyright (c) 2015,wangzp
    All rights no reserved.
  
    Name: Sort the input lines from terminal
    ID:   The C Programming Language
    问题简述: 对输入的文本行按照字母在字典中的顺序进行排序。
 
    Date: Sep 23, 2015 
 
***********************************************************************/
#include 
   
   
    
    
#include 
    
    
     
     
#include 
     
     
      
      


#define MAXLINES 5000 /*能够存储的最大文本行数*/
#define MAXLEN 1000/*每行文本行的长度*/
char *lineptr[MAXLINES];/*指向文本行的指针*/

int readlines(char *lineptr[],int nlines);/*读文本行函数*/
void writelines(char *lineptr[],int nlines);/*写入文本行函数*/
void qsort(char *v[],int left,int right);/*文本行排序函数*/
int getline(char *s,int lim);
void swap(char *v[],int i,int j);

/*主函数*/
int main(void)
{
	int nlines;/*输入行数目*/
	if ((nlines = readlines(lineptr,MAXLINES)) >= 0)
	{
		qsort(lineptr,0,nlines - 1);
		writelines(lineptr,nlines);
		return 0;
	}
	else
	{
		printf("error:input too big to sort.\n");
		return 1;
	}
}



/***********************************************************************
    @author   : wzp
	@Name     : getline
    @Funcation: 将一行读入s[]中并返回其长度  
    @Date     : Sep 23, 2015 
***********************************************************************/
int getline(char s[],int lim)
{
	int c,i;
	for (i = 0;i < (lim -1) && (c = getchar()) != EOF && c != '\n';i++)
	{
		s[i] = c;
	}
	/*保存行末尾的回车*/
	if (c == '\n')
	{
		s[i] = c;
		i++;
	}
	s[i] = '\0';/*行结束*/
	return i;
}

/***********************************************************************
    @author   : wzp
	@Name     : readlines
    @Funcation: 读入行  
    @Date     : Sep 23, 2015 
***********************************************************************/

int readlines(char *lineptr[],int maxlines)
{
	int len,nlines;
	char *p,line[MAXLINES];

	nlines = 0;
	while ((len = getline(line,MAXLEN)) > 0)
	{
		if (nlines >= maxlines || (p = (char *)malloc(len)) == NULL)
		{
			return -1;
		}
		else
		{
			line[len -1] = '\0';//删除每一行的回车
			strcpy(p,line);//把终端输入的行内容拷贝到p指针指向的空间中
			lineptr[nlines++] = p;//保存当前行的指针,排序时只需要变化指针即可,不需要动行的内容
		}
	}
	return nlines;//返回读取了多少行
}

/***********************************************************************
    @author   : wzp
	@Name     : writelines
    @Funcation: 写输出行,即打印行
    @Date     : Sep 23, 2015 
***********************************************************************/

void writelines(char *lineptr[],int nlines)
{
	int i;
	for (i = 0;i < nlines;i++)
	{
		printf("%s\n",lineptr[i]);
	}
}

/***********************************************************************
    @author   : wzp
	@Name     : qsort
    @Funcation: 按照字典顺序对行进行增序排序 快速排序方法 
    @Date     : Sep 23, 2015 
***********************************************************************/
void qsort(char *v[],int left,int right)
{
	int i,last;
	
	if (left >= right)//递归结束条件
	{
		return;
	}
	swap(v,left,(left + right)/2);
	last = left;
	for (i = left + 1;i <= right;i++)
	{
		if (strcmp(v[i],v[left]) < 0)
		{
			swap(v,++last,i);
		}
	}
	swap(v,left,last);//恢复分区元素后递归调用排序算法
	qsort(v,left,last);
	qsort(v,last + 1,right);
}


/***********************************************************************
    @author   : wzp
	@Name     : swap
    @Funcation: 交换两个指针数组中的内容,注意交换的元素为指针 
    @Date     : Sep 23, 2015 
***********************************************************************/

void swap(char *v[],int i,int j)
{
	char *temp;
	temp = v[i];
	v[i] = v[j];
	v[j] = temp;
}



     
     
    
    
   
   
运行结果(按ctrl+z结束输入):



有一个问题,需要我们注意,我们使用了malloc函数为指针数组开辟了空间,使用完毕后,最好用free()函数把指针数组指向的空间给释放掉。下图调试简单说明了指针的存储情况:地址和内容:


另外需要说明的是free(p)函数只是释放指针p指向的空间内容,而p的地址还在,所以在free之后,需要把这些指针赋值为NULL,如果不赋值为NULL的话,就成了野指针,虽然对结果造不成影响,但如果不处理野指针的话,这样做不是一个好习惯。

实现代码如下:

/***********************************************************************
    Copyright (c) 2015,wangzp
    All rights no reserved.
  
    Name: Sort the input lines from terminal
    ID:   The C Programming Language
    问题简述: 对输入的文本行按照字母在字典中的顺序进行排序。
 
    Date: Sep 23, 2015 
 
***********************************************************************/
#include 
   
   
    
    
#include 
    
    
     
     
#include 
     
     
      
      


#define MAXLINES 5000 /*能够存储的最大文本行数*/
#define MAXLEN 1000/*每行文本行的长度*/
char *lineptr[MAXLINES];/*指向文本行的指针*/

int readlines(char *lineptr[],int nlines);/*读文本行函数*/
void writelines(char *lineptr[],int nlines);/*写入文本行函数*/
void qsort(char *v[],int left,int right);/*文本行排序函数*/
int getline(char *s,int lim);
void swap(char *v[],int i,int j);

/*主函数*/
int main(void)
{
	int nlines;/*输入行数目*/
	if ((nlines = readlines(lineptr,MAXLINES)) >= 0)
	{
		qsort(lineptr,0,nlines - 1);
		writelines(lineptr,nlines);
		
		/*查看内存释放情况*/
		printf("free内存块之前:\n");
		for (int i = 0;i < nlines;i++)
		{
			printf("%s\n",lineptr[i]);
		}
		printf("free内存块之后:\n");
		for (int i = 0;i < nlines;i++)
		{
			free(lineptr[i]);
			printf("%s\n",lineptr[i]);
		}
		printf("处理野指针之后:\n");
		for (int i = 0;i < nlines;i++)
		{
			lineptr[i] = NULL;
			printf("%s\n",lineptr[i]);
		}
		return 0;
	}
	else
	{
		printf("error:input too big to sort.\n");
		return 1;
	}
}



/***********************************************************************
    @author   : wzp
	@Name     : getline
    @Funcation: 将一行读入s[]中并返回其长度  
    @Date     : Sep 23, 2015 
***********************************************************************/
int getline(char s[],int lim)
{
	int c,i;
	for (i = 0;i < (lim -1) && (c = getchar()) != EOF && c != '\n';i++)
	{
		s[i] = c;
	}
	/*保存行末尾的回车*/
	if (c == '\n')
	{
		s[i] = c;
		i++;
	}
	s[i] = '\0';/*行结束*/
	return i;
}

/***********************************************************************
    @author   : wzp
	@Name     : readlines
    @Funcation: 读入行  
    @Date     : Sep 23, 2015 
***********************************************************************/

int readlines(char *lineptr[],int maxlines)
{
	int len,nlines;
	char *p,line[MAXLINES];
	nlines = 0;
	while ((len = getline(line,MAXLEN)) > 0)
	{
		
		if (nlines >= maxlines || (p = (char *)malloc(len)) == NULL)
		{
			return -1;
		}
		else
		{
			line[len -1] = '\0';//删除每一行的回车
			strcpy(p,line);//把终端输入的行内容拷贝到p指针指向的空间中
			lineptr[nlines++] = p;//保存当前行的指针,排序时只需要变化指针即可,不需要动行的内容
		}
	}
	return nlines;//返回读取了多少行
}

/***********************************************************************
    @author   : wzp
	@Name     : writelines
    @Funcation: 写输出行,即打印行
    @Date     : Sep 23, 2015 
***********************************************************************/

void writelines(char *lineptr[],int nlines)
{
	int i;
	for (i = 0;i < nlines;i++)
	{
		printf("%s\n",lineptr[i]);
	}
}

/***********************************************************************
    @author   : wzp
	@Name     : qsort
    @Funcation: 按照字典顺序对行进行增序排序 快速排序方法 
    @Date     : Sep 23, 2015 
***********************************************************************/
void qsort(char *v[],int left,int right)
{
	int i,last;
	
	if (left >= right)//递归结束条件
	{
		return;
	}
	swap(v,left,(left + right)/2);
	last = left;
	for (i = left + 1;i <= right;i++)
	{
		if (strcmp(v[i],v[left]) < 0)
		{
			swap(v,++last,i);
		}
	}
	swap(v,left,last);//恢复分区元素后递归调用排序算法
	qsort(v,left,last);
	qsort(v,last + 1,right);
}


/***********************************************************************
    @author   : wzp
	@Name     : swap
    @Funcation: 交换两个指针数组中的内容,注意交换的元素为指针 
    @Date     : Sep 23, 2015 
***********************************************************************/

void swap(char *v[],int i,int j)
{
	char *temp;
	temp = v[i];
	v[i] = v[j];
	v[j] = temp;
}



     
     
    
    
   
   
运行结果:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值