数据结构:字符串(堆)——基本操作

版权声明:本文为博主原创博客,未经博主允许不得转载。 https://blog.csdn.net/must_5/article/details/83828415

数据结构的重要行不言而喻,简单介绍我在这部分遇到的一些问题,希望对大家有少许帮助。

首先实现的多个操作:
在这里插入图片描述

代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define    OK    1
#define  ERROR   -1
#define  OVERFLOW  -3
#define   BIG    2
#define   EQUAL  0
#define   LITTLE  -2
typedef    int Status;

typedef  struct
{
	char *ch;
	int length;
}HString;

//功能
void menu()
{
	printf("\t\t***************串的堆实现*********************\n");
	printf("\t\t\t1  求字符串的长度\n");
	printf("\t\t\t2  从主串中提取一个子串\n");
	printf("\t\t\t3  比较两个字符串的大小\n");
	printf("\t\t\t4  求一个子串在主串中的位置\n");
	printf("\t\t\t5  将两个字符串连接成一个新的字符串\n");
	printf("\t\t\t0  退出系统\n");
	printf("\t\t***************顺序栈实现*********************\n");
}
//初始化字符串
Status StrAssign(HString &T,char * chars)
{
	int len=0;
	char *c;
	if(T.ch)
		free(T.ch);
	//len=(int)strlen(chars)-1;
	for(c = chars; *c; ++c)                     
		len++;
	if(!len)
	{
		T.ch=NULL;
		T.length=0;
	}
	else
	{
		if(!(T.ch=(char *)malloc(len*sizeof(char))))
			exit(OVERFLOW);
		for(int j=0;j<len;j++)
		{
			T.ch[j]=chars[j];
			
		}
		T.length=len;
	}
	return OK;
}

//清空函数
Status ClearString(HString &S)
{
	if(S.ch)
	{
		free(S.ch);
		S.ch=NULL;
	}
	S.length=0;
	return OK;
}
//求长度
int StrLength(HString S)
{
	return S.length;
}

//求子串(第pos个位置,长度为len的子串,SubS拿来装子串)
Status SubString(HString S,HString &SubS,int pos,int len)
{
	if(pos<1 || pos>S.length || len<0 || len>S.length-pos+1)
		return ERROR;
	if(SubS.ch)
		free(SubS.ch);
	if(len==0)
	{
		SubS.ch=NULL;
		SubS.length=0;
	}
	else
	{
		SubS.ch=(char*)malloc(len*sizeof(char));
		for(int i=0;i<len;i++)
		{
			SubS.ch[i]=S.ch[pos-1];
			pos++;
		}
		SubS.length=len;
	}
	return OK;
}

/*比较也可以写成这个(避免我的警告)
//功能:对2个字符串str1和str2逐一进行比较,如果对应位置相等,
//      继续比较下一个字符,否则返回对应位置字符的ASCII的差值
int StrCompare(HString str1, HString str2)
{
	int i;
	for(i = 0;(i < str1.length && i < str2.length); i++)     //2个字符串存在从第一个开始的若干相等字符串,则比较
	{
		if(str1.str[i]!=str2.str[i])
			return(str1.str[i] - str2.str[i]);
	}
	return (str1.length-str2.length);                        //当上面比较完都没发现不同字符时,此时比较串长
}
*/


//比较两个字串的大小(应该可以优化)
int StrCompare(HString S,HString H)
{
	int time;
	time=0;
	if(S.length>H.length)
		return BIG;
	if(S.length<H.length)
		return LITTLE;
	if(S.length==H.length)
	{
		for(int i=0;i<S.length;i++)
		{
			if(S.ch[i]>H.ch[i])
				return BIG;
			if(S.ch[i]<H.ch[i])
				return LITTLE;
			if(S.ch[i]==H.ch[i])
				time++;
		}
		if(time==S.length)
			return EQUAL;
	}
	
}

//求一个字符串在主串中的位置(要引用上面求子串的函数,书上用pos的意义是从第几个位置起(有多个截取后相等情况时)
int SubStringLocation(HString S,HString T)
{
	int i=0;
	HString SubS;//用来截取的子串串
	SubS.ch=NULL;
	SubS.length=0;
	while(i<S.length-T.length+1)//截取位置起的后面一截
	{
		SubString(S,SubS,i,T.length);  //这里注意3个串别写混了
		if(StrCompare(T,SubS)!=EQUAL)
		{
			i++;
			if(i==S.length-T.length+1-1)  //防止123456aaafffg   fffffff
				return ERROR;
		}
		else
			return i;  //如果有多个子串,存入数组中输出数组即可
		
	}
}

