XDOJ第三弹:字符串处理

直接上题(代码仅供参考)

PS: 像for(i=0;i<strlen(a);i++)这种,建议先单独算出int len=strlen(a)

因为这样可以节省运行时间,由于之前没有注意,这篇文章里面可能会有使用前者for循环内部算长度的写法,大家自己判断(我懒)

P-0004 命令行选项

在这里插入图片描述

#include<stdio.h>
#include<string.h>
void InsertionSort(char a[],int length){
    int i,j;
    char t;
    //  1.从第一个元素开始依次取出所有用于比较元素
    for (i=1;i<length;i++){
        // 2.遍历取出前面元素进行比较
        for(j=i;j>0;j--){
            // 3.如果前面一个元素大于当前元素,就交换位置
            if(a[j-1]>a[j]){
                t=a[j];
                a[j]=a[j-1];
                a[j-1]=t;
            }else{
                break;
            }
        }
    }
}
int main(){
    char input[256];
    char orders[256]={'\0'};
    int j=0,k,flag=1,sign;//sign是查重的标签
    gets(input);
    for(int i=0;i<strlen(input);i++){
        if(input[i]=='-'&&flag==1){
            orders[j++]=input[i+1];
            flag=0;//只执行一次
        }else if(input[i]=='-'&&flag==0){
            for(k=0;k<strlen(orders);k++){
                if(orders[k]==input[i+1]){//赋值之前先遍历orders看看里面是否已经存在相同的
                    sign=0;
                    break;
                }
            }
            if(sign){//如果不存在相同的,就赋值
                orders[j++]=input[i+1];
            }
            sign=1;
        }
    }
    //排序
    InsertionSort(orders,strlen(orders));
    if(strlen(orders)==0){
        printf("no");
    }else{
        for(int i=0;i<strlen(orders);i++){
            printf("-%c ",orders[i]);
        }
    }
    return 0;
}

P-0072 寻找最长的行

在这里插入图片描述

#include<stdio.h>
#include<string.h>
int main(){
    int max=0,t;
    char c[101];
    char ans[101];
    while(1){
        gets(c);
      if(strcmp(c,"***end***")==0){
            break;
        }else{
            t=strlen(c);
          if(t>max){
                max=t;
                strcpy(ans,c);
          }
        }  
    }
    printf("%d\n%s",max,ans);
    return 0;
}

P-0073 字符串压缩

在这里插入图片描述

//xdoj的例子可能有一个例子是输入了51个字符前49个是字母,后俩个是数字,应该要截取50个
#include<stdio.h>
#include<ctype.h>
#include<string.h>
#include<math.h>
//用于计算输入中的数字 a13b2 计算出13 和 2
int calcul(int temp[],int count){
    int t=count;
    int ans=0;
    for(int i=0;i<t;i++){
        ans=ans+temp[i]*pow(10.0,(double)(count-1));//也可以ans=ans*10+(temp[i])
        count--;
    }
//仔细想想好像没必要用这个pow的方法,因为最多不到2位数
    return ans;
}
int main(){
    char input[51];
    int temp[50];
    char t;
    int num=0,count=0;//count表示数字的位数,num表示这个数字
    scanf("%51s",input);
    input[50]='\0';//避免输入四十九个字母后 有一个俩位数导致input变成51个输入
    for(int i=0;i<50;i++,count=0){
        if(isalpha(input[i])&&isdigit(input[i+1])){//字母加数字的情况
            t=input[i];
            for(int j=i+1;isdigit(input[j]);j++){
                temp[count]=(int)input[j]-48;
                count++;
            }
            num=calcul(temp,count);
            //输出部分解压的字符串
            for(int k=0;k<num;k++){
                putchar(t);
            }
        }else if((isalpha(input[i])&&isalpha(input[i+1]))||(isalpha(input[i])&&input[i+1]=='\0')){//连续出现次数小于3时不压缩 ||后面是越界的问题
            putchar(input[i]);
        }
    }
    printf("\n");
    return 0;
}

P-0074 括号匹配

在这里插入图片描述

