PAT乙级 (字符串处理) 1006、1021、1031、1002、1009、1014、1024、1048(二)

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: PAT乙级 (字符串处理) 1006、1021、1031、1002、1009、1014、1024、1048

1009 说反话

给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出。

输入格式:

测试输入包含一个测试用例,在一行内给出总长度不超过 80 的字符串。字符串由若干单词和若干空格组成,其中单词是由英文字母(大小写有区分)组成的字符串,单词之间用 1 个空格分开,输入保证句子末尾没有多余的空格。

输出格式:

每个测试用例的输出占一行,输出倒序后的句子。

输入样例:

Hello World Here I Come

输出样例:

Come I Here World Hello

代码:

#include<stdio.h>
#include<string.h>
int main() {
    char str[100];//保存字符串
    gets(str);
    int len = strlen(str);//得到字符长度
    char reverse[90][90];//定义一个二维数组,用于保存每个单词
    int j = 0, k = 0;//j为单词个数,k为单词长度
    for (int i = 0; i < len; i++) {//将字符串的每个单子保存到二维数组中
        //如果当前扫描到的字符串的字符为空格,则为当前二维数组加上'\0'终止符,并且移动到下个数组
        if (str[i] == ' ') {
            reverse[j][k] = '\0';
            j++;
            k = 0;
        }
        else {//如果当前扫描到的字符串的字符不是空格,则一次保存到二维数组中,并且长度+1
            reverse[j][k] = str[i];
            k++;
        }
    }
    reverse[j][k] = '\0';//执行循环后,为最后一个单词加上终止符'\0'
    while (j >= 0) {//循环输出,PAT特色输出
        if (j != 0) {
            printf("%s ", reverse[j]);
        }
        else {
            printf("%s", reverse[j]);
        }
        j--;
    }
    return 0;
}

1014 福尔摩斯的约会

大侦探福尔摩斯接到一张奇怪的字条:

我们约会吧! 
3485djDkxh4hhGE 
2984akDfkkkkggEdsb 
s&hgsfdk 
d&Hyscvnm

大侦探很快就明白了,字条上奇怪的乱码实际上就是约会的时间星期四 14:04,因为前面两字符串中第 1 对相同的大写英文字母(大小写有区分)是第 4 个字母 D,代表星期四;第 2 对相同的字符是 E ,那是第 5 个英文字母,代表一天里的第 14 个钟头(于是一天的 0 点到 23 点由数字 0 到 9、以及大写字母 AN 表示);后面两字符串第 1 对相同的英文字母 s 出现在第 4 个位置(从 0 开始计数)上,代表第 4 分钟。现给定两对字符串,请帮助福尔摩斯解码得到约会的时间。

输入格式:

输入在 4 行中分别给出 4 个非空、不包含空格、且长度不超过 60 的字符串。

输出格式:

在一行中输出约会的时间,格式为 DAY HH:MM,其中 DAY 是某星期的 3 字符缩写,即 MON 表示星期一,TUE 表示星期二,WED 表示星期三,THU 表示星期四,FRI 表示星期五,SAT 表示星期六,SUN 表示星期日。题目输入保证每个测试存在唯一解。

输入样例:

3485djDkxh4hhGE 
2984akDfkkkkggEdsb 
s&hgsfdk 
d&Hyscvnm

输出样例:

THU 14:04

注意点:

  1. 判断星期数的时候,仅需'A'-'G'
  2. 判断小时数的时候,仅需'0'-'9'和'A'-'N'

测试点示例:

测试一
3485djDkxh4hhG0 
2984akDfkkkkgg0dsb 
s&hgfdkiggggs
d&Hycvnmzzzzs
输出
THU 00:12
测试二:
HcCO2eA
HcCO2eB
cCaseC
cCaseD
输出
WED 02:00

代码:

(1)

#include<stdio.h>
#include<string.h>
char DAY[10][5] = { "MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN" };//定义输出星期几的数组
char transferDay[10] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G' };//定义星期天数的顺序,方便输出下标
//定义小时数的顺序,方便输出下标
char transferHour[25] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N' };
const int dayMax = 7;//一个星期天数的最大值
const int hourMax = 24;//一天小时数的最大值
char match1(char* a, char* b, int c, int* d) {//匹配星期几
    int i;
    for (i = 0; i < c; i++) {
        if (a[i] >= 'A' && a[i] <= 'G') {//当前扫描到ASCII码中'A'-'G'时判断
            if (a[i] == b[i]) {//如果两个数组的下标相同的字符相等
                break;//跳出循环
            }
        }
    }
    *d = i;//保存下标
    return a[i];//返回相同的字符
}
char match2(char* a, char* b, int c, int d) {//匹配小时数
    int i;
    for (i = c + 1; i < d; i++) {//从上次相同的字符的下一个元素开始遍历
        if ((a[i] >= '0' && a[i] <= '9') || (a[i] >= 'A' && a[i] <= 'N')) {//当前扫描的元素为'0'-'9'或者'A'-'N'时
            if (a[i] == b[i]) {//如果两个数组的下标相同的字符相等
                break;//跳出循环
            }
        }
    }
    return a[i];//返回相同的元素
}
int match3(char* a, char* b, int c) {//判断分钟数
    int i;
    for (i = 0; i < c; i++) {
        if ((a[i] >= 'a' && a[i] <= 'z') || (a[i] >= 'A' && b[i] <= 'Z')) {//当前扫描的元素是'a'-'z'或'A'-'Z'时
            if (a[i] == b[i]) {//如果两个数组的下标相同的字符相等
                break;//跳出循环
            }
        }
    }
    return i;//返回数组元素下标
}
int transferDaySequence(char a, char* b) {//判断当前的字符在星期的顺序数
    int i;
    for (i = 0; i < dayMax; i++) {
        if (a == b[i]) {//扫描到的字符相等
            break;//跳出循环
        }
    }
    return i;
}
int transferHourSequence(char a, char* b) {//判断输出小时数
    int i;
    for (i = 0; i < hourMax; i++) {
        if (a == b[i]) {//扫描到的字符相等
            break;//跳出循环
        }
    }
    return i;
}
int main() {
    char str[4][80];
    gets(str[0]);
    gets(str[1]);
    gets(str[2]);
    gets(str[3]);
    int len0 = strlen(str[0]);
    int len1 = strlen(str[1]);
    int len2 = strlen(str[2]);
    int len3 = strlen(str[3]);
    len0 = (len0 < len1) ? len0 : len1;//保存两个数组中更小的长度
    int firstMatch = 0;//保存第一次扫描到的数组下标
    char daySequence = match1(str[0], str[1], len0, &firstMatch);//得到相同字符
    int day = transferDaySequence(daySequence, transferDay);//得到星期数的顺序下标
    char resDay[5];
    strcpy(resDay, DAY[day]);//拷贝字符串得到最终结果
    char hourSequence = match2(str[0], str[1], firstMatch, len0);//得到相同字符
    int resHour = transferHourSequence(hourSequence, transferHour);//得到小时数
    len2 = (len2 < len3) ? len2 : len3;//保存两个数组中更小的长度
    int resMinute = match3(str[2], str[3], len2);//得到分钟数
    printf("%s %02d:%02d", resDay, resHour, resMinute);
    return 0;
}

(2)

