1. 程式人生 > >DLUT C++上機作業(實驗四)

DLUT C++上機作業(實驗四)

實驗4 運算子過載
1、 實驗目的和要求
(1) 掌握運算子過載的語法要點,理解成員函式與友元函式過載運算子的區別。
(2) 掌握各種運算子的過載方法,理解引用形式作為引數和返回值的特點。
2、 實驗內容
(1)定義描述平面點類Point,過載減號運算子計算兩個點的距離,分別用成員函式與友元函式實現。過載運算子<<輸出點的座標[x,y],給出類以及相關函式的定義。

#include<iostream>
#include<cmath>
#include<ostream>
#include<time.h>
using
namespace std; #define pow(a) (a*a) class point{ public: point(int = 0, int = 0); void setpoint(int, int); double operator-(point&); friend ostream&operator<<(ostream&, point&); // friend double operator-(point&, point&); private: int x; int y; }; point::point(int
a , int b ) :x(a), y(b){} double point::operator-(point &a){ return sqrt((double)pow(x - a.x) + (double)pow(y - a.y)); } void point::setpoint(int a, int b){ x = a, y = b; } ostream& operator<<(ostream&out, point&a){ out << a.x << " " << a.y; return
out; } /*double operator-(point&a, point&b){ return sqrt((double)pow(a.x - b.x) + (double)pow(a.y - b.y)); }*/ int main(){ point p1(2, 1), p2; double d = p1 - p2; cout << p1 << "->" << p2 << "=" << d << endl; }

(2) 描述有理數的Rational類如下,請補充類的其他成員使其能夠執行各種運算。
1)過載算術運算子“+”、“-”、“*”、“/”,使之能夠適用於有理數的四則運算。
2)過載比較運算子“>”、“ <=” 和“==”,使之能夠比較兩個有理數。
3)過載運算子“<<”,使其能以規範的方式輸出分數,如1/2,-1/3,分母不能為0。

#include<iostream>
#include<cmath>
#include<ostream>
#include<time.h>
using namespace std;
#define pow(a) (a*a)
#define LL long long int
LL gcd(LL a, LL b){
    a = abs(a);
    b = abs(b);
    if (a < b)swap(a, b);
    return b ? (gcd(b, a%b)) : a;
}
class rational{
private:
    LL num;
    LL den;
public:
    friend ostream&operator<<(ostream&,rational&a);
    bool operator<=(const rational&a);
    bool operator>=(const rational&a);
    bool operator==(const rational&a);
    rational operator+(const rational&a);
    rational operator-(const rational&a);
    rational operator*(const rational&a);
    rational operator/(const rational&a);
    rational(LL = 0, LL = 1);
    void simple();
};
rational::rational(LL a, LL b) :num(a), den(b){}
ostream&operator<<(ostream&out, rational&a){
    if(!a.den){
        out<<"error"<<endl;
        return out;
    }
    else if(!a.num){
        out<<0<<endl;
        return out;
    }
    else
    out << a.num << "/" << a.den << endl;
    return out;
}
bool rational::operator<=(const rational&a){
    return (double)num / den <= (double)a.num / a.den;
}
bool rational::operator>=(const rational&a){
    return (double)num / den >= (double)a.num / a.den;
}
bool rational::operator==(const rational&a){
    return (double)num / den == (double)a.num / a.den;
}
rational rational::operator+(const rational&a){
    LL d = den / gcd(den, a.den)*a.den;
    LL n = num*d /den + a.num*d / a.den;
    rational temp;
    temp.den = d;
    temp.num = n;
    temp.simple();
    return temp;
}
rational rational::operator-(const rational&a){
    rational temp = a;
    temp.num *= -1;
    return *this + temp;
}
rational rational::operator*(const rational&a){
    rational temp;
    temp.den = den*a.den;
    temp.num = num*a.num;
    temp.simple();
    return temp;
}
rational rational::operator / (const rational &a){
    rational temp;
    temp.num = num*a.den;
    temp.den = den*a.num;
    temp.simple();
    return temp;
}
void rational::simple(){
    LL g = gcd(num, den);
    den /= g;
    num /= g;
}
int main(){
    rational n1(1, 2);
    rational n2(0, 4);
    cout << n1 << endl << n2 << endl;
    cout << n1 + n2 << endl;
    cout << n1 - n2 << endl;
    cout << n1*n2 << endl;
    cout << n1 / n2 << endl;
    if (n1 <= n2)cout << n2 << endl;
    if (n1 == n2)cout << "==" << endl;
    if (n1 >= n2)cout << n2 << endl;
}

(3)定義一個集合類Set,最多存放100個不重複的整數,實現集合的如下操作:
1)增加某個整型元素時,保證集合中沒有重複元素;刪除指定的元素,查詢該元素在集合中則從集合中刪除該元素;
2)過載運算子“+”,實現兩個集合物件的合併操作,過載運算子“”,求兩個集合物件的交集;例如Set s, s1, s2; s = s1+s2; s = s1 s2;
3)過載賦值運算子=和複合賦值運算子-= , 實現兩個集合物件的賦值操作與差集操作。例如Set s1,s2;s1 = s2; s1-=s2; 集合S1中去掉S2中存在的元素。

