1. 程式人生 > >PTA - C程式設計 NoB - 字串 (12道題)

PTA - C程式設計 NoB - 字串 (12道題)

7-1 統計大寫子音字母
7-2 統計字元出現次數
7-3 字串逆序
7-4 字串字母大小寫轉換
7-5 查詢指定字元
7-6 字串轉換成十進位制整數
7-7 輸出大寫英文字母
7-8 刪除重複字元
7-9 字串替換
7-10 字元轉換
7-11 字串迴圈左移
7-12 Q進位制轉換成T進位制

所有題目都只需要 #include <stdio.h>,不每個都寫了。 

7-1 統計大寫子音字母 (15 分)

英文子音字母是除AEIOU以外的字母。本題要求編寫程式,統計給定字串中大寫子音字母的個數。

輸入格式:

輸入在一行中給出一個不超過80個字元、並以回車結束的字串。

輸出格式:

輸出在一行中給出字串中大寫子音字母的個數。

輸入樣例: HELLO World!

輸出樣例: 4

int main()
{
    char ch;
    int cnt = 0;
    while((ch = getchar()) != '\n')   // "!=" 優先順序比 "=" 高,所以需要小括號
        if(ch >= 'B' && ch <= 'Z' && ch != 'E' && ch != 'I' && ch != 'O' && ch != 'U')
            ++cnt;
    printf("%d\n", cnt);
    return 0;
}

7-2 統計字元出現次數 (20 分)

本題要求編寫程式,統計並輸出某給定字元在給定字串中出現的次數。

輸入格式:

輸入第一行給出一個以回車結束的字串(少於80個字元);第二行輸入一個字元。

輸出格式:

在一行中輸出給定字元在給定字串中出現的次數。

輸入樣例:

programming is More fun!
m

輸出樣例: 2

int main()
{
    int cur = 0, cnt = 0;
    char str[80];
    char ch, target;
    while((ch = getchar()) != '\n')    // 因為是後輸入要找的字元,所以只能先全讀到字元陣列中
        str[cur++] = ch;
    scanf("%c", &target);
    for(int i = 0; i < cur; i++)
        if(target == str[i])
            ++cnt;
    printf("%d\n", cnt);
    return 0;
}

7-3 字串逆序 (15 分)

輸入一個字串,對該字串進行逆序,輸出逆序後的字串。

輸入格式:

輸入在一行中給出一個不超過80個字元長度的、以回車結束的非空字串。

輸出格式:

在一行中輸出逆序後的字串。

輸入樣例:

Hello World!

輸出樣例:

!dlroW olleH
int main()
{
    int cur = 0;
    char str[81], ch;
    while((ch = getchar()) != '\n')
        str[cur++] = ch;
    for(int i = cur - 1; i >= 0; i--)
        printf("%c", str[i]);
    return 0;
}

7-4 字串字母大小寫轉換 (15 分)

本題要求編寫程式,對一個以“#”結束的字串,將其小寫字母全部轉換成大寫字母,把大寫字母全部轉換成小寫字母,其他字元不變輸出。

輸入格式:

輸入為一個以“#”結束的字串(不超過30個字元)。

輸出格式:

在一行中輸出大小寫轉換後的結果字串。

輸入樣例:

Hello World! 123#

輸出樣例:

hELLO wORLD! 123
int main()
{
    char ch;
    while((ch = getchar()) != '#')
    {
        if(ch >= 'a' && ch <= 'z')      printf("%c", ch + 'Z' - 'z');
        else if(ch >= 'A' && ch <= 'Z') printf("%c", ch - 'Z' + 'z');
        else                            printf("%c", ch);
    }
    return 0;
}

7-5 查詢指定字元 (15 分)

本題要求編寫程式,從給定字串中查詢某指定的字元。

輸入格式:

輸入的第一行是一個待查詢的字元。第二行是一個以回車結束的非空字串(不超過80個字元)。

輸出格式:

如果找到,在一行內按照格式“index = 下標”輸出該字元在字串中所對應的最大下標(下標從0開始);否則輸出"Not Found"。

解:

    需要注意的是,用getchar(),把第一行後邊的空格讀掉。 

int main()
{
    char ch, target;
    int idx = -1, cur = 0;
    scanf("%c", &target);
    getchar();
    while((ch = getchar()) != '\n')
    {
        if(ch == target)  idx = cur;
        ++cur;
    }
    if(idx == -1) printf("Not Found\n");
    else          printf("index = %d\n", idx);
    return 0;
}

