1. 程式人生 > 實用技巧 >C語言程式設計之字串處理

C語言程式設計之字串處理

C語言程式設計-字串處理

第一題:迴文數判斷

問題描述】
迴文是正讀和倒讀都一樣的句子。讀入一個最大長度不超過50個字元的句子,判斷其是否是迴文。
【輸入形式】
輸入一個最大長度不超過50個字元的句子
【輸出形式】
Yes/No
【輸入樣例】
abcba
【輸出樣例】
Yes

【樣例說明】
輸入abcba,判斷出它是迴文。

#include <stdio.h>
#include <stdlib.h>
#include<string.h>
int main()
{
    char str[50];
    int i,j,n;
    gets(str);
    //printf("%s",str);
    n = strlen(str);
    for(i=0,j=n-1;i<j;i++,j--){
        if(str[i] != str[j])
            break;
    }
    if(i<j){
        printf("No");
    }else{
        printf("Yes");
    }
    return 0;
}

解釋:

基本思路就是遍歷字元陣列,從前往後與從後往前的字元進行的對比;

結束條件是字元不相等時,跳出迴圈;

判斷i與j的大小關係即可;

第二題:求兩個字串的差集

問題描述】要求計算A-B。A和B都是字串 —即從字串A中把字串B所包含的字元全刪掉,剩下的字元組成的就是字串A-B。

【輸入形式】輸入在2行中,先後給出字串A和B。兩字串的長度都不超過104,並且保證每個字串都是由可見的ASCII碼和空白字元組成,最後以換行符結束。

【輸出形式】

在一行中打印出A-B的結果字串,如果 A-B為空串,則列印一空行。

【樣例輸入】

I love GPLT! It's a fun game!

aeiou

【樣例輸出】

I lv GPLT! It's fn gm!

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

int main()
{
    char str1[1001];
    char str2[1001];
    char ch[1001];
    int i,count=0;

    gets(str1);
    gets(str2);
    int n=strlen(str1);
    for(i=0;i<n;i++)
    {
        //如果str1中的不在str2中,則儲存
        if(strchr(str2,str1[i])==NULL)
            ch[count++]=str1[i];
    }
    printf("%s",ch);

    return 0;
}

解釋:

首先定義了兩個字串;

判斷長的字元陣列在短的字元陣列中是否存在;

我們使用的函式時strchr,如果沒有找到,則返回NUll;

所以我們可以寫成strchr(str2,str1[i])==NULL;把沒有找到字元(即不重複的字元)

儲存到新的陣列中,數字下標自加;

最後輸出新的陣列。

第三題:字母順序數字逆序

【問題描述】輸入任意的由字母和數字組成的字串,將其中字母直接輸出,數字逆序輸出S6.7。

【輸入形式】任意的由字母和數字組成的字串,#結束,中間沒有空格。

【輸出形式】將其中字母直接輸出,數字逆序輸出,不含#。

【樣例輸入】number345reverse#
【樣例輸出】numberreverse543

/*
 * 1.定位數字
 * 2.逆序數字--S1
 * 3.S1放在字元最後
 * 4.輸出
 * */
#include <stdio.h>
#include "string.h"
#define N 10001
int main()
{
    char str1[1001],c;
//    gets(str1);
    //輸入字串
    int index ;
    for (index = 0; index <N-1&&(c=getchar()) !='#'; ++index)
    {
        str1[index] =c;
    }
    str1[index]='\0';
    //定義三個字元陣列
    char count_str[1001];
    char count_int[1001];
    char count_re[1001];

    int  num=0;
    int n = strlen(str1);
    //輸出字元
    for (int i = 0; i < n; ++i)
    {
        if (str1[i]>=';' &&str1[i]<='z')
        {
            count_str[num++]=str1[i];
        }
    }

    //判斷數字48-57
    int k=0;
    for (int i = 0; i < n; ++i)
    {
        if (str1[i]>=48 && str1[i]<=57)
        {
            count_int[k++]=str1[i];
        }
    }
    //數字反轉
    int m=strlen(count_int);
    int b=0;
    for (int i = m-1; i >=0 ; i--)
    {
        count_re[b++]=count_int[i];
    }

//    puts(count_str);
//    puts(count_int);
//    puts(count_re);
    puts(strcat(count_str,count_re));
    return 0;
}

解釋:

首先需要明確字串需要一個數組,數字一個數組,逆轉的數字一個數組;

首先提取字串,根據字元的ASCII碼設定範圍來確定我們需要的字元;

這裡的起始點為什麼是";",按理說應該是"a"-"z"的,但是在測試用例裡面是有";";

老話說的好:既然不能改變,那麼只能默默接受;

然後將符合條件的字元存到陣列中;

同理數字也是一樣;

數字反轉只需要在陣列中從後往前輸出即可;

使用strcat連線兩個陣列即可。

第四題:整數轉R進位制數

問題描述】鍵盤輸入任一個大於等於0的整數,輸出R進製表示的字串
【輸入形式】

兩個空格隔開的整數, 一個是>=0的 整數,一個整數是R,(2<=R<=16)
【輸出形式】

R進位制字串
【樣例輸入1】

29 2

【樣例輸出1】

11101

【樣例輸入】

29 16

【樣例輸出】

1D

#include <stdio.h>
#define N 20
#include "string.h"
int main() {
    int n,m;
    scanf("%d%d",&n,&m);

    int jz[N];
    //元素個數
    int i=0;
    while (n!=0){
        //將餘數存到陣列中,迭代n,n==0時輸出;
        jz[i++]=n%m;
        n=n/m;
        }
    //後面取元素判斷是否<10;
    for (int j = i-1; j>=0; j--) {
        int k=jz[j];
        if (k<10) printf("%d",k);
        else printf("%c",k+55);
    }

    return 0;
}

