串的静态数组实现方式(C++版)

    串的基本操作有:


    StrAssign(&T,chars):赋值操作,把串T赋值为chars
    StrCopy(&T,S):复制操作,由串S复制得到串T
    StrEmpty(S):字符串的判空操作,若S为空串则返回True,否则返回false
    StrLength(S):求串长,返回串S的元素个数。 
    ClearString(&S):清空操作,将S清为空串。 
    DestoryString(&S):销毁串,将串S销毁(回收存储空间)
    Concat(&T,S1,S2):串连接,用T返回由S1、S2连接而成的新串。 
    SubString(&Sub,S,pos,len):求子串,用Sub返回串S的第pos个字符起长度为len的子串。
    StrCompare(S,T);比较操作,若S>T,则返回值大于0,若S=T,则返回值等于0,若S<T,返回值小于0。 
    Index(S,T):定位操作,若主串S中存在与串T值相同的子串,则返回他在主串S中第一次出现的位置,否则返回0 。

代码实现以及结果测试:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MaxSize 255   //该字符数组的最大容量 


//串的静态数组实现方式结点定义 
typedef struct{
	char data[MaxSize];
	int length;    //该字符数组中实际长度 
}SString;

//串的动态数组实现方式
typedef struct{
	char *ch;
	int length ; //该字符数组中的实际长度 
}DString;    //此种方式实现的字符串如果当存储空间不够时,可以通过realloc函数动态扩容。  非常适合于Concat拼接字符串函数。


//串的单链表实现方式1 
typedef struct LString{
	char ch;                  //1B
	struct LString *next;	 // 4B   
}LString;     //此种方式存储密度低,非常浪费存储空间,并且不支持随机存取。 


//串的单链表存储方式2
typedef struct LLString {
	char ch[4];               //4B
	struct LLString *next;    //4B
}LLString;   //此种方式存储密度较第一种显著提升。

/*
	链表各节点存储数据的个数如何确定?
	1、如果串很长,并且存储空间有限,尽可能的让各节点存储更多的数据,提高空间的利用率(每多一个结点,就要多一个指针域的空间)
	2、如果程序中针对此字符串要做大量的插入和删除操作, 则应尽可能减少各节点存储数据的量。 
	
*/
 

//赋值操作 
void StrAssign(SString &str,char chars[],int length){
		 for(int i = 0 ;i<length;i++){
 			str.data[i]=chars[i];
 		} 
 		str.length=length;
}

//字符串判空
bool StrEmpty(SString str){
	return str.length==0;
}

//字符串求串长
int StrLength(SString str){
	return str.length;
}
//字符串的初始化、清空操作 
void ClearString(SString &str){
	str.length=0;
}
//字符串的销毁操作 
void DestoryString(SString &str){
	//由于我们是在栈空间开辟的字符串的存储空间,无需手动销毁,当函数调用结束时,字符串会随着函数弹栈而被自动销毁。 
}

//复制操作 由串S得到串T。
bool StrCopy(SString *t,SString s){
	if(s.length == 0){
		return false;
	}
	for(int i=0;i<s.length;i++){
		t->data[i]=s.data[i];
	}
	t->length=s.length;
	return true;
} 
 
//字符串的连接操作 t=s1+s2; 
bool Concat(SString &t,SString s1,SString s2){
	if(s1.length+s2.length>MaxSize || (s1.length==0 && s2.length==0)){
		return false;
	} 
	for(int i = 0;i<s1.length;i++){
		t.data[i]=s1.data[i];
	}
	for(int j = 0;j<s2.length;j++){
		t.data[j+s1.length]=s2.data[j];
	}
	t.length=s1.length+s2.length;
	return true;
}

//打印字符串
void printString(SString t){
	for(int i = 0;i<t.length;i++){
		printf("%c",t.data[i]);
	}
} 

//求子串  用sub返回串S的第pos个字符起长度为len的子串。 
bool SubString(SString &sub,SString s,int pos ,int len){
	
	if(s.length==0 ||(pos+len-1)>s.length){
		return false;
	}
	for(int i = 0;i<len;i++){
		sub.data[i]=s.data[pos-1+i];
	}
	sub.length=len;
	return true; 
}

//字符串比较 s>t 返回值大于0 , s=t  返回值等于0, s<t  返回值小于0 
int StrCompare(SString s,SString t){
	//
	for(int i = 0;i<s.length && i<t.length;i++){
		if(s.data[i]!=t.data[i]){
			return s.data[i]-t.data[i];
		}		
	}
	return s.length-t.length;
}

//查找串S中,是否存在与strSon相同的子串,若存在返回首次出现的位置,若不存在,返回0
int Index(SString str,SString strSon){ 
	//先求母串的长度
	int mother = StrLength(str);
	//再求子串的长度
	int son = StrLength(strSon);
	int i = 1;
	SString sub;
	
	//在母串中截取和子串相同的长度,然后进行元素的比较
	while(i<=mother-son+1){
		SubString(sub,str,i,son);
		if(StrCompare(sub,strSon) != 0) i++;
		else return i; 
	}
	//while循环完了还没找到子串,返回0, 
	return 0;
} 
int main(int argc, char *argv[])
{
	//这就是串的定长顺序存储。
	//长度20的字符数组只能存储19个字符,因为最后一个字符要存储'\0'结束标志位。 
	char string[]="nihao,shujvjiegou!";
	 
	SString t;
	//字符串的初始化操作 
 	ClearString(t);
	//将string中的内容赋值给t 
	StrAssign(t,string,strlen(string));
	printString(t);
	printf("\n");
	//判空操作
	bool flag = StrEmpty(t); 
	printf("该字符串为空吗?%d\n",flag);
	
	//求字符串串长
	int len = StrLength(t); 
	printf("这个字符串的串长是%d\n",len);
	
	SString s;
	//字符串的copy操作
    StrCopy(&s,t);
 	printString(s);
 	printf("\n");
 	
 	//字符串的连接操作 
	char s1[] = "hello,world!";
	char s2[] = "I'm your father!";
  	SString ss1;
	
  	SString ss2;
 	StrAssign(ss1,s1,strlen(s1));
	StrAssign(ss2,s2,strlen(s2));
	SString end;
	Concat(end,ss1,ss2);
	printString(end);
	
	printf("\n");
	
	//字符串的截取子串操作 
	SString sub;
    SubString(sub,end,1,2);
	printString(sub);
	printf("\n");
	
	//字符串的比较
	char s3[] = "htllo,world!";
	char s4[] = "hallo,world!s";
  	SString ss3;
	
  	SString ss4;
 	StrAssign(ss3,s3,strlen(s3));
	StrAssign(ss4,s4,strlen(s4));
	
	int value = StrCompare(ss3,ss4);
	if(value > 0){
		printf("ss3的值更大\n"); 
	}else if(value < 0){
		printf("ss4的值更大\n");
	}else{
		printf("ss3和ss4一样大\n");
	}
		
	
	
	char s5[]="fengzhijia";
	char s6[]="ijia";
	SString ss5;
	StrAssign(ss5,s5,strlen(s5));
	SString ss6;
	StrAssign(ss6,s6,strlen(s6));
	int index = Index(ss5,ss6);
	printf("子串在母串中出现的位置是%d\n",index);	
	
	return 0;
}

注意:

concat函数实现两个串的拼接生成一个新串,虽然使用静态数组方式可以实现,但是静态数组的特性无法扩容。所以有可能这两个函数拼接之后容量超了静态数组的容量。

所以实现concat这种类似拼接字符串的函数,最好是使用动态数组分配的方式。

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值