#include<iostream>
#include<cmath>
#include<ostream>
#include<time.h>
#include<stdlib.h>
#include<algorithm>
#include<stack>
using namespace std;
#define pow(a) (a*a)
#define mem(arr,a) memset(arr,a,sizeof(arr))
#define N 100
#define LL long long int//個別編譯器可能不識別long long int,可改成long int
class set{
private:
    int *p;
public:
    void add(int);
    void del(int);
    set operator+(set&);
    set operator*(set&);
    set&operator=(set&);
    set&operator-=(set&);
    set();
    ~set();
    void show();
};
void set::show(){
    for (int i = 0; i < N; i++){
        if (p[i]){
            cout << i << " ";
        }
    }
    cout << endl;
}
set::set(){
    p = new int[N];
    for (int i = 0; i < N; i++)p[i] = 0;
//  mem(p, 0);
}
set::~set(){
    if (!p)delete[]p;
}
void set::add(int x){
    if (x >= N||x<0){
        cout << "mistake" << endl;
        return;
    }
    p[x] = 1;
}
void set::del(int x){
    if (x >= N || x < 0||!p[x]){
        cout << "mistake" << endl;
        return;
    }
    p[x] = 0;

}
set set::operator+(set&a){
    set temp;
    for (int i = 0; i < N; i++)
    {
        if (a.p[i] || p[i]){
            temp.p[i] = 1;
        }
    }
    return temp;
}
set set::operator*(set&a){
    set temp;
    for (int i = 0; i < N; i++){
        if (a.p[i] && p[i])
            temp.p[i] = 1;
    }
    return temp;
}
set& set::operator=(set&a){
    for (int i = 0; i < N; i++){
        p[i] = a.p[i];
    }
    return *this;
}
set&set::operator-=(set&a){
    for (int i = 0; i < N; i++){
        if (a.p[i]){
            p[i] = 0;
        }
    }
    return *this;
}
int main(){
    set s1, s2;
    for (int i = 0; i < 10; i++){
        s1.add(i);
    }
    for (int i = 5; i < 15; i++){
        s2.add(i);
    }
    s1.show();
    s2.show();
    set s3 = s1 + s2;
    s3.show();
    set s4 = s1 * s2;
    s4.show();
    s1 -= s2;
    s1.show();
    set s5;
    s5 = s1;
    s5.show();
}

(4)定義描述時間的Time類,包括資料成員小時hour、分鐘minute和秒second,定義相關函式實現如下操作:
1)過載運算子“+”與“-”,能夠實現時間物件與整數秒的加減操作。
2)過載運算子“<<”輸出時間物件,能夠按照“小時:分鐘:秒”的方式顯示時間。
3)過載運算子“++”與“–”,要求能夠實現時間的合理自增自減功能(秒數的增減)。

#include<iostream>
#include<cmath>
#include<ostream>
#include<time.h>
#include<stdlib.h>
#include<algorithm>
#include<stack>
using namespace std;
#define pow(a) (a*a)
#define mem(arr,a) memset(arr,a,sizeof(arr))
#define N 100
#define LL long long int
class Time{
private:
    int hour, minue, second;
public:
    Time operator+(int);
    Time operator-(int);
    friend ostream&operator<<(ostream&, Time&);
    Time &operator++();
    Time operator--(int);
    Time(int h,int m,int s);
    void change(Time&);
};
void Time::change(Time& a){
    if(a.second<0){
        second+=60;
        minue--;
        if(minue<0)
            {minue+=60;
        hour--;
        }
        if(hour<0){
            hour+=24;
        }
    }
}


ostream&operator<<(ostream&out, Time &a){
    out << a.hour << " " << a.minue << " " << a.second << endl;
    return out;
}
Time Time::operator+(int x){
    second += x;
    int s = second % 60;
    int m = second / 60;
    second = s;
    minue += m;
    int mm = minue % 60;
    int h = minue / 60;
    minue = mm;
    hour += h;
    hour %= 24;
    return *this;
}
Time Time::operator-(int a){
    second -= a;
    if (a < 0){
        minue--;
        if (minue < 0){
            hour--;
        }
    }
    change(*this);
    return *this;
}
Time&Time::operator++(){
    //*this.operator+(1);
    return *this+1;
}
Time Time::operator--(int){
    Time temp = *this;
    *this = *this - 1;
    change(*this);
    change(temp);
    return temp;
}
Time::Time(int h, int m, int s) :hour(h), minue(m), second(s){}
int main(){
    Time s(23, 59, 59);
    s++;
    cout << s << endl;
    s--;
    cout << s << endl;
    Time s1 = s + 3;
    cout << s1 << endl;
    s1 = s - 3;
    cout << s1 << endl;
}

