/****************************/
/* 分数の加減乗除 */
/* coded by Y.Suganuma */
/****************************/
#include <iostream>
/*
クラスBunsuの定義
*/
class Bunsu {
int sei; // 整数部分
int shi; // 分子
int bo; // 分母
public:
/******************/
/* コンストラクタ */
/******************/
Bunsu() {}
Bunsu(int n, int m, int l=0)
{
sei = l;
shi = n;
bo = m;
}
/**********************/
/* +のオーバーロード */
/**********************/
Bunsu operator + (const Bunsu &b)
{
Bunsu c;
c.shi = (sei * bo + shi) * b.bo + (b.sei * b.bo + b.shi) * bo;
c.bo = bo * b.bo;
c.sei = c.shi / c.bo;
c.shi -= c.bo * c.sei;
return c;
}
/**********************/
/* -のオーバーロード */
/**********************/
Bunsu operator - (const Bunsu &b)
{
Bunsu c;
c.shi = (sei * bo + shi) * b.bo - (b.sei * b.bo + b.shi) * bo;
c.bo = bo * b.bo;
c.sei = c.shi / c.bo;
c.shi -= c.bo * c.sei;
return c;
}
/**********************/
/* *のオーバーロード */
/**********************/
Bunsu operator * (const Bunsu &b)
{
Bunsu c;
c.shi = (sei * bo + shi) * (b.sei * b.bo + b.shi);
c.bo = bo * b.bo;
c.sei = c.shi / c.bo;
c.shi -= c.bo * c.sei;
return c;
}
/*********************/
/* /のオーバーロード */
/*********************/
Bunsu operator / (const Bunsu &b)
{
Bunsu c;
c.shi = (sei * bo + shi) * b.bo;
c.bo = bo * (b.sei * b.bo + b.shi);
c.sei = c.shi / c.bo;
c.shi -= c.bo * c.sei;
return c;
}
friend istream &operator >> (istream &, Bunsu &); // >> のオーバーロード
friend ostream &operator << (ostream &, Bunsu); // << のオーバーロード
};
/********************************/
/* 入力( >> のオーバーロード) */
/********************************/
istream &operator >> (istream &stream, Bunsu &a)
{
std::cout << "n (m / l)? ";
stream >> a.sei >> a.shi >> a.bo;
return stream;
}
/********************************/
/* 出力( << のオーバーロード) */
/********************************/
ostream &operator << (ostream &stream, Bunsu a)
{
if (a.sei == 0)
stream << "(" << a.shi << " / " << a.bo << ")\n";
else
stream << a.sei << "(" << a.shi << " / " << a.bo << ")\n";
return stream;
}
/************/
/* main関数 */
/************/
int main()
{
Bunsu a, b;
std::cout << "Bunsu a ";
std::cin >> a;
std::cout << "Bunsu b ";
std::cin >> b;
// +
std::cout << "--- a+b ---\n";
std::cout << " " << a+b;
// -
std::cout << "--- a-b ---\n";
std::cout << " " << a-b;
// *
std::cout << "--- a*b ---\n";
std::cout << " " << a*b;
// /
std::cout << "--- a/b ---\n";
std::cout << " " << a/b;
return 0;
}
/****************************/
/* 時間の加算と減算 */
/* coded by Y.Suganuma */
/****************************/
#include <iostream>
/*
クラスTimeの定義
*/
class Time {
int hour; // 時間
int min; // 分
int sec; // 秒
public:
/******************/
/* コンストラクタ */
/******************/
Time() {}
Time(int n, int m=0, int l=0)
{
hour = n;
min = m;
sec = l;
}
/**********************/
/* +のオーバーロード */
/**********************/
Time operator + (const Time &b)
{
Time c;
int k;
k = hour * 3600 + min * 60 + sec + b.hour * 3600 + b.min * 60 + b.sec;
c.hour = k / 3600;
k -= c.hour * 3600;
c.min = k / 60;
c.sec = k % 60;
return c;
}
/**********************/
/* -のオーバーロード */
/**********************/
Time operator - (const Time &b)
{
Time c;
int k;
k = hour * 3600 + min * 60 + sec - b.hour * 3600 - b.min * 60 - b.sec;
c.hour = k / 3600;
k -= c.hour * 3600;
c.min = k / 60;
c.sec = k % 60;
return c;
}
friend istream &operator >> (istream &, Time &); // >> のオーバーロード
friend ostream &operator << (ostream &, Time); // << のオーバーロード
};
/********************************/
/* 入力( >> のオーバーロード) */
/********************************/
istream &operator >> (istream &stream, Time &a)
{
std::cout << "hour, min, sec? ";
stream >> a.hour >> a.min >> a.sec;
return stream;
}
/********************************/
/* 出力( << のオーバーロード) */
/********************************/
ostream &operator << (ostream &stream, Time a)
{
stream << a.hour << ":" << a.min << ":" << a.sec << "\n";
return stream;
}
/************/
/* main関数 */
/************/
int main()
{
Time a(12, 10), b;
std::cin >> b;
// 加算
std::cout << a << " + " << b;
std::cout << " = " << a+b;
// 減算
std::cout << a << " - " << b;
std::cout << " = " << a-b;
return 0;
}
/****************************/
/* 年月日の加算と減算 */
/* coded by Y.Suganuma */
/****************************/
#include <iostream>
/*
クラスDateの定義
*/
class Date {
int year; // 年
int month; // 月
int day; // 日
int tu; // 西暦1年1月1日からの通算日
public:
/******************************/
/* コンストラクタ(引数無し) */
/******************************/
Date() {}
/********************************/
/* コンストラクタ(年月日入力) */
/********************************/
Date(int n, int m, int l)
{
int i1;
year = n;
month = m;
day = l;
tu = day;
for (i1 = 1; i1 < year; i1++) {
if ((i1%4 == 0 && i1%100 != 0) || i1%400 == 0)
tu += 366;
else
tu += 365;
}
for (i1 = 1; i1 < month; i1++) {
if (i1 == 2) {
if ((year%4 == 0 && year%100 != 0) || year%400 == 0)
tu += 29;
else
tu += 28;
}
else {
if (i1 == 4 || i1 == 6 || i1 == 9 || i1 == 11)
tu += 30;
else
tu += 31;
}
}
}
/********************************/
/* コンストラクタ(通算日入力) */
/********************************/
Date(int n)
{
int k = 0, sw = 0;
tu = 0;
year = 1;
month = 1;
while (sw == 0) {
if ((year%4 == 0 && year%100 != 0) || year%400 == 0)
k += 366;
else
k += 365;
if (k < n) {
tu = k;
year++;
}
else
sw = 1;
}
while (sw > 0) {
if (month == 2) {
if ((year%4 == 0 && year%100 != 0) || year%400 == 0)
k = 29;
else
k = 28;
}
else {
if (month == 4 || month == 6 || month == 9 || month == 11)
k = 30;
else
k = 31;
}
if (tu+k < n) {
tu += k;
month++;
}
else {
sw = 0;
day = n - tu;
tu += day;
}
}
}
/**********************/
/* +のオーバーロード */
/**********************/
Date operator + (const int n)
{
Date c(tu+n);
return c;
}
/**********************/
/* -のオーバーロード */
/**********************/
int operator - (const Date &b)
{
return tu - b.tu;
}
friend ostream &operator << (ostream &, Date); // << のオーバーロード
};
/********************************/
/* 出力( << のオーバーロード) */
/********************************/
ostream &operator << (ostream &stream, Date a)
{
stream << a.year << "/" << a.month << "/" << a.day;
stream << " 通算 " << a.tu << "\n";
return stream;
}
/************/
/* main関数 */
/************/
int main()
{
int year, month, day, n;
// 加算
std::cout << "年 月 日? ";
std::cin >> year >> month >> day;
Date a(year, month, day);
std::cout << "日? ";
std::cin >> n;
std::cout << n << "日後 " << a+n;
n = -n;
std::cout << -n << "日前 " << a+n;
// 減算
std::cout << "年 月 日? ";
std::cin >> year >> month >> day;
Date b(year, month, day);
n = a - b;
if (n < 0)
std::cout << " " << -n << "日後\n";
else
std::cout << " " << n << "日前\n";
return 0;
}
/************************************/
/* 行列の加減乗除 */
/* (A/BはBの逆行列を左から掛ける) */
/* coded by Y.Suganuma */
/************************************/
#include <iostream>
#include <stdlib.h>
/**************************/
/* クラスMatrixの定義 */
/**************************/
class Matrix { /* 2次元行列 */
int n; // 行の数
int m; // 列の数
double **mat; // 行列本体
public:
Matrix(int, int); // コンストラクタ(引数あり)
Matrix(const Matrix &); // 初期化のためのコンストラクタ
Matrix() {n = 0;} // コンストラクタ(引数無し)
~Matrix() // デストラクタ
{
if (n > 0) {
int i1;
for (i1 = 0; i1 < n; i1++)
delete [] mat[i1];
delete [] mat;
}
}
Matrix &operator= (const Matrix &); // =のオーバーロード
Matrix operator+ (const Matrix &); // +のオーバーロード
Matrix operator- (const Matrix &); // -のオーバーロード
Matrix operator* (const Matrix &); // *のオーバーロード
Matrix operator/ (const Matrix &); // /のオーバーロード
friend istream &operator >> (istream &, Matrix &); // >> のオーバーロード
friend ostream &operator << (ostream &, Matrix); // << のオーバーロード
};
/*****************************/
/*コンストラクタ(引数あり) */
/*****************************/
Matrix::Matrix(int n1, int m1)
{
int i1;
n = n1;
m = m1;
mat = new double * [n];
for (i1 = 0; i1 < n; i1++)
mat[i1] = new double [m];
}
/********************************/
/* 初期化のためのコンストラクタ */
/********************************/
Matrix::Matrix(const Matrix &A)
{
int i1, i2;
n = A.n;
m = A.m;
mat = new double * [n];
for (i1 = 0; i1 < n; i1++) {
mat[i1] = new double [m];
for (i2 = 0; i2 < m; i2++)
mat[i1][i2] = A.mat[i1][i2];
}
}
/********************************/
/* 入力( >> のオーバーロード) */
/********************************/
istream &operator >> (istream &stream, Matrix &A)
{
int i1, i2;
std::cout << "***" << A.n << "行" << A.m << "列の行列***\n";
for (i1 = 0; i1 < A.n; i1++) {
std::cout << i1+1 << "行目のデータ\n";
for (i2 = 0; i2 < A.m; i2++) {
std::cout << " " << i2+1 << "列目の値は? ";
stream >> A.mat[i1][i2];
}
}
return stream;
}
/********************************/
/* 出力( << のオーバーロード) */
/********************************/
ostream &operator << (ostream &stream, Matrix A)
{
int i1, i2;
for (i1 = 0; i1 < A.n; i1++) {
for (i2 = 0; i2 < A.m; i2++)
stream << " " << A.mat[i1][i2];
stream << "\n";
}
return stream;
}
/*******************************/
/* =のオーバーロード */
/* A = B (A.operator=(B)) */
/*******************************/
Matrix& Matrix::operator= (const Matrix &B)
{
int i1, i2;
if (&B != this) { // 自分自身への代入を防ぐ
if (n > 0) { // 代入する前のメモリを解放
for (i1 = 0; i1 < n; i1++)
delete [] mat[i1];
delete [] mat;
}
n = B.n;
m = B.m;
mat = new double * [n]; // メモリの確保と代入
for (i1 = 0; i1 < n; i1++) {
mat[i1] = new double [m];
for (i2 = 0; i2 < m; i2++)
mat[i1][i2] = B.mat[i1][i2];
}
}
return *this;
}
/**********************/
/* +のオーバーロード */
/**********************/
Matrix Matrix::operator + (const Matrix &B)
{
int i1, i2;
if (n != B.n || m != B.m) {
std::cout << "***error invalid data\n";
exit(1);
}
Matrix C(n, m);
for (i1 = 0; i1 < n; i1++) {
for (i2 = 0; i2 < m; i2++)
C.mat[i1][i2] = mat[i1][i2] + B.mat[i1][i2];
}
return C;
}
/**********************/
/* -のオーバーロード */
/**********************/
Matrix Matrix::operator - (const Matrix &B)
{
int i1, i2;
if (n != B.n || m != B.m) {
std::cout << "***error invalid data\n";
exit(1);
}
Matrix C(n, m);
for (i1 = 0; i1 < n; i1++) {
for (i2 = 0; i2 < m; i2++)
C.mat[i1][i2] = mat[i1][i2] - B.mat[i1][i2];
}
return C;
}
/**********************/
/* *のオーバーロード */
/**********************/
Matrix Matrix::operator* (const Matrix &B)
{
int i1, i2, i3;
if (m != B.n) {
std::cout << "***error invalid data\n";
exit(1);
}
Matrix C(n, B.m);
for (i1 = 0; i1 < n; i1++) {
for (i2 = 0; i2 < B.m; i2++) {
C.mat[i1][i2] = 0.0;
for (i3 = 0; i3 < m; i3++)
C.mat[i1][i2] += mat[i1][i3] * B.mat[i3][i2];
}
}
return C;
}
/*******************************************************/
/* 線形連立方程式を解く(逆行列を求める) */
/* w : 方程式の左辺及び右辺 */
/* n : 方程式の数 */
/* m : 方程式の右辺の列の数 */
/* eps : 正則性を判定する規準 */
/* return : =0 : 正常 */
/* =1 : 逆行列が存在しない */
/*******************************************************/
#include <math.h>
int gauss(double **w, int n, int m, double eps)
{
double y1, y2;
int ind = 0, nm, m1, m2, i1, i2, i3;
nm = n + m;
for (i1 = 0; i1 < n && ind == 0; i1++) {
y1 = .0;
m1 = i1 + 1;
m2 = 0;
for (i2 = i1; i2 < n; i2++) {
y2 = fabs(w[i2][i1]);
if (y1 < y2) {
y1 = y2;
m2 = i2;
}
}
if (y1 < eps)
ind = 1;
else {
for (i2 = i1; i2 < nm; i2++) {
y1 = w[i1][i2];
w[i1][i2] = w[m2][i2];
w[m2][i2] = y1;
}
y1 = 1.0 / w[i1][i1];
for (i2 = m1; i2 < nm; i2++)
w[i1][i2] *= y1;
for (i2 = 0; i2 < n; i2++) {
if (i2 != i1) {
for (i3 = m1; i3 < nm; i3++)
w[i2][i3] -= w[i2][i1] * w[i1][i3];
}
}
}
}
return ind;
}
/**********************/
/* /のオーバーロード */
/**********************/
Matrix Matrix::operator/ (const Matrix &B)
{
int i1, i2;
if (n != B.n || B.n != B.m) {
std::cout << "***error invalid data\n";
exit(1);
}
Matrix C(n, m);
double **w = new double * [n];
for (i1 = 0; i1 < n; i1++)
w[i1] = new double [n+m];
double eps = 1.0e-10;
for (i1 = 0; i1 < n; i1++) {
for (i2 = 0; i2 < n; i2++)
w[i1][i2] = B.mat[i1][i2];
}
for (i1 = 0; i1 < n; i1++) {
for (i2 = 0; i2 < m; i2++)
w[i1][n+i2] = mat[i1][i2];
}
int ind = gauss(w, n, m, eps);
if (ind != 0) {
std::cout << "***error no inverse\n";
exit(1);
}
else {
for (i1 = 0; i1 < n; i1++) {
for (i2 = 0; i2 < m; i2++)
C.mat[i1][i2] = w[i1][n+i2];
}
}
for (i1 = 0; i1 < n; i1++)
delete [] w[i1];
delete [] w;
return C;
}
/************/
/* main関数 */
/************/
int main()
{
int n, m, l, sw;
std::cout << "演算は?(=0:+, =1:-, =2:*, =3:/) ";
std::cin >> sw;
switch (sw) {
case 0: // +
{
std::cout << "--- A+B ---\n";
std::cout << "n行m列? ";
std::cin >> n >> m;
Matrix A(n, m), B(n, m);
std::cout << "Matrix A ";
std::cin >> A;
std::cout << "Matrix B ";
std::cin >> B;
std::cout << "Matrix (A+B)\n";
std::cout << A+B;
break;
}
case 1: // -
{
std::cout << "--- A-B ---\n";
std::cout << "n行m列? ";
std::cin >> n >> m;
Matrix A(n, m), B(n, m);
std::cout << "Matrix A ";
std::cin >> A;
std::cout << "Matrix B ";
std::cin >> B;
std::cout << "Matrix (A-B)\n";
std::cout << A-B;
break;
}
case 2: // *
{
std::cout << "--- A*B ---\n";
std::cout << "n行m列(A)? ";
std::cin >> n >> m;
std::cout << "行列Bの列数は? ";
std::cin >> l;
Matrix A(n, m), B(m, l);
std::cout << "Matrix A ";
std::cin >> A;
std::cout << "Matrix B ";
std::cin >> B;
std::cout << "Matrix (A*B)\n";
std::cout << A*B;
break;
}
case 3: // /
{
std::cout << "--- A/B ---\n";
std::cout << "n行m列(A)? ";
std::cin >> n >> m;
Matrix A(n, m), B(n, n);
std::cout << "Matrix A ";
std::cin >> A;
std::cout << "Matrix B ";
std::cin >> B;
std::cout << "Matrix (A/B)\n";
std::cout << A/B;
break;
}
}
return 0;
}
| 菅沼ホーム | 演習解答例目次 | 本文目次 | 付録 | 索引 |