动态数组 系列操作实现——C语言(创建、插入、删除、排序、复制、唯一化)

 

【实验目的】

实现动态数组创建、元素插入、元素删除、数组复制唯一化排序归并排序(自下而上)、选择排序)。

 

【实验内容】

  1. 实现一个元素类型为char的动态数组,动态数组的初始容量假设为3。
  2. 实现动态数组的创建与删除、元素插入、元素删除、动态素组的唯一化。
  3. 给出序列“CDACDDCECBAABCDCEBCB”的唯一化(Deduplication)结果。
  4. 可以基于读入某一文件中的字符串。(如:读取Test.txt文件)
  5. 实现归并排序。(自下而上归并排序)
  6. 实现选择排序。
  7. 实现不同元素出现次数的统计。

【实验要求】

  1. 将上述序列存入动态数组,给出最终动态数组的容量和规模。(请读者自行调整输出)
  2. 给出在存入上述序列的过程中动态数组调用扩容函数的次数。
  3. 计算并输出上述序列的唯一化序列。
  4. 对计算所得的归一化序列,选择排序。
  5. 对于外部文件中的大量字符排序(归并排序)。(如:对基因的排序)

(下面附上代码)

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define inti_len 3	/*初始化数组长度(初始化长度为3)*/ 
#define dn_lim 0.25	/*下限百分比(若使用的数组长度小于总可用长度的25%,则总可用长度缩小为原来的1/2)*/ 
#define Default -1	/*插入函数、删除函数 中的参数;表示末尾*/ 

char* Create_arr (int len);
int Copy_arr (char* From_store,int len,int total_store_len,char** To_store);
int Insert_element (char** store,int* len_p,int total_store_len,char ch,int position);
int Del_element (char** store,int* len_p,int total_store_len,int position);
int Sort_arr (char* store,int now_store_len);  
int sort_2arrs(char* store_haed,int len1,char* store_tail,int len2); 
int merge_sort(char* store,int now_store_len);
int Unique_arr (char* store,int len,int total_store_len,char** store_unique);
int Frequency_conter (char* store,int now_store_len,int total_store_len);
void Free_arr(char* store);

int Expand_time = 0;//动态数组扩张次数 
int Shrink_time = 0;//动态数组收缩次数

/*	
author:YXP
e-mail:yxp189@protonmail.com
如有问题,欢迎和我联系~ 
*/

int main(int argc, char *argv[]) 
{
    Expand_time = 0;
	Shrink_time = 0;
	clock_t start, finish;//用于计时 
	int total_store_len = inti_len,now_store_len = 0;//总的可用储存空间,当前使用的长度 
	int new_len;
	char *STORE = "CDACDDCECBAABCDCECB";//待处理字符串 
	char* store = Create_arr (inti_len);
	
	
	int i;
/***** 动态读入元素 *****/
printf ("/***** 动态读入元素 *****/\n");
	while (STORE[i]!='\0'){
			total_store_len = Insert_element (&store,&now_store_len,total_store_len,STORE[i],Default);
			/*每次插入一个元素;Insert_element函数详解,见插入操作*/
			i++;
	}
	for (i=0;i<now_store_len;i++){
		printf (">>%c",store[i]);		
	}
	printf ("\n");


/****** 唯一化操作 ******/
printf ("/****** 唯一化操作 ******/\n");
	char* store_unique;
	int uni_len = Unique_arr (store,now_store_len,total_store_len,&store_unique);
	/*Unique_arr (数组*,现在使用的长度,可用空间总长,用于储存归一化结果的数组**);*/ 
	for (i=0;i<uni_len;i++){
		printf (">>%c",store_unique[i]);		
	}
	printf ("\n");

/******* 排序操作 ******///(选择排序)
printf ("/******* 选择排序 *******/\n");
	Sort_arr (store_unique,uni_len);
	for (i=0;i<uni_len;i++){
		printf (">>%c",store_unique[i]);		
	}
	printf ("\n");


/******* 插入操作 ******/
printf ("/******* 插入操作 ******/\n");
	total_store_len = Insert_element (&store,&now_store_len,total_store_len,'$',Default);
	/*Insert_element (数组**,现在使用的长度*,可用空间总长,待插入的字符,插入位置(Default表示末尾));*/
	for (i=0;i<now_store_len;i++){
		printf (">>%c",store[i]);		
	}
	printf ("\n");			


/******* 删除操作 ******/
printf ("/******* 删除操作 ******/\n");	
	total_store_len = Del_element (&store,&now_store_len,total_store_len,0);//删除位置为0的元素 
	/*Del_element (数组**,现在使用的长度*,可用空间总长,待插入的字符,删除位置(Default表示末尾));*/
	for (i=0;i<now_store_len;i++){
		printf (">>%c",store[i]);		
	}
	printf ("\n");
	
/******* 复制操作 ******/
printf ("/******* 复制操作 ******/\n");
	char* Copy_store;
	int new_total_store_len = Copy_arr (store,now_store_len,total_store_len,&Copy_store); 
	/*Del_element (数组*,现在使用的长度*,可用空间总长,拷贝到的数组*);*/ 
	for (i=0;i<new_total_store_len;i++){
		printf (">>%c",Copy_store[i]);		
	}
	printf ("\n");
	
/*** 数组当前操作次数 ***/
	printf (">>自动扩容%d次\t自动收缩%d次\n\n",Expand_time,Shrink_time);

/*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*/
/*****************************************************/
/******* 对于文件处理+排序操作 ******///(选择/归并排序+计时)
	Expand_time = 0;
	Shrink_time = 0;
	char ch; 
    char* r_filename = "Test.txt";
	char* w_filename = "result.txt";
	FILE* fp_c,*fp_w,*fp_r =fopen(r_filename, "r");
        
/***** 动态读入元素 *****/
	printf (">>动态读入元素\n");
	start = clock();
	while ((ch = fgetc(fp_r)) != EOF){
			total_store_len = Insert_element (&store,&now_store_len,total_store_len,ch,Default);
			/*每次插入一个元素;Insert_element函数详解,见插入操作*/
			i++;
	}
	finish = clock();
	printf (">>读入扩容用时%lf\n",(double)(finish-start)/CLK_TCK);
	printf (">>自动扩容%d次\t自动收缩%d次\n\n",Expand_time,Shrink_time);
	fclose(fp_r);
	printf ("\n");
	
	fp_w = fopen(w_filename, "w"); 	
	
/******* 选择/归并排序 *******/	
	printf (">>开始排序\n");
	start = clock();
	//Sort_arr (store,now_store_len);//选择排序 
	merge_sort (store,now_store_len);//归并排序 
	finish = clock();
	printf (">>排序用时%lf\n",(double)(finish-start)/CLK_TCK);
	for (i=0;i<now_store_len;i++){
		fprintf (fp_w,"%c",store[i]);		
	}
	printf (">>排序完成!见文件result.txt!\n");
	fclose(fp_w);  

/*****************************************************/
/*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*/

/*****元素出现次数统计*****/
Frequency_conter (store,now_store_len,total_store_len);

	return 0;
}