(5)設計字串類String,若有String類物件s1、s2和s3,過載運算子實現如下操作:
1)過載“+”實現字串連線功能,使表示式s1= s2+s3成立;
2)過載“<”判斷兩個字串的大小
3)過載“<<”與“>>”,實現字串的輸入與輸出操作
4)過載運算子“()”,從字串物件中返回一個子串。

#include<iostream>
#include<cmath>
#include<ostream>
#include<time.h>
#include<stdlib.h>
#include<algorithm>
#include<stack>
#include<string>
using namespace std;
#define pow(a) (a*a)
#define mem(arr,a) memset(arr,a,sizeof(arr))
#define N 100
#define LL long long int//個別編譯器可能不識別long long int,可改成long int
class String{
private:
    string s;
    int m;
public:
    String operator()(int,int);
    friend ostream&operator<<(ostream&, String&);
    friend istream&operator>>(istream&in, String&a);
    String operator+(String &);
    bool operator<(String &);
};
String String::operator()(int a, int b){
    String temp;
    temp.s.assign(s, a, b);
    return temp;
}
String String::operator+(String &a){
    String temp;
    temp.s = s + a.s;
    return temp;
}
istream&operator>>(istream&in, String&a){
    in >> a.s;
    return in;
}
bool String::operator<(String&a){
    return s < a.s;
}
ostream& operator<<(ostream&out, String &a){
    out << a.s << endl;
    return out;
}

int main(){
    String s1, s2;
    cin >> s1;
    cin >> s2;
    String s3 = s1 + s2;
    cout << s3;
    cout << s1(1, 3) << endl;
    if (s1 < s2)cout << "s2" << endl;
    else cout << "s1" << endl;
}


(6)【選作】開發多項式類Polynomial,多項式的每一項用陣列或結構體表示,每項包含一個係數和一個指數。例如2x4的指數為4,係數為2。請開發一個完整的Polynomial類,包括建構函式、解構函式以及get函式和set函式。該類還要提供下述過載的運算子:
1)過載運算子“+”和“-”,將兩個多項式相加或相減。
2)過載乘法運算子“*”,將兩個多項式相乘。
3)過載賦值運算子“=”,將一個多項式賦給另外一個多項式。

怎麼說呢,反正是應付作業,寫的程式碼很時間空間複雜度都不小,而且有限制。。就這樣吧,,,。

#include<iostream>
#include<cmath>
#include<ostream>
#include<time.h>
#include<stdlib.h>
#include<algorithm>
#include<stack>
#include<string>
using namespace std;
//#define pow(a) (a*a)
#define mem(arr,a) memset(arr,a,sizeof(arr))
#define N 100
#define LL long long int//個別編譯器可能不識別long long int,可改成long int
class node{
public:
    int n, a;
};

class pol{
    node*s;
public:
    void set(int a, int n);
    pol();
    ~pol();
    LL get(int x);
    void show();
    pol operator+(pol&);
    pol operator-(pol&);
    pol operator*(pol&);
    pol&operator=(pol&);
};
pol::pol(){
    s = new node[N];
    for (int i = 0; i < N; i++)s[i].a = 0, s[i].n = 0;
}
pol::~pol(){
    cout << "delete" << endl;
}
void pol::set(int a, int n){
    s[n].a = a;
    s[n].n = n;
}
void pol::show(){
    bool flag = false;
    for (int i = 0; i < N; i++){
        if (s[i].a != 0){
            if (!flag)
                cout << s[i].a << "x^" << s[i].n, flag = true;
            else{
                cout << "+" << s[i].a << "x^" << s[i].n;
            }
        }
    }
    cout << endl;
}
pol pol::operator+(pol&a){
    pol temp;
    for (int i = 0; i < N; i++){
        if (a.s[i].a){
            temp.s[i].a = a.s[i].a + s[i].a;
            temp.s[i].n = a.s[i].n;
        }
    }
    return temp;
}
pol pol::operator-(pol&a){
    pol temp;
    for (int i = 0; i < N; i++){
        if (a.s[i].a){
            temp.s[i].a = s[i].a - a.s[i].a;
        }
    }
    return temp;
}
pol pol::operator*(pol&a){
    pol temp;
    for (int i = 0; i < N; i++){
        for (int j = 0; j < N; j++){
            if (s[i].a&&a.s[j].a){
                temp.s[i + j].a += s[i].a*a.s[j].a;
                temp.s[i + j].n = i + j;
            }
        }
    }
    return temp;
}
pol&pol::operator=(pol&a){
    for (int i = 0; i < N; i++){
        s[i].a = a.s[i].a;
        s[i].n = a.s[i].n;
    }
    return *this;
}
LL pol::get(int x){
    LL sum = 0;
    for (int i = 0; i < N; i++){
        sum += s[i].a*pow(x, s[i].n);
    }
    return sum;
}
int main(){
    pol s1, s2;
    for (int i = 0; i < 3; i++){
        s1.set(i, i);
        s2.set(i, 3 - i);
    }
    s1.show();
    s2.show();
    pol s = s1 + s2;
    s.show();
    s = s1*s2;
    s.show();
}