字符串数组技巧梳理

来源:互联网 发布:北京新华电脑学校java 编辑:程序博客网 时间:2024/05/23 18:23

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

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