char* Create_arr (int len)/*创建一个指定大小的数组*/ 
{/*Create_arr (数组的长度)
	返回值 = 申请所得空间的地址*/ 
	char* store;
	store = (char*)malloc(sizeof(char)*len);
	return store; 
}


void Free_arr(char* store)/*用于创建一个指定大小的数组*/
{/*Free_arr(数组*)*/ 

	free(store);
}


int Copy_arr (char* From_store,int len,int total_store_len,char** To_store)/*用于数组复制*/ 
{/*Copy_arr (被拷贝数组*,被复制数组长度,可用空间总长n,拷贝所得数组**)
	返回值=拷贝所得数组大小;*/ 
 
	int new_total_store_len, i;
	if (len<total_store_len*0.25){
		new_total_store_len = (int)(len/2);
		*To_store = (char*)malloc(sizeof(char)*(new_total_store_len));
		for (i=0;i<len;i++){
			(*To_store)[i]=From_store[i];
		}
		Shrink_time++;
	}else{
		if ((len+1)>total_store_len){
			new_total_store_len = (len*2);
			*To_store = (char*)malloc(sizeof(char)*(new_total_store_len));
			for (i=0;i<len;i++){
				(*To_store)[i]=From_store[i];
			}
			Expand_time++;
		}else{
			new_total_store_len = len;
			*To_store = (char*)malloc(sizeof(char)*len);
			for (i=0;i<len;i++){
				(*To_store)[i]=From_store[i];
			}			
		} 
	}
	
	return new_total_store_len;
}


int Insert_element (char** store,int* len_p,int total_store_len,char ch,int position)/*用于在指定位置,插入指定元素*/ 
{/*	Insert_element (数组**,现在使用的长度*,可用空间总长,待插入的字符,插入位置(Default表示末尾));
	返回当前 最大存储空间
	注意:position start from 0;
		if position = Default,则指末尾;*/ 

	if ((*len_p+1)>total_store_len){
		char* temp_store;
		total_store_len = Copy_arr (*store,*len_p,total_store_len,&temp_store);
		Free_arr(*store);
		*store = temp_store;
		if (position == Default){
			(*store)[*len_p] = ch;
			(*len_p)++;
		}else{
			int i;
			for (i = (*len_p)-1;i>=position;i--){
				(*store)[i+1] = (*store)[i];
			}
			(*store)[position] = ch;
			(*len_p)++;
		}	
	}else{
		if (position == Default){
			(*store)[*len_p] = ch;
			(*len_p)++;
		}else{
			int i;
			for (i = (*len_p)-1;i>=position;i--){
				(*store)[i+1] = (*store)[i];
			}
			(*store)[position] = ch;
			(*len_p)++;
		}
	}

	return total_store_len;
}