#include<stdio.h>
#include<string.h>
int main(){
    char week[7][5] = {
        "MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"
    };
    char str1[70], str2[70], str3[70], str4[70];
    gets(str1);
    gets(str2);
    gets(str3);
    gets(str4);
    int len1 = strlen(str1);
    int len2 = strlen(str2);
    int len3 = strlen(str3);
    int len4 = strlen(str4);
    int i;
    //寻找str1和str2中第一队相同位置的A-G的大写字母
    for (i = 0; i < len1 && i < len2; i++){
        if(str1[i] == str2[i] && str1[i] >= 'A' && str1[i] <= 'G'){
            printf("%s ", week[str1[i] - 'A']);//输出星期几
            break;
        }
    }
    //往后寻找第二个相同元素,范围为0-9或A-N
    for (i++; i < len1 && i < len2; i++){
        if(str1[i] == str2[i]){
            if(str1[i] >= '0' && str1[i] <= '9'){
                printf("%02d:", str1[i] - '0');//输出0-9
                break;
            }
            else if(str1[i] >= 'A' && str1[i] <= 'N'){
                printf("%02d:", str1[i] - 'A' + 10);//输出10-23
                break;
            }
        }
    }
    //寻找str3和str4第一对相同元素,范围为A-Z或a-z
    for (i = 0; i < len3 && i < len4; i++){
        if(str3[i] == str4[i]){
            if((str3[i] >= 'A' && str3[i] <='Z') || (str3[i] >= 'a' && str3[i] <= 'z')){
                printf("%02d", i);//输出当前下标
                break;
            }
        }
    }
    return 0;
}

1024 科学计数法

科学计数法是科学家用来表示很大或很小的数字的一种方便的方法,其满足正则表达式 [+-][1-9].[0-9]+E[+-][0-9]+,即数字的整数部分只有 1 位,小数部分至少有 1 位,该数字及其指数部分的正负号即使对正数也必定明确给出。

现以科学计数法的格式给出实数 A,请编写程序按普通数字表示法输出 A,并保证所有有效位都被保留。

输入格式:

每个输入包含 1 个测试用例,即一个以科学计数法表示的实数 A。该数字的存储长度不超过 9999 字节,且其指数的绝对值不超过 9999。

输出格式:

对每个测试用例,在一行中按普通数字表示法输出 A,并保证所有有效位都被保留,包括末尾的 0。

输入样例 1:

+1.23400E-03

输出样例 1:

0.00123400

输入样例 2:

-1.2E+10

输出样例 2:

-12000000000

代码:

(1)

#include<stdio.h>
#include<string.h>
int main() {
    char num[10020];//指数绝对值不超过9999,测试点6
    gets(num);
    int i, locateE, locatePoint, power = 0;//locateE用来存储E的位置,locatePoint用来存储.的位置,power用来存储指数
    int len = strlen(num);//得到字符串的长度
    for (i = 0; i < len; i++) {//确定E和小数点的位置 
        if (num[i] == 'E') {
            locateE = i;
        }
        if (num[i] == '.') {
            locatePoint = i;
        }
    }
    if (num[0] == '-') {//如果是负数,则输入负号
        printf("-");
    }
    for (int j = locateE + 2; j < len; j++) {//得到指数
        power *= 10;
        power += num[j] - '0';
    }
    if (num[locateE + 1] == '+') {//如果指数是正数
        if (power >= locateE - locatePoint - 1) {//判断指数是否大于小数的位数
            for (int j = 1; j < locateE; j++) {//输出所有数字,包括小数
                if (num[j] != '.') {//判断当前的字符是不是.
                    printf("%c", num[j]);
                }
            }
            for (int j = 0; j < power - locateE + locatePoint + 1; j++) {//输出多余的0
                printf("0");
            }
        }
        else {
            for (int j = 1; j < locatePoint + power + 1; j++) {//输出整数部分
                if (num[j] != '.') {
                    printf("%c", num[j]);
                }
            }
            printf(".");//输出.
            for (int j = locatePoint + power + 1; j < locateE; j++) {//输出小数部分
                printf("%c", num[j]);
            }
        }
    }
    else {//如果幂次方是负数
        if (power == 0) {//如果指数为0
            for (int j = 1; j < locateE; j++) {
                printf("%c", num[j]);//输出本来的数字
            }
        }
        else if (power >= 1) {//如果指数大于1
            printf("0.");//输出0.前缀
            for (int j = 0; j < power - 1; j++) {//输出多余的0
                printf("0");
            }
            for (int j = 1; j < locateE; j++) {//输出数字
                if (num[j] != '.') {
                    printf("%c", num[j]);
                }
            }
        }
    }
    return 0;
}

