B - camel_case Editorial by hanyu
ユーザ解説入力で与えられる文字列を \(S\) とします。
先頭と末尾のアンダースコアを処理する
\(S\) の先頭と末尾に連続しているアンダースコアを別途保存します。 ここで \(S\) がアンダースコアしか含まないと判明した場合、 \(S\) を出力してプログラムを終了します。
また、先頭と末尾のアンダースコアを取り除いた文字列を \(T\) とし、以降は \(T\) を相互変換することを考えます。
実装例 (C++) :
string front_ = "", back_ = ""; // 先頭、末尾のアンダースコアを保存
for (int i = 0; i < S.size(); i++) {
if (S[i] == '_') front_ += "_";
else break;
}
for (int i = S.size() - 1; i >= 0; i--) {
if (S[i] == '_') back_ += "_";
else break;
}
if (front_ == S) { // Sがアンダースコアのみからなる場合
cout << S << endl;
return 0;
}
string T = S.substr(front_.size(), S.size() - front_.size() - back_.size());
\(T\) をどう変換すべきか
結局、以下のようになります。
- \(T\) がキャメルケースであり、アンダースコア区切りではないとき、 \(T\) をアンダースコア区切りに変換する
- \(T\) がアンダースコア区切りであり、キャメルケースではないとき、 \(T\) をキャメルケースに変換する
- 上記のどちらにも当てはまらないとき、\(T\) は変換しなくてよい
したがって
- \(T\) がキャメルケースかどうか判断する関数 (
isCamel
) - \(T\) がアンダースコア区切りかどうか判断する関数 (
is_snake
) - キャメルケースをアンダースコア区切りに変換する関数 (
camel2snake
) - アンダースコア区切りをキャメルケースに変換する関数 (
snake2camel
)
を作成すればよいです。
関数の作成
isCamel
\(T\) の先頭が英小文字であり、かつ \(T\) にアンダースコアが含まれなければ、 \(T\) はキャメルケースです。
is_snake
\(T\) の先頭およびアンダースコアの直後は英小文字、その他は英小文字か数字であれば、 \(T\) はアンダースコア区切りです。
camel2snake
引数の文字列の英大文字を (アンダースコア + 英小文字) に置き換えます。
snake2camel
引数の文字列のアンダースコアを除外し、直後の英小文字を英大文字に置き換えます。
C++であれば、あらかじめ用意されている islower
, isupper
, tolower
, toupper
関数が役立ちます。
実装例 (C++) :
bool isCamel(string T) {
if (!islower(T[0])) return false;
for (int i = 1; i < (int) T.size(); i++) {
if (T[i] == '_') return false;
}
return true;
}
bool is_snake(string T) {
for (int i = 0; i < T.size(); i++) {
if (i == 0) {
if (!islower(T[i])) return false;
}
else if (T[i] == '_') {
i++;
if (!islower(T[i])) return false;
}
else {
if (isupper(T[i])) return false;
}
}
return true;
}
string camel2snake(string T) {
string res = "";
for (int i = 0; i < T.size(); i++) {
if (isupper(T[i])) {
res += "_";
res += tolower(T[i]);
}
else {
res += T[i];
}
}
return res;
}
string snake2camel(string T) {
string res = "";
for (int i = 0; i < T.size(); i++) {
if (T[i] == '_') {
i++;
res += toupper(T[i]);
}
else {
res += T[i];
}
}
return res;
}
posted:
last update: