Lab 6: Complex Number Calculator

Lab 6-1: Enhanced Complex Numbers (40%)

  • 輸入:
    1. double 格式輸入複數的實數及虛數部分,以空格分開,一行輸入一個複數
    2. char 格式輸入複數的運算子,包含 +-*/,一行輸入一個運算子
    3. 複數與運算子以交錯的方式輸入,一行輸入一個複數接著一個運算子,倒數兩行為複數與完成輸入指令
    4. 輸入 Ctrl+D 完成輸入
      • Windows 請輸入 Ctrl+Z (會在螢幕上顯示 ^Z) 再輸入 Enter (Format 中的 ) 完成輸入
  • 輸出:
    1. 顯示運算複數的結果
      1. 格式請參考 Format 中的說明
    2. 若虛數部分為 0 則僅顯示實數部分
    3. 虛數及實數部分皆以預設 double 格式顯示
  • 檔名:lab6-1_<學號>.cpp (e.g. lab6-1_106062802.cpp)

注意事項:

  • 程式不會輸出任何使用者提示,只會輸出程式結果
  • 使用者不需要處理錯誤輸入
  • 請使用 pseudo code 提供的 main function 來處理輸入與輸出
  • 程式需要於 10 秒內完成,所有的測資皆會保證於 10 秒內完成

Format

<real 1> <imag 1>⏎
<op 1>⏎
<real 2> <imag 2>⏎
<op 2>⏎
...
<real n-1> <imag n-1>⏎
<op n-1>⏎
<real n> <imag n>⏎
^Z⏎
(-)<real result> (+|-) (<imag result>i)

Example

$ ./a.out
1.0 0.0⏎
^Z⏎
1
$ ./a.out
0.0 1.0⏎
^Z⏎
0 + 1i⏎
$ ./a.out
1.0 0.0⏎
+⏎
2.0 1.1⏎
-⏎
-3.0 -2.2⏎
*⏎
4.3 2.1⏎
/⏎
-1.2 -3.4⏎
^Z⏎
-8.74846 + 2.46231i
$ ./a.out
1.0 0.0⏎
+⏎
2.0 1.1⏎
-⏎
-3.0 -2.2⏎
*⏎
4.3 2.1⏎
/⏎
-1.2 3.4⏎
^Z⏎
5.26477 - 7.40815i

Pseudo Code

#include <iostream>
#include <string>
#include <sstream>

using namespace std;

class Complex
{
private:
    // data members
    // save the real and imaginary parts of the complex number
    // with `double` precision
    double m_real;
    double m_imag;

public:
    // Constructor, initializes real and imaginary parts
    Complex(const double &arg_real = 0.0, const double &arg_imag = 0.0);
    // Copy constructor
    Complex(const Complex &arg_c);
    // assignment operator
    Complex &operator=(const Complex &arg_c);
    // add assignment operator
    Complex &operator+=(const Complex &arg_c);
    // subtract assignment operator
    Complex &operator-=(const Complex &arg_c);
    // multiply assignment operator
    Complex &operator*=(const Complex &arg_c);
    // divide assignment operator
    Complex &operator/=(const Complex &arg_c);
    // add function
    Complex operator+(const Complex &arg_c) const;
    // subtract function
    Complex operator-(const Complex &arg_c) const;
    // multiply function
    Complex operator*(const Complex &arg_c) const;
    // divide function
    Complex operator/(const Complex &arg_c) const;
    // cout `<<` operator for print complex number
    // note: be careful about the format of output
    friend ostream &operator<<(ostream &arg_os, const Complex &arg_c);
    // cin `>>` operator for input complex number
    // note: be careful about the format of input
    // hint: use `stod` to convert string to double
    friend istream &operator>>(istream &arg_is, Complex &arg_c);
};

// used for process the test cases, do not modify
int main()
{
    string input;
    Complex result_complex;
    char op = ' ';

    while (getline(cin, input))
    {
        // input is a operation
        if (input == "+" || input == "-" || input == "*" || input == "/")
        {
            op = input[0];
            continue;
        }
        else if (input.empty())
        {
            continue;
        }
        // input is a complex number
        else
        {
            stringstream ss(input);
            Complex current_complex;
            ss >> current_complex;
            switch (op)
            {
            case '+':
                result_complex += current_complex;
                break;
            case '-':
                result_complex -= current_complex;
                break;
            case '*':
                result_complex *= current_complex;
                break;
            case '/':
                result_complex /= current_complex;
                break;
            case ' ':
                result_complex = current_complex;
                break;
            default:
                cerr << "Error: unknown operation" << endl;
                return 1;
            }
        }
    }
    cout << endl;
    cout << result_complex << endl;
    return 0;
}

Reference Code:

陳誼倫(110021127)

#include <iostream>
#include <string>
#include <sstream>

using namespace std;

