🔥

AtCoder 英小文字から英大文字への変換

2023/04/08に公開

ABC292のA問題を解きながら、英小文字から英大文字への変換方法を紹介します。
コンテストサイト:
https://atcoder.jp/contests/abc292
A - CAPS LOCK

問題概要

英小文字のみからなる文字列Sが与えられます。
Sの各文字を英大文字に変換して得られる文字列Tを出力してください。

問題リンク:
https://atcoder.jp/contests/abc292/tasks/abc292_a

解法

2通りの書き方を紹介します。

1. 一つの文字を大文字に変換する関数を使う方法

例えば、C++にはtoupperという関数があります。
この関数は、一つの文字を大文字に変換することができます。

文字列全体を大文字に変換するには、transformという関数を使って、
文字列の各文字にtoupperを適用します。

C++
#include <iostream>
#include <algorithm>
using namespace std;
 
int main() {
  string S; // 入力される文字列
  cin >> S; // 文字列を読み込む
  transform(S.begin(), S.end(), S.begin(), ::toupper); // Sの各文字を大文字に変換してSに代入する
  cout << S << endl; // Sを出力する
  return 0;
}

transform関数について

transform関数は、C++の関数で、シーケンスの全要素に演算を適用するための強力なツールです。transform関数を使用することで、足し算や掛け算のような演算はもちろん、
もっと複雑な変換にも使うことができます。
transform関数は、以下のように定義されています。

C++
transform(first, last, result, op);

この関数は、firstからlastまでの範囲の各要素に対して、op関数を適用し、
その結果をresultに格納します。
op関数は、一つの引数を受け取り、その引数を変換した結果を返す関数です。
この関数は、第一引数と第二引数が同じ型である場合に使用されます。

今回第3引数にS.begin()が使用されているのは、
transform関数がSの各要素を変換した結果を再びSに格納するためです。
S.begin()は、Sの先頭要素への
イテレータ(コンテナ内の要素に順番にアクセスするためのオブジェクト)を返します。
この場合、firstとlastは同じシーケンス(要素が順序付けられたデータの集合)であるため、
変換された結果を元のシーケンスに格納するために、第3引数にS.begin()が使用されています。

transform関数を使わずに実装する方法

なおtransform関数を使わずにfor文で実装することもできます。
実装例は公式にあがっているので、公式の解説を参照してください。
https://atcoder.jp/contests/abc292/editorial/5871
公式のコードでは、for文を使用してSの各文字に対してtoupper関数を適用し、
大文字に変換しています。
そして、変換された結果をTに格納されています。
最終的に、coutでTの値が出力されています。

2. Sの各文字に対してASCIIコードを使って変換

C++
#include <iostream>
using namespace std;

int main() {
  string S; // 入力される文字列
  cin >> S; // 文字列を読み込む
  string T; // 出力する文字列
  for (char c : S) { // Sの各文字に対して
    c -= 32; // ASCIIコードで32を引くと大文字になる
    T += c; // Tに追加する
  }
  cout << T << endl; // Tを出力する
  return 0;
}

ASCIIコードとは

アルファベットや数字、記号などを収録した文字コードの一つです。
最も基本的な文字コードとして世界的に普及しており、
他の多くの文字コードがASCIIの拡張になるよう実装されています。
ASCIIは、7ビットの値(0~127)で表され、128文字が収録されています。
ASCIIコードは、アルファベットの大文字と小文字は一定の間隔を空けて配置されているため、
’a’と’A’や’z’と’Z’の間隔も常に同じで、必ず32になっています。
英小文字-32 すると英大文字になります。
異なる型同士で演算してるようにみえますが、
char型は整数値をASCIIコードによって文字に変換しているだけなので、
内部的には整数同士の演算といえます。
とりあえず、英大文字と英小文字間で変換したいときは
32という数字がキーになります。

英大文字から英小文字への変換を行うには

英小文字から英大文字への変換の際と同様に
以下の2通りの方法があります。

1.一つの文字を小文字に変換する関数を使う方法。
例えば、C++ではtolowerという関数で実装できます。
2.Sの各文字に対してASCIIコードを使って変換する方法。
英大文字+32 すると英小文字になります。

実装はほとんど同じになるので省略します。

余談

この問題のタイトルになっている「CapsLock」とは、
キーボードの特殊キーの一つで、
アルファベットの大文字と小文字を切り替えるためのキーです。
例えば、「hello good morning.」と入力すると、
「HELLO GOOD MORNING.」となります。
このキーは、タイプライターの時代に登場しました。
タイプライターでは、
大文字を入力するためにはシフトキーを押し続ける必要がありましたが、
それを省くために「CapsLock」キーが作られました。

Discussion