クラステンプレートを使ってさまざまな型の値を加算するC++プログラム
2つの整数同士、2つの浮動小数点数同士、さらに2つの文字列同士を「足し合わせる」ことのできるクラスを作りたいとします(文字列の場合、加算は文字列の連結を意味します)。入力では最初に操作の回数 n を受け取り、その後の各行には型(int、float、string)と2つのオペランドが与えられます。各行を読み込み、指定された型に応じた演算を実行して結果を出力するのが課題です。
たとえば、入力が次のようになっているとします。
5 int 5 7 int 6 9 float 5.25 9.63 string hello world string love C++
このとき、出力は次のようになります。
12 15 14.88 helloworld loveC++
解決のための手順
- クラステンプレートを使って AddItems クラスを定義します。このクラスは add() と concatenate() という2つのメンバ関数を持ちます。add() は整数や浮動小数点数の加算を担当し、concatenate() は文字列の連結を担当します。
- main 関数からは以下の処理を行います。
- i を 0 で初期化し、i < n を満たす間、i を1ずつ増やしながら次を繰り返します。
- その行の型を type として読み込みます。
- type が "float" の場合:
- 2つのオペランド e1 と e2 を読み込みます。
- e1 を初期値として、float 型の AddItems オブジェクト myfloat を生成します。
- myfloat.add(e2) を呼び出し、結果を表示します。
- type が "int" の場合:
- 2つのオペランド e1 と e2 を読み込みます。
- e1 を初期値として、int 型の AddItems オブジェクト myint を生成します。
- myint.add(e2) を呼び出し、結果を表示します。
- type が "string" の場合:
- 2つのオペランド e1 と e2 を読み込みます。
- e1 を初期値として、string 型の AddItems オブジェクト mystring を生成します。
- mystring.concatenate(e2) を呼び出し、結果を表示します。
実装例
それでは、実際の実装を見てみましょう。
#include <iostream>
using namespace std;
template <class T>
class AddItems {
T element;
public:
AddItems (T arg) {
element=arg;
}
T add (T e2) {
return element+e2;
}
T concatenate (T e2) {
return element+e2;
}
};
int main(){
int n,i;
cin >> n;
for(i=0;i<n;i++) {
string type;
cin >> type;
if(type=="float") {
float e1,e2;
cin >> e1 >> e2;
AddItems<float> myfloat (e1);
cout << myfloat.add(e2) << endl;
}
else if(type == "int") {
int e1, e2;
cin >> e1 >> e2;
AddItems<int> myint (e1);
cout << myint.add(e2) << endl;
}
else if(type == "string") {
string e1, e2;
cin >> e1 >> e2;
AddItems<string> mystring (e1);
cout << mystring.concatenate(e2) << endl;
}
}
}入力
5 int 5 7 int 6 9 float 5.25 9.63 string hello world string love C++
出力
12 15 14.88 helloworld loveC++
ポイント解説
このプログラムの鍵となるのはクラステンプレートです。テンプレート引数 T を使うことで、同じクラス定義を int、float、string という複数の型に対して再利用できます。整数や浮動小数点数では + 演算子が算術加算として働き、std::string では文字列の連結として働くため、add() と concatenate() はどちらも「element + e2」という同一の式で実装できています。もしテンプレートを使わない場合は、型ごとにほぼ同じ内容のクラスを3つ書く必要があり、コードの重複が発生します。クラステンプレートを活用することで、保守性が高く簡潔なコードを実現できるのです。
-
C++で特定の条件を満たすグラフを構築するプログラム
2つの整数 N と K が与えられます。ここで、N 個の頂点を持つ無向グラフについて考えます。このグラフは以下の条件をすべて満たす必要があります。グラフは単純グラフであり、かつ連結である頂点には 1 から N までの番号が付けられているグラフの辺の数を M とすると、辺には 1 から M までの番号が付けられており、各辺の長さは 1 です。辺 i は頂点 U[i] と頂点 V[i] を結びますi < j を満たす頂点のペア (i, j) のうち、2 頂点間の最短距離がちょうど 2 になるものが正確に K 組存在するこのようなグラフが存在する場合はそれを構築して出力し、存在しない場合は -
-
C++で2つの2進数文字列を加算するプログラムの書き方
2つの2進数を表す文字列が与えられたとき、それらを加算した結果を求め、その結果を2進数の文字列として返すことを考えます。2進数とは、0か1のいずれかで表現される数値のことです。2進数同士を足し合わせる際には、以下のような2進数特有の加算ルールに従う必要があります。0+0 → 0 0+1 → 1 1+0 → 1 1+1 → 0(繰り上がり1)入力例str1 = {11}, str2 = {1}出力例100入力例str1 = {110}, str2 = {1}出力例111問題を解くためのアプローチ両方の文字列を末尾(最下位桁)から走査する対応する桁の2進数同士を加算する1と1を足した場合は、その桁