class Complex
{
private:
    // data members
    // save the real and imaginary parts of the complex number
    // with `double` precision
    double m_real;
    double m_imag;

public:
    // Constructor, initializes real and imaginary parts
    Complex(const double &arg_real = 0, const double &arg_imag = 0);
    // Copy constructor
    Complex(const Complex &arg_c);
    // assignment operator
    ~Complex() {}
    Complex &operator=(const Complex &arg_c);
    // add assignment operator
    Complex &operator+=(const Complex &arg_c);
    // subtract assignment operator
    Complex &operator-=(const Complex &arg_c);
    // multiply assignment operator
    Complex &operator*=(const Complex &arg_c);
    // divide assignment operator
    Complex &operator/=(const Complex &arg_c);

    // cout `<<` operator for print complex number
    // note: be careful about the format of output
    friend ostream &operator<<(ostream &arg_os, const Complex &arg_c);
    // cin `>>` operator for input complex number
    // note: be careful about the format of input
    // hint: use `stod` to convert string to double
    friend istream &operator>>(istream &arg_is, Complex &arg_c);
};
Complex::Complex(const double &arg_real, const double &arg_imag)
    : m_real(arg_real), m_imag(arg_imag) {}

Complex::Complex(const Complex &arg_point)
    : m_real(arg_point.m_real), m_imag(arg_point.m_imag) {}

Complex &Complex::operator=(const Complex &arg_c)
{
    this->m_real = arg_c.m_real;
    this->m_imag = arg_c.m_imag;
    return *this;
}
Complex &Complex::operator+=(const Complex &arg_c)
{
    this->m_real += arg_c.m_real;
    this->m_imag += arg_c.m_imag;
    return *this;
}
Complex &Complex::operator-=(const Complex &arg_c)
{
    this->m_real -= arg_c.m_real;
    this->m_imag -= arg_c.m_imag;
    return *this;
}
Complex &Complex::operator*=(const Complex &arg_c)
{
    double _real = this->m_real, _imag = this->m_imag;
    this->m_real = (_real * arg_c.m_real) - (_imag * arg_c.m_imag);
    this->m_imag = (_real * arg_c.m_imag) + (_imag * arg_c.m_real);
    return *this;
}
Complex &Complex::operator/=(const Complex &arg_c)
{
    double _real = this->m_real, _imag = this->m_imag;
    this->m_real = ((_real * arg_c.m_real) + (_imag * arg_c.m_imag)) 
        / ((arg_c.m_real * arg_c.m_real + arg_c.m_imag * arg_c.m_imag));
    this->m_imag = ((-_real * arg_c.m_imag) + (_imag * arg_c.m_real)) 
        / ((arg_c.m_real * arg_c.m_real + arg_c.m_imag * arg_c.m_imag));
    return *this;
}
std::ostream &operator<<(std::ostream &arg_os, const Complex &arg_point)
{
    if (arg_point.m_imag == 0)
    {
        arg_os << arg_point.m_real;
        return arg_os;
    }
    else if (arg_point.m_imag < 0)
    {
        arg_os << arg_point.m_real << " - " << -arg_point.m_imag << "i ";
        return arg_os;
    }
    else
    {
        arg_os << arg_point.m_real << " + " << arg_point.m_imag << "i ";
        return arg_os;
    }
}

// read the coordinate of a point from the input, format: (x, y) and ignore space
std::istream &operator>>(std::istream &arg_is, Complex &arg_point)
{
    string str_x, str_y, temp;

    if (getline(arg_is, str_x, ' '))
    {
        if (getline(arg_is, str_y, ' '))
        {
            arg_point.m_real = stod(str_x);
            arg_point.m_imag = stod(str_y);
        }
    }

    return arg_is;
}

// used for process the test cases, do not modify
int main()
{
    string input;
    Complex result_complex;
    char op = ' ';

    while (getline(cin, input))
    {
        // input is a operation
        if (input == "+" || input == "-" || input == "*" || input == "/")
        {
            op = input[0];
            continue;
        }
        else if (input.empty())
        {
            continue;
        }
        // input is a complex number
        else
        {
            stringstream ss(input);
            Complex current_complex;
            ss >> current_complex;
            switch (op)
            {
            case '+':
                result_complex += current_complex;
                break;
            case '-':
                result_complex -= current_complex;
                break;
            case '*':
                result_complex *= current_complex;
                break;
            case '/':
                result_complex /= current_complex;
                break;
            case ' ':
                result_complex = current_complex;
                break;
            default:
                cerr << "Error: unknown operation" << endl;
                return 1;
            }
        }
    }
    cout << endl;
    cout << result_complex << endl;
    return 0;
}

林恩佑(109021107)

#include <iostream>
#include <string>
#include <sstream>

using namespace std;

