题目说明
抽象数据类型(ADT)的定义与实现: 复数a+bi,a为实部,b为虚部,请用C或C++语言定义和实现复数抽象数据类型。
要求能够输入两个实数作为实部和虚部,用于初始化(创建)一个复数,对任意的两个复数,能够按照复数运算规则进行加、减、乘运算,定义求复数的模,求共轭复数的算法,并实现两个复数相除,并输出对应的计算结果。
Author:Lee X;
Operating environment:Microsoft Visual Studio 2019
对于此次的题目,首先让我疑惑的是ADT,在计算机工作中,有些数字是比较难以表示的。例如有理数(可以 a/b 格式表示的数,且 a 和 b 都是整数)本来是不能在电脑中表示出来。不过可以合理的抽象数据类型来定义,如下。构造:使用两个整数 a 与 b 创建实体,其中 a 为分子,b 为分母。运算:加法、减法、乘法、除法、乘幕、比较、约分,转成实数(浮点数)。要完成整个规格,就要根据数据来定义所有的运算。例如,当两个有理数 a/b 和 c/d 相乘时,相乘的结果就要定义为 ( a c ) / ( b d )。还有输入、输出、先决条件、后置条件,以及对抽象数据类型的各种假定。
抽象数据类型(ADT)是纯粹理论实体,用于简化描述抽象算法,分类与评价数据结构,形式描述程序设计语言的类型系统。一个ADT可以用特定数据类型或数据结构实现,在许多程序设计语言中有许多种实现方式;或者用形式规范语言描述。ADT常实现为模块(module):模块的接口声明了对应于ADT操作的例程(procedure),有时用注释描述了约束。[来自维基百科]
看过题目后,对于C++熟悉的同学很容易能想到其中的complex库。为了日后的学习,现整理汇总如下的功能:
#include //complex头文件引用
std::complex<double> c{3,4}//表示3+4i,所以得知,complex<类型> 变量名(实部,虚部)
std::complex<double> c1,a;//初始化
d = real(a);// 返回复数a的实部,当然也可以写成a.real()下面不再赘述
a.real();
d = imag(a);// 返回复数a的虚部
d = abs(a);// 返回复数a的模值/幅值
d = norm(a);// 返回复数a的模值平方
d = arg(a);// 返回复数a的幅角
z = conj(a);// 返回复数a的共轭复数
c*c1,c/c1...;//符号运算
所以可见,使用complex头文件是比较方便的,但是我们也需要理解其中的意义。于是,使用C++面向对象的特性进行简易的复数运算,仅包含上述题目所要求的。(以下环境均为VS2019 enterprise版)
“Complex.h”
#pragma once
#ifndef COMPLEX_H
#define COMPLEX_H
#include
#include
using namespace std;
class Complex {
private:
float Real, Imag;
public:
Complex(float r = 0, float i = 0) {
Real = r;
Imag = i;
}
//显示输出复数
void show() {
cout << Real << "+" << Imag << "i";
}
Complex operator +(Complex& c);//"+"运算符重载完成复数间的加法运算
Complex operator +(float s);//"+"完成实部与实数的加法运算
Complex operator -(Complex& c);
Complex operator -(float s);
Complex operator *(Complex& c);
Complex operator *(float s);
Complex operator /(Complex& c);
Complex operator / (float s);
Complex conj(void);
float modu(void);
};
#endif
对于头文件,建立Complex类模板,同时数据类型为float,私有数据为实部与虚部,在公有操作中,进行了方法(成员函数)的编写,例如show,modu等,同时使用C++特性运算符重载(自定义运算),进行加减乘除的运算。
方法实现"Complex.cpp"
#include "Complex.h"
Complex Complex::operator +(Complex& c) {
Complex t;
t.Real = Real + c.Real;//以下均省略this->Real
t.Imag = Imag + c.Imag;
return t;
}
Complex Complex::operator +(float s) {
Complex t;
t.Real = Real + s;
t.Imag = Imag;
return t;
}
Complex Complex::operator-(Complex& c) {
Complex t;
t.Real = Real - c.Real;
t.Imag = Imag - c.Imag;
return t;
}
Complex Complex::operator-(float s) {
Complex t;
t.Real = Real + s;
t.Imag = Imag - s;
return t;
}
Complex Complex::operator *(Complex& c) {
Complex t;
t.Real = Real * c.Real - Imag * c.Imag;
t.Imag = Real * c.Imag + Imag * c.Real;
return t;
}
Complex Complex::operator *(float s) {
Complex t;
t.Real = Real * s;
t.Imag = Imag * s;
return t;
}
Complex Complex::operator /(Complex& c) {
Complex t;
if (c.Real != 0 && c.Imag != 0) {
t.Real = (Real * c.Real + Imag * c.Imag) / (c.Real * c.Real + c.Imag * c.Imag); //实部除积
t.Imag = (Imag * c.Real - Real * c.Imag) / (c.Real * c.Real + c.Imag * c.Imag); //虚部除积
return t;
}
else {
cout << "分母为0,不能执行命令";
return -1;
}
}
Complex Complex::operator /(float s) {
Complex t;
if (s != 0.0) {
t.Real = Real / s;
t.Imag = Imag / s;
return t;
}
else {
cout << "分母为0,不能执行命令";
return -1;
}
}
Complex Complex::conj(void) {
Complex t;
t.Real = Real;
t.Imag = -Imag;
return t;
}
float Complex::modu(void) {
return sqrt(Real * Real + Imag * Imag);
}
测试文件"Main.cpp"
#include
#include "Complex.h"
using namespace std;
int main() {
float a, b, c, d;
cout << "请输入第一个复数的实部与虚部:";
cin >> a >> b;
cout << "请输入第二个复数的实部与虚部:";
cin >> c >> d;
Complex A(a, b), B(c, d), C, D, E, F, G, H;
C = A + B, D = A - B, E = A * B, F = A / B, G = A.conj(), H = B.conj();
cout << "加法:"; A.show(); cout << "+"; B.show(); cout << "="; C.show(); cout << endl;
cout << "减法:"; A.show(); cout << "-"; B.show(); cout << "="; D.show(); cout << endl;
cout << "乘法:("; A.show(); cout << ")*("; B.show(); cout << ")="; E.show(); cout << endl;
cout << "除法:("; A.show(); cout << ")/("; B.show(); cout << ")="; F.show(); cout << endl;
cout << "共轭复数:"; A.show(); cout << ":"; G.show(); cout << " "; B.show(); cout << ":"; H.show(); cout << endl;
cout << "复数的模:"; A.show(); cout << ":" << A.modu(); cout << " "; B.show(); cout << ":" << B.modu() << endl;
return 0;
}
以上为C++的代码书写,采取了头文件测试文件等的运用,也比较直观,同时也起到了函数功能封装的作用。以上附完整代码(Main.cpp)
#include
#include
using namespace std;
class Complex{
private:
float Real,Imag;
public:
Complex(float r=0,float i=0){
Real=r;
Imag=i;
}
//显示输出复数
void show(){
cout<<Real<<"+"<<Imag<<"i";
}
Complex operator +(Complex &c);//"+"运算符重载完成复数间的加法运算
Complex operator +(float s);//"+"完成实部与实数的加法运算
Complex operator -(Complex &c);
Complex operator -(float s);
Complex operator *(Complex &c);
Complex operator *(float s);
Complex operator /(Complex &c);
Complex operator / (float s);
Complex conj(void);
float modu(void);
};
Complex Complex::operator +(Complex &c){
Complex t;
t.Real=Real+c.Real;
t.Imag=Imag+c.Imag;
return t;
}
Complex Complex::operator +(float s){
Complex t;
t.Real=Real+s;
t.Imag=Imag;
return t;
}
Complex Complex::operator-(Complex &c){
Complex t;
t.Real=Real-c.Real;
t.Imag=Imag-c.Imag;
return t;
}
Complex Complex::operator-(float s){
Complex t;
t.Real=Real+s;
t.Imag=Imag-s;
return t;
}
Complex Complex::operator *(Complex &c){
Complex t;
t.Real=Real*c.Real-Imag*c.Imag;
t.Imag=Real*c.Imag+Imag*c.Real;
return t;
}
Complex Complex::operator *(float s){
Complex t;
t.Real=Real*s;
t.Imag=Imag*s;
return t;
}
Complex Complex::operator /(Complex &c){
Complex t;
if(c.Real!=0&&c.Imag!=0){
t.Real=(Real*c.Real+Imag*c.Imag)/(c.Real*c.Real+c.Imag*c.Imag); //实部除积
t.Imag=(Imag*c.Real-Real*c.Imag)/(c.Real*c.Real+c.Imag*c.Imag); //虚部除积
return t;
}
else{
cout<<"分母为0,不能执行命令";
return -1;
}
}
Complex Complex::operator /(float s){
Complex t;
if(s!=0.0){
t.Real=Real/s;
t.Imag=Imag/s;
return t;
}
else{
cout<<"分母为0,不能执行命令";
return -1;
}
}
Complex Complex::conj(void){
Complex t;
t.Real=Real;
t.Imag=-Imag;
return t;
}
float Complex::modu(void){
return sqrt(Real*Real+Imag*Imag);
}
int main(){
float a,b,c,d;
cout<<"请输入第一个复数的实部与虚部:";
cin>>a>>b;
cout<<"请输入第二个复数的实部与虚部:";
cin>>c>>d;
Complex A(a,b),B(c,d),C,D,E,F,G,H;
C=A+B,D=A-B,E=A*B,F=A/B,G=A.conj(),H=B.conj();
cout<<"加法:";A.show();cout<<"+";B.show();C.show();cout<<endl;
cout<<"减法:";A.show();cout<<"-";B.show();D.show();cout<<endl;
cout<<"乘法:";A.show();cout<<"*";B.show();E.show();cout<<endl;
cout<<"除法:";A.show();cout<<"/";B.show();F.show();cout<<endl;
cout<<"共轭复数:";A.show();cout<<":";G.show();cout<<" ";B.show();cout<<":";H.show();cout<<endl;
cout<<"复数的模:";A.show();cout<<":"<<A.modu();cout<<" ";B.show();cout<<":"<<B.modu()<<endl;
return 0;
}