7-6 字串轉換成十進位制整數 (15 分)

輸入一個以#結束的字串,本題要求濾去所有的非十六進位制字元(不分大小寫),組成一個新的表示十六進位制數字的字串,然後將其轉換為十進位制數後輸出。如果在第一個十六進位制字元之前存在字元“-”,則代表該數是負數。

輸入格式:

輸入在一行中給出一個以#結束的非空字串。

輸出格式:

在一行中輸出轉換後的十進位制數。題目保證輸出在長整型範圍內。

輸入樣例:

+-P-xf4+-1!#

輸出樣例:

-3905

解:

    這道題要判斷每個字元是不是16進位制字元,因為不區別大小寫,所以需要判斷三種情況,還需要判斷 '-' 是不是出現在第一個十六進位制字元前邊。判斷好這兩個就解決了。

int main()
{
    int flaghex = 0, minus = 0;  // 是否已經出現過16進位制字元,是否是負數
    int sum = 0;
    char ch;
    while((ch = getchar()) != '#')
    {
        if(ch >= '0' && ch <= '9')
        {
            flaghex = 1;
            sum = sum * 16 + (ch - '0');
        }
        else if(ch >= 'a' && ch <= 'f')
        {
            flaghex = 1;
            sum = sum * 16 + (ch - 'a') + 10;
        }
        else if(ch >= 'A' && ch <= 'F')
        {
            flaghex = 1;
            sum = sum * 16 + (ch - 'A') + 10;
        }
        else if(ch == '-' && flaghex == 0)  // '-'出現在第一個十六進位制數前邊
            minus = 1;
    }
    if(minus == 1) printf("%d\n", -sum);
    else           printf("%d\n",  sum);
    return 0;
}

7-7 輸出大寫英文字母 (15 分)

本題要求編寫程式,順序輸出給定字串中所出現過的大寫英文字母,每個字母只輸出一遍;若無大寫英文字母則輸出 “Not Found”。

輸入格式:

輸入為一個以回車結束的字串(少於80個字元)。

輸出格式:

按照輸入的順序在一行中輸出所出現過的大寫英文字母,每個字母只輸出一遍。若無大寫英文字母則輸出“Not Found”。

解:

    只需要用一個數組記錄一下26個字母是否出現過就行了。

int main()
{
    static int alp[26];   // 全部初始化為0,表示26個字母是否出現過
    int flag = 0;         // 為判斷 Not Found
    char ch;
    while((ch = getchar()) != '\n')
    {
        if(ch > 'Z' || ch < 'A') continue;  // 不是就跳過
        if(alp[ch - 'A'] == 0)  // 還沒出現過
        {
            printf("%c", ch);
            alp[ch - 'A'] = 1;
            flag = 1;
        }
    }
    if(flag == 0) printf("Not Found\n");
    return 0;
}

7-8 刪除重複字元 (20 分)

本題要求編寫程式,將給定字串去掉重複的字元後,按照字元ASCII碼順序從小到大排序後輸出。

輸入格式:

輸入是一個以回車結束的非空字串(少於80個字元)。

輸出格式:

輸出去重排序後的結果字串。

輸入樣例:

ad2f3adjfeainzzzv

輸出樣例:

23adefijnvz

    每次讀進來一個字元,在已經存起來的數組裡邊找並找合適位置插入,如果找到了相同的,就跳過,因為重複了。

int main()
{
    char res[82], ch;
    int cur = 0;
    while ((ch = getchar()) != '\n')
    {
        int flag = 0;            // 判斷是否出現過,或者成功插入了
        for (int i = 0; i < cur; i++)
        {
            if (res[i] == ch)    // 出現過,直接跳過
            {
                flag = 1;
                break;
            }
            if (res[i] > ch)     // ascii 碼的比較, 插入在這個位置前邊
            {
                for (int j = cur; j > i; j--)    // i右邊所有元素右移一位
                    res[j] = res[j - 1];
                res[i] = ch;     // ch 插入到i位置
                ++cur;           // res大小加一
                flag = 1;
                break;
            }
        }
        if (flag == 0)           // 沒有出現過,而且res裡都比ch小
            res[cur++] = ch;     // res大小加一
    }
    // 按序輸出res即可
    for (int i = 0; i < cur; i++)
        printf("%c", res[i]);
    return 0;
}

