常用的算法--字符串

零、创建“字符串”

众所周知,C语言是没有字符串类型的,但还是有字符串常量的概念的。

字符串常量与指针:通过指针找空间

char s;*
声明了一个指向字符的指针变量s,它可以指向一个字符数组,也就是一个字符串

    char *s = "hello World";

他们存的首地址语言,但是他们自身的地址不同;若内容一样,则指向的空间也会是一样的
在这里插入图片描述

代更新: 常量字符串

字符数组

char arr[]="hello";

一、移除元素

我们通常在做题的时候,会遇到查看字符串里面是否有重复的字符元素的问题。我们C语言的字符串是利用数组开辟的。使用暴力的解答方式,一个一个的对比形成了O(n^2)的时间复杂度。

那么就不得不提及尺取法(双指针) == 的做法了。
我之前写
尺取法(双指针)==的链接在此link

1.1)移除后的字符串

那么我们通过一道例题来实战一下:

题目编号 AT_test001_b
题目来源 AtCoder 【在洛谷做的】
地址:链接: link

题目描述:
给出一个字符串 a与破掉的按键b。请输出a除去b后的新字符串。

#include<stdio.h>
#include<string.h>
int main(){
    char ch;
    ch=getchar();
    char arr[60];
    scanf("%s",arr);
    int low=0,fast=0;
    for(fast=0;fast<strlen(arr);fast++){
        if(ch!=arr[fast])
        arr[low++]=arr[fast];
    }
    arr[low]='\0';
    printf("%s\n",arr);
}

注意事项:

1)这个主要原因就是,开辟好的空间储存着一定量的元素,而且只有该地址覆盖,删除不得。
2)而且数组是遇见’\0’才算终止。

对比一下:

将13行的那个赋予‘\0’的注释掉的话,我们看到的就是结果是三个S。
在这里插入图片描述
取消注释:两个S
在这里插入图片描述

1.2)查看是否有重复字符

例题:

题目编号 AT_abc063_b
题目来源 AtCoder 【在洛谷做】
地址:链接: link

题目描述:给定一个字符串S,判断其中字符,如果全部不相同,输出yes,否则输出no。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int emm(const void* a,const void* b){
    return (*(char*)a-*(char*)b);
}
int main(){
    char arr[100];
    int low=0,fast=0;
    scanf("%s",arr);
    int len=strlen(arr);
    qsort(arr,len,sizeof(arr[0]),emm);
    for(fast=0;fast<len;fast++){
        if(arr[fast+1]!=arr[fast]){
        low++;
        }
    }
	
    if(low==len)printf("yes\n");
    else printf("no\n");
}

1.3)特殊:

<1>连续出现的字符

链接: link

题目描述
给定一个字符串,在字符串中寻找第一个连续出现次数不低于 k 次的字符。
输入格式2 行。第 1 行是 k;第 2 行是仅包含大小写字母的字符串。

输出格式
字符串中第一个连续出现次数不低于 k 次的字符。如果没有符合条件的字符,输出 No。

#include<stdio.h>
#include<string.h>

int main(){
    char arr[1005];
    int k;
    scanf("%d",&k);
    scanf("%s",arr);
    int len=strlen(arr);
    int i,count=1;
    for(i=1;i<=len;i++){
        if(arr[i]==arr[i-1]){count++;
        if(count>=k){
            printf("%c",arr[i]);return 0;
            }}else count=1;
    }
    printf("No");
}

<2>

链接: link

题目描述
在实际的开发工作中,对字符串的处理是最常见的编程任务。本题目即是要求程序对用户输入的串进行处理。具体规则如下:

把每个单词的首字母变为大写。
把数字与字母之间用下划线字符(_)分开,使得更清晰
把单词中间有多个空格的调整为 1 个空格。

输入描述
用户输入的串中只有小写字母,空格和数字,不含其它的字母或符号。每个单词间由 1 个或多个空格分隔。假设用户输入的串长度不超过 200 个字符。

输出描述
输出处理好的字符串。

输入输出样例示例
输入
you and me what cpp2005programcopy
输出
You And Me What Cpp_2005_program

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
  int i;
  char str[201];
  gets(str);//遇到\n结束输入
  if(str[0]>='a' && str[0]<='z') {
    printf("%c",str[0]-32);//第一个字符是字母则大写 
    if(str[i+1]>='0' && str[i+1]<='9') printf("_");//后面有数字再输出一个_
  }
  else printf("%c",str[0]);//否则直接输出第一个字符
  for(i = 1;i<strlen(str);i++){
    if(str[i]>='a' && str[i]<='z')//判断是不是字母
      {
      if(str[i-1]>='0' && str[i-1]<='9') printf("_");//如果前面有数字先输出_
      if(str[i-1]==' ') printf("%c",str[i]-32);//首字母大写
        else printf("%c",str[i]);//否则小写
      if(str[i+1]>='0' && str[i+1]<='9') printf("_");//如果后面有数字则再输出一个_
    }
        else if(str[i]==' ' && str[i-1]==' ')continue;//如果空格前面还是空格,不输出 
        else printf("%c",str[i]);//如果空格或者数字,直接输出
  }

  return 0;
}

1.4)注意事项:

本题的数据规模换不算太大,如果超过了10^5字符串长度的时候,就该考虑优化一定的时间复杂度了。这题我采取的是C语言自带的快速排序的库里面的函数。【这极大的区别于那个冒泡排序】

本题不需要像上方再写 arr[low++]=arr[fast]; 空间里面不要管了。

二、反转字符串

这个在熟悉不过了。往往最熟悉的容易刺伤自己 我做了一些题,大多就是反转整个字符串,
还有就是反转字符串中的单词,还有一点就是,按某一位反转再整体反转的那种。

2.1)普通反转字符串

只是输出反转

没有改变实际的空间,当我们直接输出整条字符串的时候,依然会是原来的字符串,原封不动的换回来

char arr[100];
scanf("%s",arr);
for(i=strlen(arr)-1;i>=0;i--){
printf("%c",arr[i]);}

改变空间的反转

这个才是输出整条字符串的时候,输出我们想要的那种。

char arr[100];
scanf("%s",arr);
int left = 0,right = 0;
for(left = 0,right = strlen (arr) ;left < stlrn(arr)/2;i ++,j --){
char temp = arr [left];
        arr [left++] = arr[right];
        arr [right--] = temp;

   

2.2)反转字符串中的单词

( 后续马上更新)

  • 14
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你会魔法吗✧(≖ ◡ ≖✿)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值