1032 Quiz#1 有理數 (Rational Number)

C++ 實習測試: 有理數 (Rational Number) 類別製作
時間: 40分鐘 (10:10 上傳時間截止)

數學定義中有理數 (rational number) 是一個整數 a 和一個非零整數 b 的比值,例如 3/8,又稱作分數。所有有理數的集合表示為 Q。 如果把有理數表示為實數的話,小數部分只有有限的位數或為循環小數,不是有理數的實數稱為無理數 (irrational),有理數是可屬的 (countable)。

  • 一個有理數的表示法可以化簡 (reduce), 使得分子 a 和分母 b 互質
  • 兩個有理數可以執行 加法(減法) 乘法(除法) 的運算
  • 兩個有理數可以 比較是否相等(或是比較大小)

下面是一個簡化過(沒有實作減法, 除法, 比較大小...), 實作 有理數程序化程式(使用C/C++語法), 除了add()equal() 函式沒有完成, 其它都可以正確運作

#include <cassert>
#include <iostream>
using std::cin;
using std::cout;
using std::ostream;
using std::istream;
#include <iomanip>
using std::endl;
#include <cstdlib>
using std::abs;


struct Rational
{
    int _num;
    int _denom;
};

void add(Rational *lhs, Rational rhs);
void mult(Rational *lhs, Rational rhs);
bool equal(Rational lhs, Rational rhs);
void reduce(Rational *number);
int gcd(int a, int b);
void print(const char message[], Rational r);


int main()
{
    Rational a;
    Rational b = {1,2};
    Rational bad = {1,0};
    Rational c = {10,15};
    Rational verify1 = {7,5}, verify2 = {7,10};

    a._num = 27;
    a._denom = 30;
    print("a=", a);
    print("b=", b);

    print("bad=", bad);
    print("c=", c);
    reduce(&c);
    print("化簡後 c=", c);

    add(&a, b);
    print("a+b=", a);
    assert(equal(a,verify1));
    mult(&a, b);
    print("(a+b)*b=", a);
    assert(equal(a,verify2));

    return 0;
}


void print(const char message[], Rational r)
{
    cout << message << r._num << "/" << r._denom << endl;
}


void reduce(Rational *r)
{
    assert(r->_denom != 0);
    int divisor, num = abs(r->_num), denom = abs(r->_denom);
    if (num >= denom)
        divisor = gcd(num, denom);
    else
        divisor = gcd(denom, num);
    r->_num /= divisor;
    r->_denom /= divisor;
}


void add(Rational *lhs, Rational rhs)
{
// 將 *lhs 以及 rhs 兩個 有理數通分後相加,
// 化簡成最簡分數後存回 *lhs
}


void mult(Rational *lhs, Rational rhs)
{
    Rational temp;
    int divisor;
    temp._num = lhs->_num * rhs._num;
    temp._denom = lhs->_denom * rhs._denom;
    assert(temp._denom != 0);
    divisor = gcd(abs(temp._num), abs(temp._denom));
    temp._num /= divisor;
    temp._denom /= divisor;
    *lhs = temp;
}


bool equal(Rational lhs, Rational rhs)
{
// 比較兩個有理數 lhs 及 rhs 是否相等
// 注意: 這兩個數字不見得是最簡化的表示法
}


int gcd(int a, int b) // assume a>=b>=0
{
    if (b == 0) return a;
    return gcd(b, a%b);
}

時間: 40分鐘 (10:10 上傳時間截止)

  1. 請製作一個新的方案, 讓 Visual Studio 為方案建立目錄, 設定專案名稱為 C_Version, 將上述程式拷貝進 main.cpp
  2. 完成上面的 add() 與 equal() 函式
  3. 測試程式功能
  4. 請在方案中新增一個專案, 名稱是 CPP_Version
  5. 製作一個 C++ 版本的 Rational 類別, 類別裡有兩個資料成員和六個成員函式 (請注意前面 C 版本的有理數結構 (struct Rational) 沒有辦法保證結構裡面的有理數是以最簡方式存放, 但是在 C++ 版本裡請在個個成員函式裡保證以最簡方式存放, 並且保證沒有分母為 0 的有理數, 需要重新定義類別界面方法的參數, 函式參數或是 函式本身 可以使用 const 的地方請儘量使用, 使用 參考變數 可以簡化的地方請使用參考)
  6. 加入一個 main.cpp 內容包含上述 main.cpp 裡面的所有測試, 配合你定義的 Rational 類別界面, 測試後繳交
將所完成的 project (只需保留 .cpp, .h, .sln 以及 .vcxproj 檔案即可; 刪除掉 .suo, .sdf, .filters, .users, debug\ 資料匣, 以及 ipch\ 資料匣下的所有內容) 以 zip/rar/7zip 程式將整個資料匣壓縮起來, 選擇 Labtest1上傳
參考程式碼

C++ 物件導向程式設計課程 首頁

製作日期: 03/25/2015 by 丁培毅 (Pei-yih Ting)
E-mail: pyting@mail.ntou.edu.tw TEL: 02 24622192x6615
海洋大學 電機資訊學院 資訊工程學系 Lagoon