2018年01月31日
《その268》 問題演習 p.349演習9-9
新版明解C++中級編 p.349 演習9-9
下記のスタッククラステンプレート SimpleStack<> は、インクルードモデルで実現されています。このクラステンプレートに、以下のメンバ関数を追加せよ。
Type& peek() … 頂上のデータを削除することなく返す。
int capacity() … スタックの容量を返す。
bool is_full() … スタックが満杯であるかどうかを返す。
bool is_empty() … スタックが空であるかどうかを返す。
なお、例外が送出・捕捉されるような利用例のプログラムもあわせて作ること。
// SimpleStack.h
#ifndef ___Class_SimpleStack
#define ___Class_SimpleStack
// スタッククラステンプレート
template<class Type> class SimpleStack {
int size; // スタック容量
int ptr; // スタックポインタ
Type* stk; // 先頭要素へのポインタ
// コピーコンストラクタの無効化
SimpleStack(const SimpleStack<Type>&);
// 代入演算子の無効化
SimpleStack& operator=(const SimpleStack<Type>&);
public:
class Overflow { }; // Overflow例外
class Empty { }; // Empty例外
// コンストラクタ
explicit SimpleStack(int sz);
// デストラクタ
~SimpleStack();
// push
Type& push(const Type& x);
// pop
Type pop();
};
#include "SimpleStackImplementation.h"
#endif
// SimpleStackImplementation.h
#ifndef ___Class_SimpleStackImplementation
#define ___Class_SimpleStackImplementation
// コンストラクタ
template<class Type>
SimpleStack<Type>::SimpleStack(int sz)
: size(sz), ptr(0) {
stk = new Type[size];
}
// デストラクタ
template<class Type>
SimpleStack<Type>::~SimpleStack() {
delete[] stk;
}
// push
template<class Type>
Type& SimpleStack<Type>::push(const Type& x) {
if (ptr >= size)
throw Overflow();
return stk[ptr++] = x;
}
// pop
template<class Type>
Type SimpleStack<Type>::pop() {
if (ptr <= 0)
throw Empty();
return stk[--ptr];
}
#endif
// 解答
// SimpleStack.h
#ifndef ___Class_SimpleStack
#define ___Class_SimpleStack
// スタッククラステンプレート
template<class Type> class SimpleStack {
int size; // スタック容量
int ptr; // スタックポインタ
Type* stk; // 先頭要素へのポインタ
// コピーコンストラクタの無効化
SimpleStack(const SimpleStack<Type>&);
// 代入演算子の無効化
SimpleStack& operator=(const SimpleStack<Type>&);
public:
class Overflow { }; // Overflow例外
class Empty { }; // Empty例外
// コンストラクタ
explicit SimpleStack(int sz);
// デストラクタ
~SimpleStack();
// push
Type& push(const Type& x);
// pop
Type pop();
// ★頂上のデータを削除することなく返す。
Type& peek();
// ★スタックの容量を返す。
int capacity();
// ★スタックが満杯であるかどうかを返す。
bool is_full();
// ★スタックが空であるかどうかを返す。
bool is_empty();
};
#include "SimpleStackImplementation.h"
#endif
// SimpleStackImplementation.h
#ifndef ___Class_SimpleStackImplementation
#define ___Class_SimpleStackImplementation
// コンストラクタ
template<class Type>
SimpleStack<Type>::SimpleStack(int sz)
: size(sz), ptr(0) {
stk = new Type[size];
}
// デストラクタ
template<class Type>
SimpleStack<Type>::~SimpleStack() {
delete[] stk;
}
// push
template<class Type>
Type& SimpleStack<Type>::push(const Type& x) {
if (ptr >= size)
throw Overflow();
return stk[ptr++] = x;
}
// pop
template<class Type>
Type SimpleStack<Type>::pop() {
if (ptr <= 0)
throw Empty();
return stk[--ptr];
}
// ★頂上のデータを削除することなく返す。
template<class Type>
Type& SimpleStack<Type>::peek() {
if (ptr <= 0)
throw Empty();
int temp = ptr - 1;
return stk[temp];
}
// ★スタックの容量を返す。
template<class Type>
int SimpleStack<Type>::capacity() {
return size;
}
// ★スタックが満杯であるかどうかを返す。
template<class Type>
bool SimpleStack<Type>::is_full() {
return size == ptr;
}
// ★スタックが空であるかどうかを返す。
template<class Type>
bool SimpleStack<Type>::is_empty() {
return ptr == 0;
}
#endif
// SimpleStackTest.cpp
#include <string>
#include <iostream>
#include "SimpleStack.h"
using namespace std;
void push_it(SimpleStack<char>& s, char c) {
try {
s.push(c);
}
catch (const SimpleStack<char>::Overflow&) {
cout << "\a !満杯の<char>スタックに"
"プッシュしようとしました。\n";
}
}
void pop_it(SimpleStack<char>& s) {
try {
char c = s.pop();
cout << ' ' << c << '\n';
}
catch (const SimpleStack<char>::Empty&) {
cout << "\a !空の<char>スタックから"
"ポップしようとしました。\n";
}
}
void pop_all(SimpleStack<char>& s) {
if (s.is_empty()) {
pop_it(s); goto L;
}
while (!s.is_empty()) {
cout << ' ' << s.pop();
}
cout << '\n';
L:;
}
int main() {
int nn;
cout << "スタックの容量 : "; cin >> nn;
SimpleStack<char> s(nn);
cout << "容量 " << s.capacity()
<< " のスタックを準備しました。\n";
while (1) {
int f; char c;
cout << "◆ 1.push 2.pop 3.文字列をpush "
"4.頂上のデータ 5.全データをpop "
"0.終了 : "; cin >> f;
if (f == 1) {
cout << " 文字 : "; cin >> c;
push_it(s, c);
}
else if (f == 2)
pop_it(s);
else if (f == 3) {
string x;
cout << " 文字列:";
cin >> x;
for (unsigned i = 0; i < x.length(); i++)
push_it(s, x[i]);
}
else if (f == 4)
cout << ' ' << s.peek() << '\n';
else if (f == 5) {
pop_all(s);
}
else break;
if (s.is_full()) cout << " ※満\n";
if (s.is_empty()) cout << " ※空\n";
}
}
この記事へのコメント
コメントを書く
この記事へのトラックバックURL
https://fanblogs.jp/tb/7261430
※ブログオーナーが承認したトラックバックのみ表示されます。
この記事へのトラックバック