#include<stdio.h>
#include<string.h>
//分析:如果合法的话,所有括号(除去其他符号)都应该是相邻对称的
//遇到左括号就存储(push)到stack,遇到右括号就判断是否与stack的最后一项匹配
//如果匹配,stack的最后一项就要删除(pop),如果不匹配,flag标签改变(no)
int main(){
    char input[51];
    char st[51];
    int flag=0,j=0;//j是栈(stack)的索引,flag是0表示正确
    gets(input);
    for(int i=0;i<strlen(input);i++){
        if(input[i]=='('||input[i]=='['||input[i]=='{'){
            st[j++]=input[i];//push进栈了j个左括号
        }
        switch(input[i]){//右括号的三种情况
            case ')':
                if(st[j-1]=='('){//第14行已经j++了,j-1才是stack的最后一项
                    j--;//j-- 表示之前的j已经匹配上了右括号,这样遇到下一个左括号可以赋值来同时完成pop和push
                    break;
                }else{
                    flag=1;
                }
                break;
            case ']':
                if(st[j-1]=='['){
                    j--;
                    break;
                }else{
                    flag=1;
                }
                break;
            case '}':
                if(st[j-1]=='{'){
                    j--;
                    break;
                }else{
                    flag=1;
                }
                break;
        }
    }
    if(flag==0&&j==0){
        printf("yes");
    }else{
        printf("no");
    }
    return 0;
}
    

    其实就是进栈出栈的过程

在这里插入图片描述

(忽略字丑)

P-0077 表达式求值

在这里插入图片描述

#include<stdio.h>
#include<ctype.h>
#include<string.h>
int main(){
    int flag=0,t=0;//flag表示下x和y的值计算完没有
    char op;
    char input[20];//8+8 +2+ 1+1
    int num[2]={0};//俩个元素分别是x y
    gets(input);
    for(int i=0;i<strlen(input);i++){//空格,数字,符号,三种情况
        if(isdigit(input[i])){//数字
            flag=1;
            num[t]=num[t]*10+(int)input[i]-48;
        }else if(input[i]==' '){//空格
            if(flag){
                t++;
            }
            flag=0;
            continue;
        }else{//符号
            op=input[i];
        }
    }
    switch(op){
        case '+':printf("%d",num[0]+num[1]);break;
        case '-':printf("%d",num[0]-num[1]);break;
        case '*':printf("%d",num[0]*num[1]);break;
        case '/':
            if(num[1]!=0){
                printf("%d",num[0]/num[1]);
                break;
            }
        case '%':
            if(num[1]!=0){
                printf("%d",num[0]%num[1]);
                break;
            }
        default:break;
    }
    return 0;
}

P-0080 字符统计

在这里插入图片描述

#include<stdio.h>
#include<ctype.h>
#include<string.h>
int main(){
    char C,S[101];
    int n,count=0;
    scanf("%c%d",&C,&n);
    scanf("%100s",S);
    switch(n){
        case 0://大小写不敏感
            if(isupper(C)){
                C+=32;
            }
            for(int i=0;i<strlen(S);i++){
                if(isupper(S[i])){//大写转化成小写
                    S[i]+=32;
                }
                if(S[i]==C){
                    count++;
                }
            }
            printf("%d",count);    
            break;
        case 1:
            for(int i=0;i<strlen(S);i++){
                if(S[i]==C){
                    count++;
                }
            }
            printf("%d",count);    
            break;
        default:break;
    }
    return 0;
}

P-0081 字符串查找

在这里插入图片描述

