洛谷普及B3640 T3 句子反转

题目:句子反转

题号:B3640

难度:普及一


题目分析

洛谷普及B3640 T3 句子反转_第1张图片

洛谷普及B3640 T3 句子反转_第2张图片

通过分析不难发现,每个单词之间的顺序颠倒,并非字母顺序颠倒,

而且数字字符串是每个数字颠倒。且大小写字母转化,

每个步骤分明,我觉得模块化的话会很轻松,思路很清晰。

关于本题需要注意的点是,字符串长度为1时,省去不必要的操作

关于去除fgets获取的字符串末尾的回车符号时,需要判断确定了回车符再转化为结尾符。

函数模块化思路

分别编写函数对应每个功能要求

1,字母大小写互换(最好是针对整个子字符串互换,因为题中规定每个单词大小写一致)

2,数字字符串的颠倒(参数也是各个数字字符串)

3,遍历每个子字符串,判断数字字符串和字母字符串,分支操作。

4,△(重点)将长语句字符串分割成若干个包含单词的子字符串,方便上述操作。

关于组合函数的框架

fgets获取父字符串

↓  ↓  ↓  ↓  ↓  ↓  ↓

函数4分离出子字符串

       ↓  ↓  ↓

函数3判断字符串类型创造分支

        ↓↓↓                                   ↓↓↓

函数2颠倒数字串     函数3转换字母串大小写

代码

头模块,fgets获取父字符串

需要注意末尾回车符的判断和去除。

char str[1002][8];
    char c[8000];
fgets(c, sizeof(c), stdin);
        int len = strlen(c);
        if (len > 0 && c[len - 1] == '\n') {
            c[len - 1] = '\0';
        }

函数一:大小写互换函数(参数:一维数组(子字符串))

void reverse_type(char c[]) {
    for (int i = 0; i < strlen(c); i++) {
        if (c[i] >= 'a' && c[i] <= 'z') {
            c[i] = c[i] - 32;
        } else if (c[i] >= 'A' && c[i] <= 'Z') {
            c[i] = c[i] + 32;
        }
    }
}

函数二:反转字符串函数(参数:一维数组(子字符串))

void reverse_order(char c[]) {
    int i = 0, j = strlen(c) - 1;
    while (i < j) {
        char temp = c[i];
        c[i] = c[j];
        c[j] = temp;
        i++;
        j--;
    }
}

函数三:判断并处理字母串和数字串函数

(参数:二维数组(分离后的子字符串集合),子字符串的数量)

void judge(char p[][8], int y) {
    for (int i = 0; i <= y; i++) {
        if (p[i][0] >= '0' && p[i][0] <= '9') {
            reverse_order(p[i]);
        } else {
            reverse_type(p[i]);
        }
    }
}

函数四:分割字符串函数(参数:一维数组(父字符串),二维数组(承载子字符串的集合))

int separate(char c[], char p[][8]) {
    int i = 0, y = 0, x = 0;
    while (c[i] != '\0') {
        if (c[i] != ' ') {
            p[y][x++] = c[i];
        } else {
            p[y][x] = '\0';
            y++;
            x = 0;
        }
        i++;
    }
    p[y][x] = '\0';
    return y;
}

组合后的总代码

#include 
#include 

// 大小写互换函数
void reverse_type(char c[]) {
    for (int i = 0; i < strlen(c); i++) {
        if (c[i] >= 'a' && c[i] <= 'z') {
            c[i] = c[i] - 32;
        } else if (c[i] >= 'A' && c[i] <= 'Z') {
            c[i] = c[i] + 32;
        }
    }
}

// 反转字符串函数
void reverse_order(char c[]) {
    int i = 0, j = strlen(c) - 1;
    while (i < j) {
        char temp = c[i];
        c[i] = c[j];
        c[j] = temp;
        i++;
        j--;
    }
}

// 判断并处理单词函数
void judge(char p[][8], int y) {
    for (int i = 0; i <= y; i++) {
        if (p[i][0] >= '0' && p[i][0] <= '9') {
            reverse_order(p[i]);
        } else {
            reverse_type(p[i]);
        }
    }
}

// 分割字符串函数
int separate(char c[], char p[][8]) {
    int i = 0, y = 0, x = 0;
    while (c[i] != '\0') {
        if (c[i] != ' ') {
            p[y][x++] = c[i];
        } else {
            p[y][x] = '\0';
            y++;
            x = 0;
        }
        i++;
    }
    p[y][x] = '\0';
    return y;
}

int main() {
    char str[1002][8];
    char c[8000];
fgets(c, sizeof(c), stdin);
        int len = strlen(c);
        if (len > 0 && c[len - 1] == '\n') {
            c[len - 1] = '\0';
        }
        int y = separate(c, str);
        judge(str, y);
        for (int i = y; i >= 0; i--) {
            printf("%s", str[i]);
            if (i != 0) {
                printf(" ");
            }
        }
        printf("\n");
    
    return 0;
}

总结

本题难度偏易,主要操作在于函数的编写和使用,

整体思维逻辑浅显,使用模块化简化成多个子问题后,本题迎刃而解。

你可能感兴趣的:(算法)