解釋:

首先需要知道進位制轉換的原理:

除R取餘,然後再逆取餘數,如圖所示;

將餘數儲存到陣列中,再從後往前輸出即可得出進位制數;

但是我們需要判斷元素的大小,如果大於/小於10;需要做相應的判斷處理;

這裡我們小於10處理,小於10輸出,否則將字元+55;

因為16進位制,+55正好是在大寫字元的範圍中,10+55-->65(A)。

可能會問怎麼知道陣列中的元素個數,這個就是i變數的作用,相當於計數器。

第五題:字串基本操作

編寫一個程式,輸入一個正整數n和字串A,對字串A作如下處理:

  • 去掉重複的字元
  • 去掉所有非字母非數字的字元
  • 將字母大小寫互換
  • 按照字元的ASCII碼從大到小排序

最後在同一行裡輸出n個處理後的字串A

【輸入形式】

  • 輸入正整數n和字串A,0<n<10,A長度小於80,輸入以回車結束

【輸出形式】

  • 輸出結果為目標字串
  • 輸出後面無換行符

【樣例輸入】

2 abcd123

【樣例輸出】

DCBA321DCBA321
#include <stdio.h>
#include "string.h"
#define N 10000
int main() {
    int n;
    scanf("%d",&n);
    char str[N];
    char str2[N];
    char str3[N];
    fgets(str, 100, stdin);
    int len = strlen(str);
    int count=0;
    //處理重複字串
    for (int i = 0; i < len; ++i) {
        int index=0;
        for (int j = 0; j < i; ++j) {
            if (str[i]==str[j]){
                index=1;
            }
        }

        if (index==0){
            str2[count++]=str[i];
        }
    }
//    去掉所有去掉所有非字母非數字的字元
    int k=0;
    int len2 = strlen(str2);
    for (int i = 0; i <len2 ; ++i) {
        if ((str2[i]>='A' && str2[i]<='Z' )||(str2[i]>='a' && str2[i]<='z')||(str2[i]>='0'&&str2[i]<='9')){
            //大小寫互換
            if ((str2[i]>='A' && str2[i]<='Z' )||(str2[i]>='a' && str2[i]<='z')){
                    str2[i] ^=32;
            }
            str3[k++]=str2[i];
        }
    }
//    puts(str2);
//    puts(str3);
    //通過氣泡排序進行由大到小
    int len3 = strlen(str3);
    for (int i=0;i<len3-1;i++)
        for (int j=0;j<len3-i-1;j++)
        {
            if (str3[j]<str3[j+1]) // 這裡是從大到小排序,如果是從小到大排序,只需將“<”換成“>”
            {
                int temp;
                temp=str3[j];
                str3[j]=str3[j+1];
                str3[j+1]=temp;
            }
        }
    char str4[N];
    int num=0;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j <len3 ; ++j) {
            str4[num++]=str3[j];
        }
    }
    puts(str4);
    return 0;
}

解釋:

首先去掉重複的字元:

這裡我們採用的是二層迴圈,意思是將字串中的第一個字元與本身所有的字元進行對比;

定義一個記錄變數index並初始為0-->表示沒有相同的字元,如果有相同的,index=1;

在第一層迴圈裡判斷index,若index=0;則將該字元存到新的陣列中。

for (int i = 0; i < len; ++i) {
        int index=0;
        for (int j = 0; j < i; ++j) {
            if (str[i]==str[j]){
                index=1;
            }
        }

        if (index==0){
            str2[count++]=str[i];
        }
    }

第二步:去掉所有非字母非數字的字元與將字母大小寫互換整合

這個判斷字元ASCII的範圍即可;在篩選出符合的的字元後在判斷是否為大小寫:

轉換為大小寫的騷操作是網上的大佬所寫,大體意思是:進行異或操作,具體連結放到博文結尾。

for (int i = 0; i <len2 ; ++i) {
        if ((str2[i]>='A' && str2[i]<='Z' )||(str2[i]>='a' && str2[i]<='z')||(str2[i]>='0'&&str2[i]<='9')){
            //大小寫互換
            if ((str2[i]>='A' && str2[i]<='Z' )||(str2[i]>='a' && str2[i]<='z')){
                    str2[i] ^=32;
            }
            str3[k++]=str2[i];
        }
    }

第三步:按照字元的ASCII碼從大到小排序

這裡採用的是陣列中的氣泡排序,不多解釋,如果不理解的話看前面部落格:

https://www.cnblogs.com/xbhog/p/11741079.html

for (int i=0;i<len3-1;i++)
        for (int j=0;j<len3-i-1;j++)
        {
            if (str3[j]<str3[j+1]) // 這裡是從大到小排序,如果是從小到大排序,只需將“<”換成“>”
            {
                int temp;
                temp=str3[j];
                str3[j]=str3[j+1];
                str3[j+1]=temp;
            }
        }

最後:由題意可知需要輸出n次並不換行;

然後再迴圈內遍歷字元存到新的陣列中。

for (int i = 0; i < n; ++i) {
        for (int j = 0; j <len3 ; ++j) {
            str4[num++]=str3[j];
        }
    }

總結:

上述題目的解不是唯一,例題中的解是我所理解並執行成功的,如果有不對的地方,歡迎指出。

關於大小寫的轉換部落格來連結:https://blog.csdn.net/zkx981105/article/details/78525672