字符串数组技巧梳理

REASON:复习之前学习的字符串数组,同时将题目中用到的相关技巧总结到此文中,方便日后学习查阅。

·函数及用法

一.cstring字符串处理函数库

1.int strlen(char *str) 计算字符串长度
原理:从括号内给的地址开始一直到寻找到’\0’结束符为止(不计算’\0’所占的空间)
!区别:sizeof(char str)→计算整个的长度(空间),包括’\0’*
e.g.

char a[]="abcdefg";
    int s=strlen(a);
    int m=strlen(a+1);
    int n=sizeof(a);
    printf("%d %d %d",s,m,n);//7 6 8

2.int strcmp(char *a,char *b) 比较函数(字典序)
字典序:从第一位开始逐个比较其ascii值
返回值:
a>b,return 1;a=b,return 0;a<b return -1;

  1. char* strcpy(char *a,char *b) 赋值函数
    功能:把字符串b原样复制到a,返回指针a;
    原理;将字符串b从地址输入的地址开始一直到’\0’之间的部分原样复制到a中并自动带上’\0’;
    关于strcpy的用法很灵活,且实际操作空间很大

这里写图片描述

4.int strcat(char *a,char *b) 连接函数
功能:把从地址b开始一直到’\0’所指字符串的内容连接到 a 所指的字符串后面(即a的‘\0’后),并自动覆盖 a 末尾的‘\0’
ps:使用此函数一定要确保a数组大小够大!

5 char* strrev(char* str) 反转函数
功能:把从地址b开始一直到’\0’所指字符串的内容颠倒反转

6.char *strchr(char *a,char ch) 字符查找函数
功能:用与查找字符 ch 在字符串 a 中出现的内存地址,如果没找到,返回空指针 NULL。

7.char *strstr(char *a,char *b) 子串查找函数
功能:用与查找字符字符串 b 在字符串 a 中最早出现的内存地址,
如果不存在,则返回 NULL。

P.S.对于strchr和strstr来说,返回的都是一个指针,因此实际要得知说所查找的字符(串)所在的位置时应该用返回的地址减去字符串首地址

ENLARGE:如何查找第2次出现的位置
此法是博主于ccf绿书上看到的,至于具体原因还是没怎么懂,望大神指导

    char a[]="abcdeabfg";
    char c[]="ab";
    char *p;
    p=strstr(a,c);//第一次出现的位置 
    printf("%d",p-a)//输出0
    if(p!=NULL)
    p=strstr(p+1,c);//第二次 
    printf("%d",p-a);//输出5

如法炮制,我们也可用其得到子串出现的第3次、第4次…第n次(前提是有这么多次),我们甚至可以求到子串出现的次数!

8.int sscanf(char *a,”格式控制串”,输出项)
功能:把字符串中的数据按标准输入格式输入到输入项中。(即将数字字符串变为一个整型或浮点型的数字)
e.g

    char a[]="1233 0.25";
    int x;
    float y;
    sscanf(a,"%d%f",&x,&y) ;
    printf("%d %f",x,y);//1233 0.250000

所以sscanf部分等价于
(只针对整型)

    char a[]="54321";
    int x=0;
    for(int i=0;i<strlen(a);i++)
    x=x*10+a[i]-'0';//必须-'0'
    printf("%d",x);//54321

p.s.
①sscanf与scanf类似,都是用于输入的,只是后者以屏幕(stdin)为输入源,前者以固定字符串为输入源。
②遇到空格会停
!!!sscanf的用法还有很多,博主只是草草了解,其他用法可自行百度;

9.int sprintf(char *a, ”格式控制串”,输出项)
功能:把格式化的输出内容,输出到字符串 a 中。
(与sscanf恰好相反,用法也类似,不再赘述)

二.cctype字符函数库

这里写图片描述


·字符串处理技巧

1.插入操作(e.g.将字符串b插入到a的第k个位子)
思路:①复制从a[k]开始的字符串至c并将a[k]赋值为’\0’→②将b连接到a后(strcat)→③将c连接至现在的a后

    int k=2;
    char a[]="hello",b[]="world";
    char c[10];
    strcpy(c,a+k);
    a[k]='\0';
    strcat(a,b);
    strcat(a,c);
    printf("%s",a);//heworldllo

以上方法还可以将b的某一子串(b[i]~b[j])插入到a,巧用‘\0’,自行尝试

2.删除操作(e.g.将a[i]~a[j]删除)
思路:①将a[j+1]开始的字符串复制到b中→②将a[i]赋值为‘\0’→③连接a和b

    int i=1,j=3;
    char a[]="hello";
    char b[10];
    strcpy(b,a+j+1);
    a[i]='\0';
    strcat(a,b);
    printf("%s",a);//ho

3.枚举子串

  • 枚举起点i和终点j
    char a[]="abcdef";
    char p[30][10];
    int t=0;//用以记录子串个数以存储入数组
    for(int i=0;i<strlen(a);i++)
     for(int j=i;j<strlen(a);j++)
     {
        strcpy(p[++t],a+i);
        p[t][j-i+1]='\0';//j-i+1即当前枚举的子串的末尾+1
     }
    for(int i=1;i<=t;i++)
    printf("%s\n",p[i]);

核心

     for(int i=0;i<strlen(a);i++)//起点
     for(int j=i;j<strlen(a);j++)//终点
     {
        strcpy(p[++t],a+i);
        p[t][j-i+1]='\0';//j-i+1即当前枚举的子串的末尾+1
     }
  • 枚举起点i和长度l
    char a[]="abcdef";
    char p[30][10];
    int t=0;
    for(int l=1;l<=strlen(a);l++)//枚举长度 
     for(int i=0;i<strlen(a);i++)//枚举起点 
     {
        strcpy(p[++t],a+i);
        p[t][l]='\0';
     }
    for(int i=1;i<=t;i++)
    printf("%s\n",p[i]);

核心

    for(int l=1;l<=strlen(a);l++)//枚举长度 
     for(int i=0;i<strlen(a);i++)//枚举起点 
     {
        strcpy(p[++t],a+i);
        p[t][l]='\0';
     }

p.s.子串必须用字符串数组存储,另非空子串的总个数

N=n(n+1)2 N = n ( n + 1 ) 2

4.回文串的判断:根据左右对称性

//法一
int ok=1;
for(int i=0,j=strlen(c)-1;i<j;i++,j--) // 根据对称性判定
 if(c[i]!=c[j]) (ok=0;break;)
if(ok) printf("Yes\n");
else printf("No\n");

//法二
    int t=0,i=0,j=strlen(c)-1;
    while(i<j)
    if(c[i++]==c[j--])t++;
    if(t==strlen(c)/2)printf("yes");
    else printf("no");

5.不区分大小写
全部转化为大写或小写即可


个人学习笔记,请勿转载。欢迎大神指明错误之处~
from Mr_Shadow

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值