NSOqwq

题解 SP117199「Java vs C++」

题解 SP1163 「Java vs C++」


题意

有两种不同的变量命名风格:

  • C++ 风格:所有字符采用小写,并用一个下划线分隔开单词。如 hello_world_luogu
  • Java 风格:第一个单词全小写,后面的单词首字母大写、其余全小写,如 helloWorldLuogu(其实就是小驼峰)。

要求你转换这两种命名风格。

如,输入 helloWorldLuogu,输出 hello_world_luogu;输入 hello_world_luogu,输出 helloWorldLuogu。如果某一个变量名不属于任何命名风格,如 hello_worldLuogu,输出 Error!


思路

遍历原变量名中每个字符:

  • 如果这个字符是下划线:

    • 如果下一个字符是小写字母:

      在新字符串中加入这个字符的大写形式,并继续遍历下一个字符。

    • 如果下一个字符是其他符号:

      Error。

  • 如果这个字符是大写字母:

    在新字符串中加入一个下划线,以及它的小写形式。

  • 如果这个字符是小写字母:

    在新字符串中加入这个小写字母。

  • 如果发现了大写字母和下划线同时存在(这个可以用几个 bool 变量来记录):

    Error。


坑点

这题 AC 率这么低就是因为有几个坑:

  • 首字母不能是大写字母,也不能是下划线。

  • 尾字母不能是下划线。

  • 不能有连续多个下划线。

这也是我翻 SPOJ 讨论区才看出来的。


Code

采用 std::string,方便操作。

#include <string>
#include <iostream>
std::string s;
int main() {
    while (std::cin >> s) {
        const int len = s.length();
        std::string newS;
        bool flag1 = false, flag2 = false;
        if (s[0] == '_' || s[0] >= 'A' && s[0] <= 'Z') { // 判首字母
            puts("Error!");
            continue;
        }
        for (int i = 0; i < len; ++i) {
            if (flag1 && flag2) { // 判多种命名方法混杂的情况
                newS = "Error!";
                break;
            }
            if (s[i] == '_') { // 判下划线
                flag1 = true;
                if (i == len - 1) { // 判尾字母
                    newS = "Error!";
                    break;
                }
                if (s[i + 1] >= 'a' && s[i + 1] <= 'z') {
                    newS += s[i + 1] + 'A' - 'a';
                    ++i;
                    continue;
                } else {
                    newS = "Error!";
                    break;
                }
            } else if (s[i] >= 'A' && s[i] <= 'Z') { // 判大写字母
                flag2 = true;
                newS += '_';
                newS += s[i] + 'a' - 'A';
            } else { // 其余情况(小写字母)
                newS += s[i];
            }
        }
        std::cout << newS << std::endl;
    }
}

2021-03-24 23:32:14 in 题解