串的存储结构

发布时间:2026/7/26 1:51:55
串的存储结构 文章目录顺序存储链式存储基于顺序存储基本操作的实现*求子串*比较操作*定位操作赋值操作复制操作求串长和判空操作清空操作串联接操作顺序存储“废弃 ch[0] 新增 length 变量”是定长顺序存储写法其核心目的是让“逻辑位序从1开始”与“物理数组下标从1开始”严格对齐。即字符的位序和数组的下标相同。将采用上述方式实现。分配连续的存储空间每个char字符占1B。#defineMAXLEN255// 预定义最大串长// 重点 静态数组实现定长顺序存储 系统自动回收// 重点typedefstruct{charch[MAXLEN];// 1. 每个分量存储一个字符intlength;// 2. 记录串当前实际长度}SString;// 动态数组实现堆分配存储 手动freetypedefstruct{char*ch;// 按串长分配存储区ch指向串的基地址intlength;// 记录串当前实际长度}HString;HString S;S.ch(char*)malloc(MAXLEN*sizeof(char));S.length0;// malloc 与 free 成对出现链式存储可让每个结点存多个字符没有字符的位置用#或\0补足。typedefstructStringNode{charch;// 每个结点存1个字符structStringNode*next;}StringNode,*String;优化方案#defineCHUNKSIZE4typedefstructStringNode{chardata[CHUNKSIZE];// 每个结点存 多个字符这里是4个structStringNode*next;}StringNode,*String;基于顺序存储基本操作的实现*求子串SubString(Sub, S, pos, len)用Sub返回串S的第pos个字符起长度为len的子串。// 求子串boolSubString(SStringSub,SString S,intpos,intlen){// 1. 边界检查pos必须在[1, length]区间len不能超过剩余长度if(pos1||len0||poslen-1S.length)returnfalse;// 2. 复制数据下标对齐Sub.ch[1] 对应 S.ch[pos]for(intipos;iposlen;i){Sub.ch[i-pos1]S.ch[i];}Sub.lengthlen;returntrue;}*比较操作StrCompare(S, T)规则从第1个字符开始按ASCII码 比较。若所有字符相等则长度较长者更大。返回值S T返回正数S T返回负数相等返回0。// 比较操作intStrCompare(SString S,SString T){for(inti1;iS.lengthiT.length;i){if(S.ch[i]!T.ch[i])returnS.ch[i]-T.ch[i];// 直接返回 ASCII 码差值}// 扫描完毕:所有字符都相同若长度相等则完全相等returnS.length-T.length;}*定位操作Index(S, T)功能返回子串 T 在主串 S 中第一次出现的位置未找到返回0。核心逻辑利用上面的SubString和StrCompare配合实现代码最简洁。// 定位操作intIndex(SString S,SString T){// S为主串T为子串inti1;intnS.length,mT.length;// 获取串的长度SString Sub;// 用于暂存子串while(in-m1){// 边界条件剩余长度必须 mSubString(Sub,S,i,m);// 调用已实现的求子串 取出长度为m的子串if(StrCompare(Sub,T)0){returni;// 匹配成功}i;// 不匹配则往后移动一位继续查找}return0;// 未找到 S中不存在与T相等的子串}赋值操作StrAssign(S, chars)把串S赋值为chars。boolStrAssign(SStringS,charchars[]){intlen0;while(chars[len]!\0)len;// 计算源串长度// 判断如果源串太长只截取 MAXLEN 个返回 false 表示溢出if(lenMAXLEN){for(inti1;iMAXLEN;i)S.ch[i]chars[i-1];S.lengthMAXLEN;returnfalse;// 截断标志}else{for(inti1;ilen;i)S.ch[i]chars[i-1];S.lengthlen;returntrue;}}复制操作StrCopy(S, T)将串T完整复制给串S。如果 S 是已存在的串此操作会覆盖它不需要 free因为是定长数组。voidStrCopy(SStringS,SString T){for(inti1;iT.length;i){S.ch[i]T.ch[i];}S.lengthT.length;}求串长和判空操作intStrLength(SString S){returnS.length;}boolStrEmpty(SString S){returnS.length0;// 或 return S.length 0;}清空操作ClearString(S)将串恢复为空串。注意物理内存中的字符数据无需清零逻辑上把长度置0即可下次赋值会覆盖。voidClearString(SStringS){S.length0;}串联接操作Concat(T, S1, S2)用T返回S1 S2拼接后的新串。boolConcat(SStringT,SString S1,SString S2){inti,j;// 1. 复制 S1 到 Tfor(i1;iS1.length;i){T.ch[i]S1.ch[i];}// 2. 复制 S2需判断剩余空间for(j1;jS2.lengthiMAXLEN;j,i){T.ch[i]S2.ch[j];}T.lengthi-1;// 更新实际长度i停在下标位置-1得到最后一个元素的下标// 3. 如果 S2 没复制完即发生截断返回 falseif(jS2.length){returnfalse;}returntrue;}