1、什么是串
串又称字符串,是比较常见的一个数据结构,它由0或多个字符构成,一般定义为s="abcdegf"
。字符的个数称为串的长度。长度为0的串为空串,记为s=""
,由空格组成的串为空格串,空格也是字符,记为s=" "
。
目前,随着科学技术的发展,非数值处理的情况越来越多,学好字符串的处理变得尤为重要,本文将介绍字符串处理的几个基本方法。
2、串的顺序存储
在串的顺序存储结构中,用一组地址连续的空间,即数组来存储字符串中的字符,串中的每一个字符占据一个空间,如图所示:
2.1 创建和赋值
//创建String类型
typedef struct str{
char *str; //串指针
int length; //串的长度
}String;
//赋值
int strAssign(String * s,char *p){
//获取p的长度
int i=0;
while(p[i]!='\0'){
i++;
}
//给str分配内存,多分配一个空间存储'\0'
s->str = (char *)malloc(sizeof(char) * (i+1));
//赋值
int j;
for(j=0;j<i;j++){
s->str[j] = p[j];
}
s->str[j] = '\0';
s->length = i;
return 1;
}
2.2 获取串的长度
//获取串的长度
int getLength(String *s){
return s->length;
}
2.3 复制串
先重新为str分配需要的内存,然后memset赋‘\0’。最后循环赋值。
//复制串,将t复制到s中
void strCopy(String *s,String *t){
s->str = (char*)malloc(sizeof(char) * (t->length+1));
memset(s->str,'\0',t->length+1);
int i;
for(i=0;i<t->length;i++){
s->str[i] = t->str[i];
}
s->length = t->length;
}
2.4 判断两个串是否相等
//判断两个串是否相等
int strEqual(String *s1,String *s2){
char *ss1 = s1->str;
char *ss2 = s2->str;
if(s1->length != s2->length){
return 0;
}
if(*ss1++ != *ss2++){
return 0;
}
return 1;
}
2.5 连接两个串
//连接两个串
int strConnect(String *s,String *p){
int len = s->length + p->length;
//临时空间
char *temp = (char*)malloc(sizeof(char) * (len+1));
int i,j;
//拷贝s
for(i=0;i<s->length;i++){
temp[i] = s->str[i];
}
//拷贝p
for(j=0;j<p->length;j++){
temp[j+i] = p->str[j];
}
temp[j+i] = '\0';
//字符串指向temp
s->str = temp;
s->length = len;
return 1;
}
2.6 比较两个串的大小
//比较两个串的大小
int strCompete(String *s,String *p){
int slen = s->length;
int plen = p->length;
char *s1 = s->str;
char *p1 = p->str;
//同时遍历两个字符串,有一个为空时结束循环。
while(*s1!='\0' && *p1!='\0'){
// s > p
if(*s1 > *p1){
return 1;
}
//s < p
if(*s1 < *p1){
return -1;
}
s1++;
p1++;
}
//两个字符串前n个字符相等时,比较长度
if(slen == plen){ //s=p
return 0;
}
if(slen>plen){ //s>p
return 1;
}
if(slen<plen){ //s<p
return -1;
}
}
2.7 插入串
//插入串 将字符串p插入到s的指定位置上
int strInsert(String *s,String *p,int pos){
//位置判断
if(pos<0||pos>s->length){
printf("insert position error!\n");
return;
}
int len = s->length + p->length;
char * temp = (char *)malloc(sizeof(char)*(len+1));
int i,j;
//插入 s的左边部分
for(i=0;i<pos;i++){
temp[i] = s->str[i];
}
//插入 p
for(j=0;j<p->length;j++){
temp[j+pos] = p->str[j];
}
//插入 s的右边部分
for(;i<s->length;i++){
temp[j+i] = s->str[i];
}
temp[j+i] = '\0';
s->str = temp;
s->length = len;
}
2.8 删除指定串
//删除
int strDelete(String *s, int pos, int length){
//位置判断
if(pos<0||pos>s->length){
printf("delete position error!\n");
return;
}
int len = s->length - length;
char * temp = (char*)malloc(sizeof(char)*(len+1));
int i,j;
for(i=0;i<pos;i++){
temp[i] = s->str[i];
}
j = pos+length;
for(;j<s->length;j++){
temp[i] = s->str[j];
i++;
}
temp[i] = '\0';
s->str = temp;
s->length = len;
return 1;
}
2.9 测试
//串的顺序存储
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(){
printf("Create String:\n");
String * s = (String *)malloc(sizeof(String));
char *s1 = "abcdefg";
strAssign(s,s1);
puts(s->str);
printf("Length = %d\n",getLength(s));
printf("\n");
String * p = (String *)malloc(sizeof(String));
char *p1 = "abc";
strAssign(p,p1);
printf("Copy String %s to %s:\n",s->str,p->str);
strCopy(p,s);
puts(s->str);
printf("\n");
printf("是否相等:%d\n",strEqual(s,p));
printf("Insert String %s to %s:\n",p->str,s->str);
strInsert(s,p,2);
puts(s->str);
printf("\n");
printf("Delete String:\n");
strDelete(s,2,3);
puts(s->str);
return 0;
}
输出结果:
3、串的链式存储
串的链式存储可以使用单链表来存储字符,每一个结点存储1个字符(密度为1),有利于串的插入或删除,但它的空间利用率太低。如果一个结点存储多个字符,对字符串的操作又会变得相当麻烦,得不偿失。串的链式存储的实用率很低,使用起来也不灵活,所以,一般都是使用串的顺序存储。