int Del_element (char** store,int* len_p,int total_store_len,int position)/*用于删除指定位置元素*/ 
{/*	Del_element (数组**,现在使用的长度*,可用空间总长,待插入的字符,删除位置(Default表示末尾));
	返回当前 最大存储空间
	注意:position start from 0;
		if position = Default,则指末尾;*/ 

	int new_total_store_len;
	if ((*len_p-1)<(total_store_len*dn_lim)){
		char* temp_store;
		new_total_store_len = Copy_arr (*store,*len_p,total_store_len,&temp_store);
		Free_arr(*store);
		*store = temp_store;
		if (position == Default){
			(*len_p)--;
		}else{
			int i;
			for (i = position;i<(*len_p);i++){
				(*store)[i] = (*store)[i+1];
			}
			(*len_p)--;
		}	
	}else{
		new_total_store_len = total_store_len;
		if (position == Default){
			(*len_p)--;
		}else{
			int i;
			for (i = position;i<((*len_p)-1);i++){
				(*store)[i] = (*store)[i+1];
			}
			(*len_p)--;
		}
	}

	return new_total_store_len;
}


int Unique_arr (char* store,int len,int total_store_len,char** store_unique)
{/*Unique_arr (数组*,现在使用的长度,可用空间总长,用于储存归一化结果的数组**);
	返回值 = 归一化所得数组的长度*/ 
	int i,j,new_len = 0,flag;//flag:0未重复  1重复 
	*store_unique = (char*)malloc(len*sizeof(char));
	for (i=0;i<len;i++){
		
		for (j=0,flag=0;j<new_len;j++){
			if (store[i] == (*store_unique)[j]){
				flag = 1;
				goto AAA;
			}
		}
		AAA:;
		if (flag == 0){
			(*store_unique) [new_len] = store[i];
			new_len ++ ;
		}
	}
	
	char* temp_store;
	total_store_len = Copy_arr (*store_unique,new_len,total_store_len,&temp_store);
	Free_arr(*store_unique);
	*store_unique = temp_store;	
	
	return new_len;
}


int Sort_arr (char* store,int now_store_len)
{
	int i,j,min_e;
	char min ,temp = '\0';
	for (i=0;i<now_store_len;i++){
		min = store[i];
		for (j=i;j<now_store_len;j++){
			if (store[j]<=min){
				min_e = j; 
				min = store[j];
			}
		}
		temp = store[min_e];
		store[min_e] = store[i];
		store[i] = temp;
	}
	return 0;
}

 
int merge_sort(char* store,int now_store_len)//归并排序 
{
	int i, step = 1, sec_step = 0,thr_step = 0;
	for (;((step*3/2)<=now_store_len)||(step==1 );){
		for (i=0;i<now_store_len;){
			if (((i+2*step)<=now_store_len)&&((i+4*step)<now_store_len)){//小于两步 
				sort_2arrs(&(store[i]),step,&(store[i+step]),step);
				i=i + 2*step;
			}else{
				if ((i+4*step)>=now_store_len){
					sec_step = now_store_len-i-2*step;
					thr_step = now_store_len-i-step;
//					Sort_arr (&(store[i+step]),sec_step);
					sort_2arrs(&(store[i+step]),step,&(store[i+2*step]),sec_step);
					sort_2arrs(&(store[i]),step,&(store[i+step]),thr_step);
					i=now_store_len;
				}
			}	
		}
		step=step*2;
	}
	return 0;
}
 
 
int sort_2arrs(char* store_haed,int len1,char* store_tail,int len2)//两有序数组间排序
{
	int temp_now_store_len = len1+len2;
	char* temp_store = Create_arr (temp_now_store_len);
	char temp;
	int i;
	int k = 0,k1 = 0,k2 = 0;
	while ((k1!=(len1))||(k2!=(len2))){
		if (k1==len1){
			while ((k<temp_now_store_len)&&(k2 <len2)){
				temp_store[k++] = store_tail[k2++];
			}
		}
		if (k2==len2){
			while ((k<temp_now_store_len)&&(k1 <len1)){
				temp_store[k++] = store_haed[k1++];
			}
		}		
		while((store_haed[k1]<=store_tail[k2])&&(k1 <len1)){
			temp_store[k++] = store_haed[k1++];
		}
		while((store_haed[k1]>store_tail[k2])&&(k2 <len2)){
			temp_store[k++] = store_tail[k2++];
		}
	}
	
	for (i=0;i<len1;i++){
		store_haed[i] = temp_store[i];
	}
	for (i=0;i<len2;i++){
		store_tail[i] = temp_store[len1+i];
	}
	free (temp_store);
	return 0;
}


int Frequency_conter (char* store,int now_store_len,int total_store_len)
{
	char* store_unique;
	int new_len = Unique_arr (store,now_store_len,total_store_len,&store_unique);
	int *temp_counter= (int*)malloc(new_len*sizeof(int));
	int i,k;
	for (i=0;i<new_len;i++){
		temp_counter[i]=0;
	}
	for (i=0,k=0;i<now_store_len;i++){
		if (store[i]==store_unique[k]){
			temp_counter[k]++;
		}else{
			k++;
			temp_counter[k]++;
		}
	}
	for (i=0;i<new_len;i++){
		printf (">>%c = %d\n",store_unique[i],temp_counter[i]);
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值