class Complex
{
private:
    // data members
    // save the real and imaginary parts of the complex number
    // with double precision
    double m_real;
    double m_imag;

public:
    // Constructor, initializes real and imaginary parts
    Complex(const double &arg_real = 0.0, const double &arg_imag = 0.0);
    // Copy constructor
    Complex(const Complex &arg_c);
    // assignment operator
    Complex &operator=(const Complex &arg_c);
    // add assignment operator
    Complex &operator+=(const Complex &arg_c);
    // subtract assignment operator
    Complex &operator-=(const Complex &arg_c);
    // multiply assignment operator
    Complex &operator*=(const Complex &arg_c);
    // divide assignment operator
    Complex &operator/=(const Complex &arg_c);
    // add function
    Complex operator+(const Complex &arg_c) const;
    // subtract function
    Complex operator-(const Complex &arg_c) const;
    // multiply function
    Complex operator*(const Complex &arg_c) const;
    // divide function
    Complex operator/(const Complex &arg_c) const;
    // cout `<<` operator for print complex number
    // note: be careful about the format of output
    friend ostream &operator<<(ostream &arg_os, const Complex &arg_c);
    // cin `>>` operator for input complex number
    // note: be careful about the format of input
    // hint: use stod to convert string to double
    friend istream &operator>>(istream &arg_is, Complex &arg_c);
};

Complex::Complex(const double &arg_real, const double &arg_image)
    : m_real(arg_real), m_imag(arg_image)
{
}

Complex::Complex(const Complex &arg_c)
    : m_real(arg_c.m_real), m_imag(arg_c.m_imag)
{
}

Complex &Complex::operator=(const Complex &arg_c)
{
    m_real = arg_c.m_real;
    m_imag = arg_c.m_imag;
    return *this;
}

Complex &Complex::operator+=(const Complex &arg_c)
{
    m_real += arg_c.m_real;
    m_imag += arg_c.m_imag;
    return *this;
}

Complex &Complex::operator-=(const Complex &arg_c)
{
    m_real -= arg_c.m_real;
    m_imag -= arg_c.m_imag;
    return *this;
}

Complex &Complex::operator*=(const Complex &arg_c)
{
    Complex a;
    a.m_real = m_real;
    a.m_imag = m_imag;
    m_real = a.m_real * arg_c.m_real - a.m_imag * arg_c.m_imag;
    m_imag = a.m_real * arg_c.m_imag + arg_c.m_real * a.m_imag;
    return *this;
}

Complex &Complex::operator/=(const Complex &arg_c)
{
    Complex a;
    a.m_real = m_real;
    a.m_imag = m_imag;
    m_real = (a.m_real * arg_c.m_real + a.m_imag * arg_c.m_imag) 
        / (arg_c.m_real * arg_c.m_real + arg_c.m_imag * arg_c.m_imag);
    m_imag = (arg_c.m_real * a.m_imag - a.m_real * arg_c.m_imag) 
        / (arg_c.m_real * arg_c.m_real + arg_c.m_imag * arg_c.m_imag);
    return *this;
}

ostream &operator<<(ostream &arg_os, const Complex &arg_c)
{
    if (arg_c.m_imag == 0)
    {
        arg_os << arg_c.m_real;
    }
    else if (arg_c.m_imag < 0)
    {
        arg_os << arg_c.m_real << " - " << 0.0 - arg_c.m_imag << "i";
    }
    else
    {
        arg_os << arg_c.m_real << " + " << arg_c.m_imag << "i";
    }
    return arg_os;
}

istream &operator>>(istream &arg_is, Complex &arg_c)
{
    string strs;
    size_t sz;
    arg_c = {0, 0};
    arg_is >> strs;
    try
    {
        arg_c.m_real = stod(strs);
    }
    catch (const invalid_argument &ia)
    {
    }
    strs = "";
    arg_is >> strs;
    try
    {
        arg_c.m_imag = stod(strs);
    }
    catch (const invalid_argument &ia)
    {
    }
    return arg_is;
}

// used for process the test cases, do not modify
int main()
{
    string input;
    Complex result_complex;
    char op = ' ';

    while (getline(cin, input))
    {
        // input is a operation
        if (input == "+" || input == "-" || input == "*" || input == "/")
        {
            op = input[0];
            continue;
        }
        else if (input.empty())
        {
            continue;
        }
        // input is a complex number
        else
        {
            stringstream ss(input);
            Complex current_complex;
            ss >> current_complex;
            switch (op)
            {
            case '+':
                result_complex += current_complex;
                break;
            case '-':
                result_complex -= current_complex;
                break;
            case '*':
                result_complex *= current_complex;
                break;
            case '/':
                result_complex /= current_complex;
                break;
            case ' ':
                result_complex = current_complex;
                break;
            default:
                cerr << "Error: unknown operation" << endl;
                return 1;
            }
        }
    }
    cout << endl;
    cout << result_complex << endl;
    return 0;
}