(2)

#include<stdio.h>
#include<string.h>
int main(){
    char str[10010];
    gets(str);
    int len = strlen(str);
    if (str[0] == '-'){//如果是负数,输出负号
        printf("-");
    }
    int pos = 0;//pos存放字符串中E的位置
    while (str[pos] != 'E'){
        pos++;
    }
    int exp = 0;//exp保存指数
    for (int i = pos + 2; i < len; i++){
        exp = exp * 10 + (str[i] - '0');
    }
    if (exp == 0){//判断指数为0
        for (int i = 1; i < pos; i++){
            printf("%c", str[i]);
        }
    }
    if (str[pos + 1] == '-'){//如果指数为负
        printf("0.");
        for (int i = 0; i < exp - 1; i++){//输出(exp - 1)个0
            printf("0");
        }
        printf("%c", str[1]);//输出除了小数点意外的数字
        for (int i = 3; i < pos; i++){
            printf("%c", str[i]);
        }
    }
    else{//如果指数为正
        for (int i = 1; i < pos; i++){
            if(str[i] == '.'){//略过原小数点
                continue;
            }
            printf("%c", str[i]);//输出当前数位
            if(i == exp + 2 && pos - 3 != exp){//小数点加上位置(exp + 2)上
                //原小数点和E之间的数字个数(pos -3)不能等于小数点右移位数exp
                printf(".");
            }
        }
        //如果指数exp更大,输出多余的0
        for (int i = 0; i < exp - (pos - 3); i++){
            printf("0");
        }
    }
    return 0;
}

1048 数字加密

本题要求实现一种数字加密方法。首先固定一个加密用正整数 A,对任一正整数 B,将其每 1 位数字与 A 的对应位置上的数字进行以下运算:对奇数位,对奇数位,对应位的数字相加后对 13 取余——这里用 J 代表 10、Q 代表 11、K 代表 12;对偶数位,用 B 的数字减去 A 的数字,若结果为负数,则再加 10。这里令个位为第 1 位。

输入格式:

输入在一行中依次给出 A 和 B,均为不超过 100 位的正整数,其间以空格分隔。

输出格式:

在一行中输出加密后的结果。

输入样例:

1234567 368782971

输出样例:

3695Q8118

代码:

(1)

#include<stdio.h>
#include<string.h>
char odd[15] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'J', 'Q', 'K' };
char oddNum(char* a, char* b, int c, int d) {//奇数位
    int temp = a[c] - '0' + b[d] - '0';//得到两个数列相应元素数字的合
    temp %= 13;//对13取余
    return odd[temp];//返回odd数列的结果
}
int evenNum(char* a, char* b, int c, int d) {//偶数位
    int temp = b[d] - '0' - a[c] + '0';//B - A
    if (temp < 0) {//如果结果为负数,+10
        temp += 10;
    }
    return temp;
}
int main() {
    char str1[110], str2[110];
    scanf("%s", str1);
    scanf("%s", str2);
    int len1 = strlen(str1);
    int len2 = strlen(str2);
    int temp1;
    char temp2;
    if (len2 > len1) {//当B的长度 > A时
        for (int i = 0; i < len2 - len1; i++) {//输出B比A长的部分
            printf("%c", str2[i]);
        }
        for (int i = 0, j = len2 - len1; i < len1; i++, j++) {//遍历A和B剩余的字符串
            if ((len1 - i) % 2 != 0) {//奇数
                temp2 = oddNum(str1, str2, i, j);
                printf("%c", temp2);
            }
            else {//偶数
                temp1 = evenNum(str1, str2, i, j);
                printf("%d", temp1);
            }
        }
    }
    else {//B长度 <= A时
        int j;
        char str3[110];
        for (j = 0; j < len1 - len2; j++) {//补str1和str2长度差额的0
            str3[j] = '0';
        }
        str3[j] = '\0';//添加终止符
        strcat(str3, str2);//将str2的字符串内容添加到str3后
        for (int i = 0; i < len1; i++) {//遍历字符串,因为str1和str3长度相等,仅需遍历str1
            if ((len1 - i) % 2 != 0) {//奇数
                temp2 = oddNum(str1, str3, i, i);
                printf("%c", temp2);
            }
            else {//偶数
                temp1 = evenNum(str1, str3, i, i);
                printf("%d", temp1);
            }
        }
    }
    return 0;
}