#include<stdio.h>
#include<string.h>
int main(){
  char str[101][100],copy[101][100];
  char son[101],lowson[101];//son子串 str1用来存储小写的son 
  int i,j,n,mode;
  scanf("%s",son);
  scanf("%d",&mode);
    scanf("%d",&n);//n个数
  for(i=0;i<n;i++){
    scanf("%s",str[i]);//二维数组存储n个字符串
  }
  if(!mode){//大小写不敏感的模式
    strcpy(lowson,son);
    for(j=0;j<strlen(lowson);j++){
      if(lowson[j]>='A'&&lowson[j]<='Z'){
                lowson[j]+=32;//大写改小写
            }
    }
    for(i=0;i<n;i++){
            strcpy(copy[i],str[i]);//输入的字符串全部按行赋值给copy
        }
    for(i=0;i<n;i++){
      for(j=0;j<strlen(copy[i]);j++){//转小写 
        if(copy[i][j]>='A'&&copy[i][j]<='Z'){
                    copy[i][j]+=32;
                }
      }
    }
    for(i=0;i<n;i++){
      if(strstr(copy[i],lowson)!=NULL){//strstr函数 返回在 copy 中第一次出现 lowson 字符串的位置,如果未找到则返回 null
                puts(str[i]);//只要有子串,就输出原来的字符串
            }
    }
  }else{
    for(i=0;i<n;i++){
      if(strstr(str[i],son)!=NULL){
                puts(str[i]);
            }
    } 
  }
  return 0;
}

P-0084 目录操作

在这里插入图片描述

#include<stdio.h>
#include<string.h>
void operation(char directory[],char op[]){
    int len=strlen(directory);
    int len2=strlen(op);
    int i,j=0;
    int t=len;
    if(strcmp(op,"cd /")==0){// cd /的命令
        if(len!=1){
            memset(directory,'\0',len);
            directory[0]='/';
        }
    }else if(strcmp(op,"cd ..")==0){// cd ..的命令
        if(len!=1){
            for(i=len-1;directory[i]!='/';i--){
                directory[i]='\0';
            }
        }
        if(strlen(directory)!=1&&directory[strlen(directory)-1]=='/'){
            directory[strlen(directory)-1]='\0';//删除后面的/
        }
    }else if(len2>=4&&op[3]=='/'){// cd /d1/d5这样的命令
        memset(directory,'\0',len);
        for(i=3;i<len2;i++){
            directory[j++]=op[i];
        }
    }else if(len2>=4&&op[3]!='.'){// cd d4/d5 这样的命令
        if(len!=1){
            directory[len]='/';
            len+=1;
            for(int i=3;i<len2;i++){
                directory[len++]=op[i];
            }
        }else{
            for(int i=3;i<len2;i++){
                directory[len++]=op[i];
            }
        }
        
    }
}
int main(){
    char directory[201]={'\0'};
    char op[201]={'\0'};
    gets(directory);
    int flag=1;
    while(flag){
        gets(op);
        if(strcmp(op,"pwd")==0){
            flag=0;
        }else{
            operation(directory,op);
        }
    }
    printf("%s",directory);
    return 0;
}

P-0085 字符串相似度

在这里插入图片描述

思路:把两个字符串按照行和列展开,定义一个全是0的行列式,如果某行

某列字符一样,就把该行该列的数字改为左上角的数字再加1,最后再找出行

列式里最大的数字,就是LCS

在这里插入图片描述

(没填写数字的格子都是0)

#include<stdio.h>
#include<string.h>
#include<math.h>
int main(){
  char s1[101],s2[101],t[101];
  int i,j;
  double max=0;
  int a[100][100]={0};//100*100的行列式
  double similar;
  gets(s1);
  gets(s2);
  for(i=0;i<strlen(s1);i++){
    for(j=0;j<strlen(s2);j++){
      if(s1[i]==s2[j]||abs(s1[i]-s2[j])==32){//如果字母一样(忽略大小写)
        if(i!=0&&j!=0){
            a[i][j]=a[i-1][j-1]+1;//a[i][j]左上角数字的索引是a[i-1][j-1]
                }else{
                    a[i][j]=1;
                }
      }
    }
  }
    //查找100*100行列式中的最大值
  for(i=0;i<strlen(s1);i++){
    for(j=0;j<strlen(s2);j++){
      if(a[i][j]>max){
                max=a[i][j];
            }
    }
  }
  similar=2.0*max/(strlen(s1)+strlen(s2));
  printf("%.3f",similar);
    return 0;
}

P-0088 ISBN号码

在这里插入图片描述

