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 分)
英文子音字母是除A
、E
、I
、O
、U
以外的字母。本題要求編寫程式,統計給定字串中大寫子音字母的個數。
輸入格式:
輸入在一行中給出一個不超過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;
}