(2)

#include<stdio.h>
#include<string.h>
char A[110], B[110], ans[110];
void reverse(char* s){//反转字符串
    int len = strlen(s);
    for (int i = 0; i < len / 2; i++){//交换s[i]和s[len - 1 - i]
        int temp = s[i];
        s[i] = s[len - 1 - i];
        s[len - 1 - i] = temp;
    }
}
int main(){
    scanf("%s %s", A, B);//整数A和B
    reverse(A);
    reverse(B);
    int lenA = strlen(A);//A长度
    int lenB = strlen(B);//B长度
    int len = lenA > lenB ? lenA : lenB;//A和B较大长度
    for(int i = 0; i < len; i++){//从低位开始
        int numA = i < lenA ? A[i] - '0' : 0;//numA对应A[i]
        int numB = i < lenB ? B[i] - '0' : 0;//numB对应B[i]
        if(i % 2 ==0){//当前位i是偶数
            int temp = (numB + numA) % 13;//和再模13
            if(temp == 10) ans[i] = 'J';//特判10、11、12
            else if (temp == 11) ans[i] = 'Q';
            else if (temp == 12) ans[i] = 'K';
            else ans[i] = temp + '0';//0-9
        }
        else{//当前位i是奇数
            int temp = numB - numA;//差
            if(temp < 0) temp += 10;//如果小于0,加上10
            ans[i] = temp + '0';//赋对应字符
        }
    }
    reverse(ans);//反转字符串
    puts(ans);//输出结果
    return 0;
}


相关文章
|
7月前
|
存储 安全 Java
初学者对C语言的爱恨情仇之神秘的字符串
初学者对C语言的爱恨情仇之神秘的字符串
60 0
|
数据采集 人工智能 自然语言处理
“大蟒蛇”的养殖教程---“字符串”
“大蟒蛇”的养殖教程---“字符串”
168 0
|
6月前
|
C语言
C语言学习记录——鹏哥字符分类函数、字符转换函数
C语言学习记录——鹏哥字符分类函数、字符转换函数
852 2
|
7月前
|
对象存储 C++ 索引
C++ 字符串操作的技术性探讨
C++ 字符串操作的技术性探讨
23 1
|
C语言
【C语言航路外传】进制转换
【C语言航路外传】进制转换
60 0
|
IDE 开发工具 C语言
【C语言航路】第十一站:字符串、字符和内存函数(上)
【C语言航路】第十一站:字符串、字符和内存函数
54 0
|
存储 编译器 C语言
【C语言航路】第十一站:字符串、字符和内存函数(下)
【C语言航路】第十一站:字符串、字符和内存函数
74 0
|
算法 安全 编译器
【C语言航路】第十一站:字符串、字符和内存函数(中)
【C语言航路】第十一站:字符串、字符和内存函数
84 0
|
C语言 索引
【C语言航路】第五站:操作符(二)
【C语言航路】第五站:操作符(二)
117 0
|
存储 编译器 C语言
【C语言航路】第五站:操作符(一)
【C语言航路】第五站:操作符(一)
87 0