#include<stdio.h>
#include<ctype.h>
#include<string.h>
int main(){
    char ISBN[14];
    int a=1;
    int sum=0;
    scanf("%13s",ISBN);
    int len=strlen(ISBN);
    for(int i=0;i<len-1;i++){
        if(isdigit(ISBN[i])){
            sum=sum+a*((int)ISBN[i]-48);
            a++;
        }
    }
    int check=sum%11;
    if((check!=10&&check==((int)ISBN[12]-48))||(check==10&&ISBN[12]=='X')){
        printf("Right");
    }else{
        for(int i=0;i<len-1;i++){
            printf("%c",ISBN[i]);
        }
        if(check==10){
            printf("X");
        }else{
            printf("%d",check);
        }
    }
    return 0;
}

P-0109 处理字符串

在这里插入图片描述

#include<stdio.h>
#include<string.h>
int main(){
    char c[101];
    char t[101]={'\0'};
    char b[101]={'\0'};
    int j=0,min,k,i;
    gets(c);
    int len=strlen(c);
    char f=c[0];
    for(int i=1;i<len;i++){
        if(c[i]>f){
            putchar(c[i]);
        }else if(c[i]<=f){
            t[j++]=c[i];
        }
    }
    int len1=strlen(t);
    putchar(f);
    //排序
    for(i=0;i<len1-1;i++){
        for(k=i+1,min=i;k<strlen(t);k++){
            if(t[k]<t[min]){
                min=k;
            }
        }
        if(min!=i){
            f=t[min];
            t[min]=t[i];
            t[i]=f;
        }
    }
    for(int i=0;i<len1;i++){
        printf("%c",t[i]);
    }
    return 0;
}

P-0168(跟P-0085一样)

在这里插入图片描述

#include<stdio.h>
#include<string.h>
#include<math.h>
int main(){
  char s1[101],s2[101],t[101];
  int i,j;
  double max=0;
  int a[100][100]={0};//100*100的行列式
  double similar;
  gets(s1);
  gets(s2);
  for(i=0;i<strlen(s1);i++){
    for(j=0;j<strlen(s2);j++){
      if(s1[i]==s2[j]||abs(s1[i]-s2[j])==32){//如果字母一样(忽略大小写)
        if(i!=0&&j!=0){
            a[i][j]=a[i-1][j-1]+1;//a[i][j]左上角数字的索引是a[i-1][j-1]
                }else{
                    a[i][j]=1;
                }
      }
    }
  }
    //查找100*100行列式中的最大值
  for(i=0;i<strlen(s1);i++){
    for(j=0;j<strlen(s2);j++){
      if(a[i][j]>max){
                max=a[i][j];
            }
    }
  }
  similar=2.0*max/(strlen(s1)+strlen(s2));
  printf("%.3f",similar);
    return 0;
}

P-0244 单词排序

在这里插入图片描述

#include<stdio.h>
#include<string.h>
//选择排序 和 冒泡排序分别过不了编号为 795和 797的例子
//也不知道是不是不稳定排序的问题
//题目貌似也没说明首字母一样的情况怎么排序
void wd_sort(char str[][20],int N){
    int i,j,flag,temp;
    char t[20];
    for(i=0;i<N;i++){
    for(j=0;j<N-1;j++){
      if(str[j][0]>str[j+1][0]){
                //利用strcpy进行 整行换行
                strcpy(t,str[j]);
                strcpy(str[j],str[j+1]);
                strcpy(str[j+1],t);
      }
    }
  }
}
//也可以if strcmp(str[min][0],str[j][0])==1
int main(){
    char str[10][20]={'\0'};
    int N;
    scanf("%d",&N);
    if(N>0&&N<=10){
        printf("\n");
        for(int i=0;i<N;i++){
            scanf("%s",&str[i]);
        }
        wd_sort(str,N);
        for(int i=0;i<N;i++){
        puts(str[i]);
        printf("\n");
      }
    }
    return 0;
}

最后

感兴趣的可以关注我的微信公众号,第一时间收到动态

在这里插入图片描述

  • 16
    点赞
  • 85
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值