/****************************/ /* 分数の加減乗除 */ /* 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; }
菅沼ホーム | 演習解答例目次 | 本文目次 | 付録 | 索引 |