当前位置: 首页 > news >正文

数据结构<c语言>——串

一、顺序串的基本操作:

假定下面所有的串均为顺序串,参数ch、ch1和ch2均是字符型,编写算法依次实现下列操作。

① 将串r中所有值为ch1的字符换成ch2的字符。

② 将串r中所有字符按照相反的次序仍存放在r中。

③ 从串r中删除其值等于ch的所有字符。

④ 从串r1中第index个字符起求出首次与串r2相同的子串的起始位置。
输入格式:

第一行:r

第二行:r1

第三行:r2

第四行:ch ch1 ch2

第五行:index

输出格式:

第一行:操作①结果

第二行:操作②结果

第三行:操作③结果

第四行:操作④结果(不存在输出-1)

1.操作1:替换字符

// 1. 字符替换:将S中所有ch1替换为ch2
void StrReplaceCh(SString *S, char ch1, char ch2) {for (int i = 0; i < S->len; i++) {if (S->ch[i] == ch1) {S->ch[i] = ch2;}}
}

2.操作2(双指针):逆置字符串

// 2. 串逆置:将S中字符按相反次序存放
void StrRreverse(SString *S) {int left = 0;          // 左指针(起始位置)int right = S->len - 1;// 右指针(末尾位置)while (left < right) {// 交换左右指针指向的字符char temp = S->ch[left];S->ch[left] = S->ch[right];S->ch[right] = temp;// 指针移动left++;right--;}
}

3.操作3:删除字符

// 3. 字符删除:删除S中所有值为ch的字符
void StrDeleteCh(SString *S, char ch) {int k = 0;  // 记录有效字符的位置for (int i = 0; i < S->len; i++) {if (S->ch[i] != ch) {S->ch[k++] = S->ch[i];  // 有效字符存到k位置,k自增}}S->len = k;  // 更新串的长度为有效字符数
}

4.操作4:定位子串(查找主串中与子串进行匹配的起始位置)

// 4. 子串定位:从S的pos位置起,查找首次匹配T的起始位置(失败返回-1)
int StrIndex(SString *S, int pos, SString T) {// 边界检查:T为空、pos超出范围、S长度不足if (T.len == 0 || pos < 0 || pos >= S->len || S->len < T.len) {return -1;}// i:S中当前比较的位置,从pos开始;j:T中当前比较的位置int i = pos, j = 0;// 遍历S中可能的起始位置(最多到S->len - T->len)while (i <= S->len - T.len && j < T.len) {if (S->ch[i] == T.ch[j]) {// 字符匹配,继续比较下一个i++;j++;} else {// 字符不匹配,回溯:S回到上一轮起始位置+1,T回到0i = i - j + 1;j = 0;}}// 若j遍历完T,说明匹配成功,返回起始位置(i - T.len)return (j == T.len) ? (i - T.len) : -1;
}

5.代码汇总:

#include<stdio.h>
#include <stdlib.h>
#include <string.h>#define MAXLEN 50   // 字符串的最大长度
typedef struct{char ch[MAXLEN];int  len;
}SString;// 函数声明
void StrReplaceCh(SString *S, char ch1, char ch2);  /*字符替换函数*/
void StrRreverse(SString *S);   /*串逆置函数*/
void StrDeleteCh(SString *S, char ch);  /*在串S中删除值为ch的字符*/
int StrIndex(SString *S, int pos, SString T);  /*求串T在串S中的位置*/// 串初始化(裁判代码已提供,此处仅作参考)
void StrInit(SString *s){s->len=0;
}// 串赋值(裁判代码已提供,此处仅作参考)
void StrAssign(SString *s, char *r){    int i=0;while (r[i]!='\0'){s->ch[i]=r[i];i++;}s->len=i;
}// 1. 字符替换:将S中所有ch1替换为ch2
void StrReplaceCh(SString *S, char ch1, char ch2) {for (int i = 0; i < S->len; i++) {if (S->ch[i] == ch1) {S->ch[i] = ch2;}}
}// 2. 串逆置:将S中字符按相反次序存放
void StrRreverse(SString *S) {int left = 0;          // 左指针(起始位置)int right = S->len - 1;// 右指针(末尾位置)while (left < right) {// 交换左右指针指向的字符char temp = S->ch[left];S->ch[left] = S->ch[right];S->ch[right] = temp;// 指针移动left++;right--;}
}// 3. 字符删除:删除S中所有值为ch的字符
void StrDeleteCh(SString *S, char ch) {int k = 0;  // 记录有效字符的位置for (int i = 0; i < S->len; i++) {if (S->ch[i] != ch) {S->ch[k++] = S->ch[i];  // 有效字符存到k位置,k自增}}S->len = k;  // 更新串的长度为有效字符数
}// 4. 子串定位:从S的pos位置起,查找首次匹配T的起始位置(失败返回-1)
int StrIndex(SString *S, int pos, SString T) {// 边界检查:T为空、pos超出范围、S长度不足if (T.len == 0 || pos < 0 || pos >= S->len || S->len < T.len) {return -1;}// i:S中当前比较的位置,从pos开始;j:T中当前比较的位置int i = pos, j = 0;// 遍历S中可能的起始位置(最多到S->len - T->len)while (i <= S->len - T.len && j < T.len) {if (S->ch[i] == T.ch[j]) {// 字符匹配,继续比较下一个i++;j++;} else {// 字符不匹配,回溯:S回到上一轮起始位置+1,T回到0i = i - j + 1;j = 0;}}// 若j遍历完T,说明匹配成功,返回起始位置(i - T.len)return (j == T.len) ? (i - T.len) : -1;
}// 裁判测试程序(已提供,此处仅作参考)
void main()
{SString s, s1, s2;char r[50], r1[50], r2[50];char ch, ch1, ch2;int i, loc, index;gets(r);  gets(r1);  gets(r2);scanf("%c %c %c", &ch, &ch1, &ch2); StrAssign(&s, r);/*操作1:字符替换*/StrReplaceCh(&s, ch1, ch2);for(i=0;i<s.len;i++)printf("%c", s.ch[i]);printf("\n");/*操作2:串逆置*/StrRreverse(&s);for(i=0;i<s.len;i++)printf("%c", s.ch[i]);printf("\n");/*操作3:串删除*/StrDeleteCh(&s, ch);for(i=0;i<s.len;i++)printf("%c", s.ch[i]);printf("\n");/*操作4:串定位匹配*/StrAssign(&s1, r1); StrAssign(&s2, r2);scanf("%d", &index); loc=StrIndex(&s1, index, s2);printf("%d\n",loc);
}

二、堆串的基本操作:

编写算法,实现堆串的基本操作StrReplace(S, T, V)。

初始条件: 串S, T和 V 均已存在,且 V 是非空串。

操作结果: 用V替换主串S中出现的所有与(模式串)T相等的不重叠的子串。


输入格式:

第一行:S

第二行:T

第三行:V

输出格式:

S = 被替换后的结果

1.替代操作:

// 核心:串替换函数
void StrReplace(HString *S, HString T, HString V) {// 边界条件:T为空或T长度大于S长度,无匹配可替换if (T.len == 0 || T.len > S->len) {return;}int pos = 0;  // 每次定位的起始位置int start;    // 匹配到的子串起始位置while (1) {// 从pos位置开始查找T的匹配start = StrIndex(S, pos, T);if (start == -1) {break;  // 无更多匹配,退出循环}// 1. 删除S中从start开始的T子串StrDelete(S, start, T.len);// 2. 在start位置插入V子串StrInsert(S, start, V);// 3. 更新下一轮定位起点(避免重叠,跳过已替换的V)pos = start + V.len;// 若起点超出S长度,退出循环if (pos >= S->len) {break;}}
}

2.代码汇总:

#include<stdio.h>
#include <stdlib.h>
#include <string.h>typedef struct{char *ch;int  len;
}HString;// 函数声明(裁判已提供部分,此处补充)
void StrReplace(HString *S, HString T, HString V);
void StrInit(HString *s);
int StrAssign(HString *s, char *tval);
int StrInsert(HString *s, int pos, HString t);
int StrDelete(HString *s, int pos, int len);
int StrIndex(HString *s, int pos, HString t);//初始化
void StrInit(HString *s) {s->ch=NULL;s->len=0;
}
//赋值字符串
int StrAssign(HString *s, char *tval) {    int len,i=0;if (s->ch!=NULL) free(s->ch);while (tval[i]!='\0')  i++;len=i;if (len){s->ch=(char *)malloc(len);if (s->ch==NULL)  return(0); for (i=0;i<len;i++)s->ch[i]=tval[i];}else  s->ch=NULL;s->len=len;return(1);
}
//插入串
int StrInsert(HString *s, int pos, HString t){int i;  char *temp;if (pos<0 || pos>s->len)return(0);temp=(char *)malloc(s->len + t.len);if (temp==NULL)  return(0);for (i=0;i<pos;i++)temp[i]=s->ch[i];for (i=0;i<t.len;i++)temp[i+pos]=t.ch[i];for (i=pos;i<s->len;i++)temp[i + t.len]=s->ch[i];s->len+=t.len;free(s->ch);s->ch=temp;return(1);
} 
//删除串
int StrDelete(HString *s, int pos, int len) {int i; char *temp;if (pos<0 || pos>(s->len - len))return(0);temp=(char *)malloc(s->len - len);if (temp==NULL)  return(0);for (i=0;i<pos;i++)temp[i]=s->ch[i];for (i=pos;i<s->len - len;i++)temp[i]=s->ch[i+len];s->len=s->len-len;free(s->ch);s->ch=temp;return(1);
}
//求索引
int StrIndex(HString *s, int pos, HString t){int i,j,start;if (t.len==0 || pos < 0 || pos >= s->len)  return(-1);start=pos; i=start; j=0;while (i<s->len && j<t.len){if (s->ch[i]==t.ch[j])  {i++;j++;}else  {start++; i=start; j=0;}}if (j>=t.len) return(start);else return(-1);
} // 核心:串替换函数
void StrReplace(HString *S, HString T, HString V) {// 边界条件:T为空或T长度大于S长度,无匹配可替换if (T.len == 0 || T.len > S->len) {return;}int pos = 0;  // 每次定位的起始位置int start;    // 匹配到的子串起始位置while (1) {// 从pos位置开始查找T的匹配start = StrIndex(S, pos, T);if (start == -1) {break;  // 无更多匹配,退出循环}// 1. 删除S中从start开始的T子串StrDelete(S, start, T.len);// 2. 在start位置插入V子串StrInsert(S, start, V);// 3. 更新下一轮定位起点(避免重叠,跳过已替换的V)pos = start + V.len;// 若起点超出S长度,退出循环if (pos >= S->len) {break;}}
}// 裁判测试程序
void main()
{HString s, t, v;char str1[100],str2[100],str3[100];int i;gets(str1);  StrInit(&s);  StrAssign(&s, str1);gets(str2);  StrInit(&t);  StrAssign(&t, str2);gets(str3);  StrInit(&v);  StrAssign(&v, str3);StrReplace(&s, t, v);printf("S = '");for(i=0;i<s.len;i++)printf("%c", s.ch[i]);printf("'\n");
}
http://www.dtcms.com/a/474727.html

相关文章:

  • 基于单片机的16位逐次逼近AD电路设计
  • 网站建设交流会石狮建设网站
  • 小白也能开发 Chrome 插件
  • 网站建设费的摊销期wordpress显示所有文章列表
  • 《以 Trae 为桥:高效集成豆包 1.6 API 的实践与思考》
  • 做网站看好金石网络高新区做网站
  • cursor自动绑定虚拟卡
  • 做网店在素材网站找的图侵权吗现在帮别人做网站赚钱不
  • 网站用微信登录 要怎么做惠山网页制作
  • IP白名单配置:使用/24子网掩码是否有效
  • Ubuntu Linux 入门指南
  • 提高网站收录江西新农村建设权威网站
  • Vue和Vue CLI
  • SQL 索引速查:CREATE / DROP / SHOW INDEX 用法全解
  • ru后缀的网站中信建设有限责任公司地址
  • 后端开发学习路线:从入门到精通
  • linux mutex
  • 河南中原建设公司网站wordpress代码实现
  • 什么网站动物和人做的网络设计中网络设备选择的原则
  • 做设计接外快在哪个网站成都注册公司的流程及手续
  • WPF中核心接口 INotifyPropertyChanged​
  • 【完整源码+数据集+部署教程】 面包种类识别系统源码和数据集:改进yolo11-aux
  • qData数据中台商业版实操全流程演示(2025年10月版)
  • 南昌网站建设公司价位广州市门户网站建设
  • 机器视觉3D定位引导成功的一半机械臂TCP工具,什么是机械臂TCP工具?为什么TCP如此重要?如何定义和设置TCP?
  • 自动化测试,预制菜和大厨现制
  • 计算机本科论文 网站建设东莞网站关键词优化怎么做
  • Linux 通配符与正则表达式(含实战案例+避坑指南)
  • GO语言篇之Slice
  • 长春建站培训班广告设计制作公司简介