7-9 字串替換 (15 分)

本題要求編寫程式,將給定字串中的大寫英文字母按以下對應規則替換:

原字母 對應字母
A Z
B Y
C X
D W
X C
Y B
Z A

輸入格式:

輸入在一行中給出一個不超過80個字元、並以回車結束的字串。

輸出格式:

輸出在一行中給出替換完成後的字串。

解:

    用一個26大小陣列表示字母表,比如 alp[1] 就代表 ‘B’ ,然後如果是大小英文字母,就把他對應的位置 i 變成 25 - i 就行了,對應位置上就是他要變成的大小字母。

int main()
{
    char alp[27] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";	// 最後一位是 '\0'
    char ch;
    while ((ch = getchar()) != '\n')
    {
        if (ch >= 'A' && ch <= 'Z')
            printf("%c", alp[25 - (ch - 'A')]);
        else
            printf("%c", ch);
    }
    return 0;
}

7-10 字元轉換 (15 分)

本題要求提取一個字串中的所有數字字元('0'……'9'),將其轉換為一個整數輸出。

輸入格式:

輸入在一行中給出一個不超過80個字元且以回車結束的字串。

輸出格式:

在一行中輸出轉換後的整數。題目保證輸出不超過長整型範圍。

輸入樣例:

free82jeep5

輸出樣例:

825
int main()
{
    int sum = 0;
    char ch;
    while ((ch = getchar()) != '\n')
        if(ch >= '0' && ch <= '9')
          sum = sum * 10 + (ch - '0');
    printf("%d\n", sum);
    return 0;
}

7-11 字串迴圈左移 (20 分)

輸入一個字串和一個非負整數N,要求將字串迴圈左移N次。

輸入格式:

輸入在第1行中給出一個不超過100個字元長度的、以回車結束的非空字串;第2行給出非負整數N。

輸出格式:

在一行中輸出迴圈左移N次後的字串。

輸入樣例:

Hello World!
2

輸出樣例:

llo World!He

讀入字串,然後先輸出後半部分,在輸出前半部分就行了。

int main()
{
    char str[101], ch;
    int cur = 0, N;
    while ((str[cur++] = getchar()) != '\n');
    --cur;        // 最後的 '\n' 被讀進來,要扔掉
    scanf("%d", &N);
    N %= cur;
    // 先輸出後邊的,然後輸出前邊的
    for (int i = N; i < cur; i++)   printf("%c", str[i]);
    for (int i = 0; i < N; i++)     printf("%c", str[i]);
    return 0;
}

7-12 Q進位制轉換成T進位制 (20 分)

給定一個整數Q(2<=Q<=10),一個非空字串,以及另一個整數T(2<=T<=10), 程式設計要求過濾掉字串中所有非Q進位制數對應的字元組成一個新的字串,該字串無正負號,將該字串表示的Q進位制數轉換為T進位制數的字串輸出。

輸入格式:

第一行輸入一個整數Q, 代表Q進位制(2<=Q<=10)

第二行輸入以回車結束的一行非空字串。

第三行輸入一個整數T, 代表要轉換成T進位制

輸出格式:

輸出轉換後的T進位制數字符串。

輸入樣例:

10
15
2

輸出樣例:

1111

解:

    這道題兩個進位制都是 2 到 10 之間所以難度不大,如果有16進位制這種的,就會麻煩一些了。

int main()
{
    int Q, T, sum = 0;
    scanf("%d", &Q);
    getchar();      // 要讀掉回車
    char ch;
    while ((ch = getchar()) != '\n')
        if (ch >= '0' && ch <= ('0' + Q - 1))  // 其他字元都過濾掉,2進位制可取值為0和1,沒有2
            sum = sum * Q + (ch - '0');        // sum為Q進位制轉為10進位制
    if (sum == 0)
    {
        printf("0\n");
        return 0;
    }
    scanf("%d", &T);
    if (T == 10)    // 轉成十進位制的話直接輸出就行
    {
        printf("%d\n", sum);
        return 0;
    }
    // 下面是10進位制數sum轉為T進位制
    int cur = 0, a[100000];
    while (sum != 0)
    {
        a[cur++] = sum % T;
        sum /= T;
    }
    for (int i = cur - 1; i >= 0; i--)
        printf("%d", a[i]);
    return 0;
}