//连接两个字符串为一个字符串
Status StringCat(HString &T,HString S,HString S2)
{
	if(T.ch)
		free(T.ch);
	if(!(T.ch=(char *)malloc((S.length+S2.length)*sizeof(char))))
		exit(OVERFLOW);
	for(int i=0;i<S.length;i++)
	{
		T.ch[i]=S.ch[i];
	}
	T.length=S.length+S2.length;
	for( i=S.length;i<T.length;i++)
	{
		T.ch[i]=S2.ch[i-S.length];//注意别写漏掉i-S.length
	}
	return OK;
}

int main()
{
	int choice,pos=0,len=0;
	HString S,T,Str;
	S.ch=NULL;
	S.length=0;
	T.ch=NULL;   //注意必须先初始化,不然没有值输出
	T.length=0;//注意必须先初始化
	Str.ch=NULL;
	Str.length=0;
	char s[100],s1[100];   
	while(1)
	{
		menu();
		printf("请输入要选择的功能:\n");
		scanf("%d",&choice);
		switch(choice)
		{
		case 1:
			{
				printf("请输入一个字符串:\n");
				scanf("%s",s);
				if(StrAssign(T,s))
					printf("字符串长度为:%d\n",StrLength(T));
				printf("请按回车继续!\n");
				getchar();getchar();
				system("cls");break;
			}
			
		case 2:
			{
				printf("请输入主串:\n");
				scanf("%s",s);
				if(StrAssign(S,s))
				{
					printf("请输入提取子串的位置pos,以及长度len:");
					scanf("%d%d",&pos,&len);
					ClearString(T);//注意释放,防止再次输入
					if(SubString(S,T,pos,len)==OK)    //这里为什么要写OK才行?
					{
						for(int i=0;i<T.length;i++)
						{
							printf("%c",*(T.ch+i));//指针
						}
						printf("\n");
					}
					else
						printf("输入的位置或长度有误!\n");
				}
				printf("请按回车继续!\n");
				getchar();getchar();
				system("cls");break;
			}
			
		case 3:
			{
				printf("请输入两个字符串s和s1:\n");
				scanf("%s%s",s,s1);
				if(StrAssign(S,s) && StrAssign(T,s1))
				{
					if(StrCompare(S,T)==BIG)
						printf("字符串s:%s更大",s);
					if(StrCompare(S,T)==EQUAL)
						printf("字符串s:%s与字符串s1: %s相等",s,s1);
					if(StrCompare(S,T)==LITTLE)
						printf("字符串s1:%s更大",s1);
				}
				printf("请按回车继续:\n");
				getchar();getchar();
				system("cls");break;
			   }
			
		case 4:
			{
				printf("请输入主串s:\n");
				scanf("%s",s);
				if(StrAssign(S,s))
				{
					printf("请输入字串s1:\n");
					scanf("%s",s1);
					if(StrAssign(T,s1))
					{
						if(SubStringLocation(S,T)!=ERROR)
							printf("子串s1在主串s中按从左往右计数的位置(只计算出第相同子串一个位置)为:%d\n",SubStringLocation(S,T));
						else
							printf("主串中没有该子串!\n");
					}
				}
				printf("请按回车继续!\n");
				getchar();getchar();
				system("cls");break;
			}
			
		case 5:
			{
				printf("请输入第一个字符串s:\n");
				scanf("%s",s);
				if(StrAssign(S,s))
				{
					printf("请输入第二个字符串s1:\n");
					scanf("%s",s1);
					if(StrAssign(T,s1))
					{
						if(StringCat(Str,S,T))
						{
							for(int i=0;i<Str.length;i++)
								printf("%c",*(Str.ch+i));
						}
						printf("\n");
					}
				}
				printf("请按回车继续!\n");
				getchar();getchar();
				system("cls");break;
			}
			
		case 0:printf("成功退出系统!\n");exit(0);break;
			
		default:printf("输入有误!\n");exit(0);break;
			
		}
	}
	return 0;
}

综合程序是需要不断改进的,下面说说我遇到的问题吧:
1.在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

这以上3中常见串问题 大家需要注意。
代码中大多数注释都有,若有错误望大家不吝指教,祝大家编程愉快,谢谢!。

猜你喜欢

转载自blog.csdn.net/must_5/article/details/83828415