本篇文章是C++程序设计的第二篇文章。上次我其实已经写过一篇关于C++程序设计的文章,最近又在整理电脑资料的时候发现了另外一份之前大一下暑期学校的C++程序设计大作业,所以希望跟大家进行一个分享。
大一下暑期学校C++课程设计
课程设计题目
题目:iMatlab软件的设计
项目要求:近年来美国对中国科技方面的打压和制裁愈演愈烈,某国防七子学校已经被剥夺了使用Matlab的机会。本项目旨在打破矩阵计算软件的封锁,研发出属于国人自己的矩阵计算软件。为了达成这一目标,下面有几个要求需要达成:
- 基本矩阵计算的操作
- 用户输入表达式的读取和解析
- 精美的用户界面
- 拓展:尽可能快速的计算速度
-
解决方案及代码
实现矩阵的基本运算
矩阵的基本运算包含矩阵的加减乘除\exp\log等运算结果,下面具体展开叙述。
(本次项目还是依托于大一下所学习的C++知识,所以在项目中会包含许多的类、运算符重载、友元函数、构造析构函数、I/O flow等知识,后来也知道了也许有更好的实现方法,但是当时确实不失为一种巩固所学知识的方法,所以大佬看见有些地方的操作过于繁琐的话请自动无视~)
矩阵类的构建:class Cmatrix//from刘彦迪{private:double matrixname;double rat;int row;int col;int rownow;int colnow;double** Matrix;public:Cmatrix(){row = col = colnow = rownow = 0;rat = 1;Matrix = new double* [1000];for (int i = 0; i < 1000; i++)Matrix[i] = new double[1000];}Cmatrix(int number){row = col = number;rat = 1;Matrix = new double* [1000];for (int i = 0; i < 1000; i++)Matrix[i] = new double[1000];for (int i = 0; i < row; i++)for (int j = 0; j < col; j++){Matrix[i][j] = 0;}for (int i = 0; i < number; i++){Matrix[i][i] = 1;}}double Getrat() { return this->rat; }const int Getrow() const { return this->row; }const int Getcol() const { return this->col; }const double Getrat() const { return this->rat; }void Setrow(int rownum) { this->row = rownum; }void Setcol(int colnum) { this->col = colnum; }void Setrat(double ratnum) { this->col = ratnum; }const double Getname() const { return this->matrixname; }const double Getmatrix(int row, int col) const { return this->Matrix[row][col]; }double** Getmatrixi() { return this->Matrix; }void Modify(int row, int col, double x) { this->Matrix[row][col] = x; }void Adddata(double data){if (row == 0)row++;Matrix[rownow][colnow] = data;colnow++;col = colnow;}void Change(){row++;rownow++;colnow = 0;}};
矩阵的求逆函数:
Cmatrix inv(){if (this->det() == 0 || this->row != this->col){cout << "无逆矩阵!" << endl;return *this;}Cmatrix tempo(this->row);Cmatrix tempo2 = this->Plus(tempo);Cmatrix tempo3 = tempo2.Lst();Cmatrix tempo4;tempo4.row = this->row; tempo4.col = this->col;for (int i = 0; i < tempo4.row; i++)for (int j = 0; j < tempo4.col; j++){tempo4.Matrix[i][j] = tempo3.Matrix[i][j + this->col];}return tempo4;}
矩阵的加减乘除(重载实现),注意除法相当于取逆,所以需要加判断条件:
Cmatrix& operator=(const Cmatrix& m){this->matrixname = m.Getname();this->row = m.Getrow();this->col = m.Getcol();rownow = 0;colnow = 0;for (int i = 0; i < row; i++){for (int j = 0; j < col; j++){this->Matrix[i][j] = m.Matrix[i][j];}}return *this;}Cmatrix operator +(Cmatrix& another){if ((this->row != another.row) || (this->col != another.col)){cout << "无法进行相加" << endl;ifnotadd = 1;return *this;}Cmatrix tempo;tempo.row = row;tempo.col = col;for (int i = 0; i < row; i++)for (int j = 0; j < col; j++)tempo.Matrix[i][j] = this->Matrix[i][j] + another.Matrix[i][j];return tempo;}Cmatrix operator -(Cmatrix& another){if ((this->row != another.row) || (this->col != another.col)){cout << "无法进行相减" << endl;ifnotsub = 1;return *this;}Cmatrix tempo;tempo.row = row;tempo.col = col;for (int i = 0; i < row; i++)for (int j = 0; j < col; j++)tempo.Matrix[i][j] = this->Matrix[i][j] - another.Matrix[i][j];return tempo;}Cmatrix operator *(Cmatrix& another){if (this->col != another.row){cout << "无法进行相乘" << endl;ifnotmul = 1;return *this;}Cmatrix tempo;tempo.row = this->row;tempo.col = another.col;for (int i = 0; i < tempo.row; i++)for (int j = 0; j < tempo.col; j++){double numbernow = 0;for (int p = 0; p < this->col; p++)numbernow += this->Matrix[i][p] * another.Matrix[p][j];tempo.Matrix[i][j] = numbernow;}return tempo;}Cmatrix operator /(Cmatrix& another){if (another.det() == 0){cout << "无法进行相除" << endl;ifnotdiv = 1;return *this;}Cmatrix tempo = another.inv();Cmatrix tempo2 = (*this) * tempo;return tempo2;}
矩阵的Concatenate、log\exp函数和转置函数: ```cpp Cmatrix Plus(Cmatrix another) { Cmatrix temp; temp.row = this->row; temp.col = this->col + another.col; for (int i = 0; i < this->row; i++)
for (int j = 0; j < this->col; j++){temp.Matrix[i][j] = this->Matrix[i][j];}
int start = this->col; for (int i = 0; i < this->row; i++)
for (int j = start; j < temp.col; j++){temp.Matrix[i][j] = another.Matrix[i][j - start];}
return temp; }
Cmatrix ilog() { if (this->row != 1 && this->col != 1) { cout << “没法采用log计算” << endl; return this; } Cmatrix tempo; tempo.row = 1; tempo.col = 1; tempo.Matrix[0][0] = log(this->Matrix[0][0]); return tempo; } Cmatrix iexp() { if (this->row != 1 && this->col != 1) { cout << “没法采用exp计算” << endl; return this; } Cmatrix tempo; tempo.row = 1; tempo.col = 1; tempo.Matrix[0][0] = exp(this->Matrix[0][0]); return tempo; }
Cmatrix matt() { Cmatrix tempo; tempo.row = this->col; tempo.col = this->row; for (int i = 0; i < tempo.row; i++) { for (int j = 0; j < tempo.col; j++) { tempo.Matrix[i][j] = this->Matrix[j][i]; } } return tempo; }
矩阵的求秩和求行列式:```cppdouble det(){if (this->row != this->col) std::abort();if (this->ranks() < this->row) return 0;Cmatrix temp = this->Lst();double det = this->rat;for (int i = 0; i < temp.col; i++)det *= temp.Matrix[i][i];return det;}int ranks(){Cmatrix a; a.row = this->row; a.col = this->col;for (int i = 0; i < a.row; i++)for (int j = 0; j < a.col; j++)a.Matrix[i][j] = this->Matrix[i][j];Cmatrix b = a.Lst();int rank = 0;for (int i = 0; i < row; i++){if (!b.Checkzero(i + 1)) rank++;else break;}return rank;}
实现矩阵的拓展运算
除开上面提及的一些基本运算,矩阵还有一些其他的功能可以实现。下面是我完成的一些拓展实现(有一些函数应该还有一些bug现在还没有解决,也有可能有其他我根本未尝那个发现的bug还存在着~)
矩阵的化简(就是把一些无限趋近于0的值改为0),然后还有一个让我当时花了非常大功夫的函数,就是化行最简式,代码如下:
void Simplify(){for (int i = 0; i < this->row; i++)for (int j = 0; j < this->col; j++){if (abs(this->Matrix[i][j]) < 0.0001){this->Matrix[i][j] = 0;}}for (int i = 0; i < this->row; i++){if (!Checkzero(i + 1)) continue;else{int p = i + 1;for (; p < this->row; p++){if (!Checkzero(p + 1)){for (int j = 0; j < this->col; j++)Swap(i + 1, j + 1, p + 1, j + 1);break;}}if (p == this->row) break;}}}Cmatrix Lst()//化行最简式{Cmatrix tempo;tempo.row = this->row;tempo.col = this->col;for (int i = 0; i < tempo.row; i++){for (int j = 0; j < tempo.col; j++)tempo.Matrix[i][j] = this->Matrix[i][j];}double ratio = 0;f:for (int i = 0; i < tempo.row; i++){for (int j = 0; j < i; j++){if (tempo.Matrix[j][j] == 0 && j != tempo.row - 2){for (int p = i + 1; p < tempo.row; p++){if (tempo.Matrix[p][j] != 0){for (int y = 0; y < tempo.col; y++){tempo.Swap(j + 1, y + 1, p + 1, y + 1);}break;}}goto f;}if (tempo.Matrix[j][j] == 0 && tempo.Matrix[i][j] != 0 && j == tempo.row - 2){for (int y = 0; y < tempo.col; y++){tempo.Swap(j + 1, y + 1, tempo.row, y + 1);}}if (tempo.Matrix[j][j] == 0 && tempo.Matrix[i][j] == 0 && j == tempo.row - 2){int seed = j + 1;while (tempo.Matrix[j][seed] == 0 && seed < tempo.col){seed++;}if (seed == tempo.col){for (int i = 0; i < tempo.row; i++){if (tempo.Checkzero(i + 1)) continue;for (int j = 0; j < tempo.col; j++){if (tempo.Matrix[i][j] != 0){tempo.Multi(i + 1, 1 / tempo.Matrix[i][j]); break;}}}goto g;}ratio = tempo.Matrix[i][seed] / tempo.Matrix[j][seed];for (int start = seed; start < tempo.col; start++){tempo.Matrix[i][start] -= ratio * tempo.Matrix[j][start];}break;}ratio = tempo.Matrix[i][j] / tempo.Matrix[j][j];for (int start = j; start < tempo.col; start++)tempo.Matrix[i][start] -= ratio * tempo.Matrix[j][start];}}tempo.Simplify();for (int i = 0; i < tempo.row; i++){if (tempo.Checkzero(i + 1)) continue;for (int j = 0; j < tempo.col; j++){if (tempo.Matrix[i][j] != 0){tempo.Multi(i + 1, 1 / tempo.Matrix[i][j]); break;}}}tempo.Simplify();g:int rank = 0;for (int i = 0; i < row; i++){if (!tempo.Checkzero(i + 1)) rank++;else break;}for (int i = 1; i < rank; i++){int seed = 0;for (int j = 0; j < tempo.col; j++){if (tempo.Matrix[rank - i][j] == 0) seed++;else{break;}}for (int p = 0; p < rank - i; p++){ratio = tempo.Matrix[p][seed];for (int y = seed; y < tempo.col; y++){tempo.Matrix[p][y] -= ratio * tempo.Matrix[rank - i][y];}}}tempo.Simplify();this->rat = tempo.rat;return tempo;}
矩阵的施密特正交化(不知道为什么想着去实现它,代码如下:
Cmatrix Sch()
{
for (int j = 0; j < this->col; j++)
{
if (Checkzero2(j + 1))
{
cout << "这个矩阵不能施密特正交化" << endl;
return *this;
}
}
Cmatrix tem = *this;
for (int j = 1; j < tem.col; j++)
{
Cmatrix reserve = tem.vectorn(j + 1);
for (int p = 0; p < j; p++)
{
Cmatrix tempo = tem.vectorn(p + 1);
double ratio = -reserve.inpro(tempo) / tempo.inpro(tempo);
tem.Swap_add(j + 1, p + 1, ratio);
}
}
return tem;
}
利用矩阵求解线性方程组,个人感觉这个功能还是很有用的,而且挺强大的,对于无解的方程可以自动采用最小二乘法求出最佳的近似解,代码如下:
Cmatrix Sol(Cmatrix answ)
{
int n = 0;
Cmatrix tempo5 = this->Plus(answ);
if (this->row != answ.row)
{
return *this;
}
if (this->ranks() != tempo5.ranks())
{
n = 1;
}
else
{
n = 2;
}
Cmatrix tempo;
if (n == 1) tempo = this->Plus(answ);
if (n == 2)
{
Cmatrix thisT = this->matt() * (*this);
Cmatrix answ2 = this->matt() * answ;
tempo = thisT.Plus(answ2);
}
Cmatrix tempo2 = tempo.Lst();
Cmatrix tempo3 = tempo2;
int freedom = this->col - this->ranks();
cout << "自由变量有" << freedom << "个" << endl;
tempo3.Simplify();
cout << "tempo3为:" << endl;
for (int i = 0; i < tempo3.row; i++)
{
for (int j = 0; j < tempo3.col; j++)
{
cout << tempo3.Matrix[i][j] << " ";
}
cout << endl;
}
cout << endl;
int* trueorfalse; trueorfalse = new int[this->col];
for (int i = 0; i < this->col; i++)
trueorfalse[i] = 0;
for (int i = 0; i < this->row; i++)
{
int seed = 0;
for (int j = 0; j < tempo3.ranks(); j++)
{
if (tempo3.Matrix[i][j] == 0) seed++;
else
{
if (trueorfalse[seed] == 0)
{
trueorfalse[seed] = 1;
}
}
}
}
int* freedomnum = new int[freedom];
int record = 0;
for (int i = 0; i < this->col; i++)
{
if (trueorfalse[i] == 0)
{
freedomnum[record] = i; record++;
}
}
Cmatrix answer; answer.row = this->col; answer.col = 1;
for (int i = 0; i < answer.row; i++)
{
if (trueorfalse[i] == 1)
answer.Matrix[i][0] = tempo3.Matrix[i][tempo3.col - 1];
else
answer.Matrix[i][0] = 0;
}
Cmatrix answer2; answer2.row = this->col; answer2.col = freedom;
int j = 0;
for (; j < answer2.col; j++)
{
for (int i = 0; i < answer2.row; i++)
{
if (i != freedomnum[j] && tempo3.Matrix[i][freedomnum[j]] != 0)
answer2.Matrix[i][j] = -tempo3.Matrix[i][freedomnum[j]];
else if (i != freedomnum[j] && tempo3.Matrix[i][freedomnum[j]] == 0)
answer2.Matrix[i][j] = 0;
else
answer2.Matrix[i][j] = 1;
}
}
Cmatrix total = answer.Plus(answer2);
return total;
}
用户指令的读取和解析
这个部分感觉是重头戏之一,但是这个部分不是我写的,是我队伍里一个大佬写的,所以这个部分就不详细展开叙述了,大致过程如下:
- 定义一些容器存储指令
- 限定指令具有一定强制的格式(识别的关键
- 通过一些字符的识别来翻译指令
常见的指令主要包括数字、关键字、空格、括号、运算符号和矩阵等。所以我们要做的就是去匹配表达式,这里的表达式又分为前缀和中缀的,所以需要分别处理:
这里使用哈希表用来进行指令功能的匹配,如def就是定义一个变量,sol就是求解线性方程组,draw就是画点还有cal就是进行矩阵计算等等:
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <cstring>
#include <ctime>
#include <Windows.h>
using namespace std;
int ifnotadd = 0;
int ifnotsub = 0;
int ifnotmul = 0;
int ifnotdiv = 0;
class Dictionary
{
private:
int* dic;//哈希表,支持五位长度的单词
public:
Dictionary()
{
dic = new int[100000000];
char path[] = "../hash.txt";
ifstream fin(path);
int i = 0;
while (!fin.eof())
{
char name[6];
int xname = 0;
int value = 0;
fin >> name;
fin >> value;
for (int i = 0;i < 6;i++)
{
if (name[i] >= 'a' && name[i] <= 'z')
{
xname = xname * 26 + (name[i] - 'a' + 1);
}
else if (name[i] >= 'A' && name[i] <= 'Z')
{
xname = xname * 26 + (name[i] - 'A' + 1);
}
else break;
}
dic[xname] = value;
/*cout << xname << ' ' << value << endl;*/
}
fin.close();
}
~Dictionary()
{
if (dic)
{
delete[] dic;
dic = 0;
}
}
int Trans(int word)
{
if (dic[word] < 0)return -1;
else return dic[word];
}
};
class Quantity
{
private:
int quaname;
double quanum;
friend class QuantityList;
};
class QuantityList
{
private:
Quantity* list;
int quantitysize;
public:
QuantityList()
{
list = new Quantity[1001];
quantitysize = 0;
}
~QuantityList()
{
if (list)
{
delete[] list;
list = 0;
}
}
void AddQuantity(int name, double num)
{
for (int i = 0;i < quantitysize;i++)
{
if (list[i].quaname == name)
{
list[i].quanum = num;
return;
}
}
list[quantitysize].quaname = name;
list[quantitysize].quanum = num;
quantitysize++;
}
void PrintQuantity()
{
cout << "共" << quantitysize << "个变量" << endl;
for (int i = 0;i < quantitysize;i++)
{
cout << "变量名: " << list[i].quaname << endl;
cout << "值: " << list[i].quanum << endl << endl;
}
}
double CheckQuantity(int name)
{
for (int i = 0;i < quantitysize;i++)
{
if (list[i].quaname == name)
{
return list[i].quanum;
}
}
return 0;
}
friend class Order;
};
class MatrixQuantityList
{
private:
Cmatrix* matrixlist;
int matrixsize;
public:
MatrixQuantityList()
{
matrixlist = new Cmatrix[100];
matrixsize = 0;
}
~MatrixQuantityList()
{
if (matrixlist)
{
delete[] matrixlist;
matrixlist = 0;
}
}
int GetMatrixQuantityListSize() { return matrixsize; }
Cmatrix GetMatrix(int i) { return matrixlist[i]; }
int AddMatrix(Cmatrix& other)
{
for (int i = 0;i < matrixsize;i++)
{
if (matrixlist[i].matrixname == other.matrixname && matrixlist[i].matrixname != 0)
{
matrixlist[i] = other;
return i;
}
}
matrixlist[matrixsize] = other;
matrixsize++;
return matrixsize - 1;
}
int CheckMatrix(double x)
{
for (int i = 0;i < matrixsize;i++)
{
if (matrixlist[i].matrixname == x)
{
return i;
}
}
return 0;
}
void PrintMatrix()
{
cout << "共" << matrixsize << "个矩阵" << endl;
for (int i = 0;i < matrixsize;i++)
{
cout << matrixlist[i] << endl;
}
}
friend class Order;
};
class Point2D
{
private:
double x = 0;
double y = 0;
public:
void AddPoint(double x, double y)
{
this->x = x;
this->y = y;
}
friend class Point2DList;
friend class Order;
};
class Point2DList
{
private:
Point2D* list;
int Point2Dsize;
public:
Point2DList()
{
list = new Point2D[200];
Point2Dsize = 0;
}
~Point2DList()
{
if (list)
{
delete[] list;
list = 0;
}
}
void AddPoint2D(double x, double y)
{
list[Point2Dsize].AddPoint(x, y);
Point2Dsize++;
}
void LimitPoint2D()
{
double xmax = fabs(list[0].x), ymax = fabs(list[0].y);
for (int i = 1;i < Point2Dsize;i++)
{
if (fabs(list[i - 1].x) < fabs(list[i].x)) xmax = fabs(list[i].x);
if (fabs(list[i - 1].y) < fabs(list[i].y)) ymax = fabs(list[i].y);
}
double kx = 5 / xmax, ky = 4 / ymax;
for (int i = 0;i < Point2Dsize;i++)
{
list[i].x *= kx;
list[i].y *= ky;
}
}
void Print()
{
for (int i = 0;i < Point2Dsize;i++) cout << list[i].x << ' ' << list[i].y << endl;
}
};
class UnknownNum
{
private:
double name = 0;
int line = 0;
int col = 0;
double value = 0;
friend class UnknownList;
};
class UnknownList
{
private:
UnknownNum list[20];
int size = 0;
int UnknownSize = 0;
public:
void Add(double text, int linenum, double num)
{
bool bz = false;
for (int i = 0;i < size;i++)
{
if (list[i].name == text)
{
if (list[i].line == linenum)
{
list[i].value += num;
return;
}
else
{
bz = true;
list[size].col = list[i].col;
}
}
}
if (bz == false)
{
list[size].col = UnknownSize;
UnknownSize++;
}
list[size].name = text;
list[size].line = linenum;
list[size].value = num;
size++;
}
void Print()
{
cout << "共" << size << "个 有" << UnknownSize-1 << "个未知数" << endl;
for (int i = 0;i < size;i++)
{
cout << list[i].name << ' ' << list[i].line << ' ' << list[i].col << ' ' << list[i].value << endl;
}
}
int Getzero()
{
for (int i = 0;i < size;i++)
{
if (list[i].name == 0) return list[i].col;
}
}
double Check(int line, int col)
{
for (int i = 0;i < size;i++)
{
if (list[i].line == line && list[i].col == col ) return list[i].value;
}
return 0.0;
}
friend class Order;
};
//定义一个double型二维数组,第一位存储数据类型,第二位存储值
//数据类型:括号-0;数字-1;中缀运算符-2;关键字-3;断字符-4;等于号-5;变量-6;矩阵-7
//括号:小左-0;小右-1;中左-2;中右-3;大左-4;大右-5
//中缀:加-0;减-1;乘-2;除-3
//断字符:逗号-0;分号-1;
class Data
{
private:
double num;
int type;
friend class Order;
};
Cmatrix(*function_1[100])(Cmatrix a);
Cmatrix(*function_2[100])(Cmatrix a, Cmatrix b);
//一元运算符
Cmatrix compute_1(Cmatrix a, Cmatrix(*func)(Cmatrix a)) { return func(a); }
Cmatrix Abs(Cmatrix a);
Cmatrix Lst(Cmatrix a);
Cmatrix matt(Cmatrix a);
Cmatrix inv(Cmatrix a);
Cmatrix Sch(Cmatrix a);
Cmatrix ilog(Cmatrix a);
Cmatrix iexp(Cmatrix a);
//二元运算符
Cmatrix compute_2(Cmatrix a, Cmatrix b, Cmatrix(*func)(Cmatrix a, Cmatrix b)) { return func(a, b); }
Cmatrix add(Cmatrix a, Cmatrix b);
Cmatrix sub(Cmatrix a, Cmatrix b);
Cmatrix mul(Cmatrix a, Cmatrix b);
Cmatrix div(Cmatrix a, Cmatrix b);
Cmatrix Sol(Cmatrix a, Cmatrix b);
void functioninput()
{
function_1[1] = Abs;
function_1[2] = Lst;
function_1[3] = matt;
function_1[4] = inv;
function_1[5] = Sch;
function_1[6] = ilog;
function_1[7] = iexp;
function_2[1] = add;
function_2[2] = sub;
function_2[3] = mul;
function_2[4] = div;
function_2[5] = Sol;
}
QuantityList var;
MatrixQuantityList matrixvar;
Cmatrix matx;
Cmatrix a;
Cmatrix b;
class Order
{
private:
Data* orders;
int size;
Dictionary hash;
public:
Order()
{
orders = new Data[1001];
size = 0;
}
~Order()
{
if (orders)
{
delete[] orders;
orders = 0;
}
}
void GetOrder()//初始指令读取&处理
{
char original[5000];
char c;
int n = 0;
//读取
while ((c = getchar()) != '\n')
{
//if (c == ' ') continue;
if (c >= 'A' && c <= 'Z') c = c - ('A' - 'a');
original[n] = c;
n++;
}
//从前向后处理
for (int i = 0;i < n;i++)
{
//括号判别
if (original[i] == '(')
{
orders[size].type = 0;
orders[size].num = 0;
size++;
}
else if (original[i] == ')')
{
orders[size].type = 0;
orders[size].num = 1;
size++;
}
else if (original[i] == '[')
{
orders[size].type = 0;
orders[size].num = 2;
size++;
}
else if (original[i] == ']')
{
orders[size].type = 0;
orders[size].num = 3;
size++;
}
else if (original[i] == '{')
{
orders[size].type = 0;
orders[size].num = 4;
size++;
}
else if (original[i] == '}')
{
orders[size].type = 0;
orders[size].num = 5;
size++;
}
//数字判别
else if (original[i] >= '0' && original[i] <= '9')
{
double x = 0;
while (true)
{
x = x * 10.0 + (original[i] - '0');
if (original[i + 1] < '0' || original[i + 1] > '9') break;
i++;
}
if (original[i + 1] == '.')//如果下一位是小数点
{
i += 2;//跳过小数点
double rate = 0.1;
while (true)
{
x += (original[i] - '0') * rate;
if (original[i + 1] < '0' || original[i + 1] > '9') break;
i++;
rate *= 0.1;
}
}
orders[size].type = 1;
orders[size].num = x;
size++;
}
//中缀表达式判别
else if (original[i] == '+')
{
orders[size].type = 2;
orders[size].num = 0;
size++;
}
else if (original[i] == '-')
{
orders[size].type = 2;
orders[size].num = 1;
size++;
}
else if (original[i] == '*')
{
orders[size].type = 2;
orders[size].num = 2;
size++;
}
else if (original[i] == '/')
{
orders[size].type = 2;
orders[size].num = 3;
size++;
}
//关键字判别
else if (original[i] >= 'a' && original[i] <= 'z')
{
double x = 0;
while (true)
{
x = x * 26 + (original[i] - 'a' + 1);
if (original[i + 1] < 'a' || original[i + 1] > 'z') break;
i++;
}
orders[size].type = 3;
orders[size].num = x;
size++;
}
//断字符判别
else if (original[i] == ',')
{
orders[size].type = 4;
orders[size].num = 0;
size++;
}
else if (original[i] == ';')
{
orders[size].type = 4;
orders[size].num = 1;
size++;
}
//等于号判别
else if (original[i] == '=')
{
orders[size].type = 5;
orders[size].num = 0;
size++;
}
else
{
orders[size].type = -1;
orders[size].num = 0;
size++;
}
}
//cout << "a" << endl;
}
void PrintOrder()
{
cout << "数据个数: " << size << endl << endl;
for (int i = 0;i < size;i++)
{
if (orders[i].type == 3 && orders[i].num < 0) cout << i + 1 << ": 类型-3 数据-错误" << endl;
else cout << i + 1 << ": 类型-" << orders[i].type << " 数据-" << orders[i].num << endl;
}
}
void AddOrder(int begin, int n)
{
for (int i = size - 1;i >= begin;i--)
{
orders[i].num = orders[i + n].num;
orders[i].type = orders[i + n].type;
}
size += n;
}
void DeleteOrder(int begin, int n)
{
for (int i = begin + n;i < size;i++)
{
orders[i - n].num = orders[i].num;
orders[i - n].type = orders[i].type;
}
size -= n;
}
void ReplaceOrder(int begin, int n, double x)
{
orders[begin].num = x;
orders[begin].type = 1;
for (int i = begin + n;i < size;i++)
{
orders[i - n + 1].num = orders[i].num;
orders[i - n + 1].type = orders[i].type;
}
size -= (n - 1);
}
void ReplaceMatrix(int begin, int n, double x)
{
orders[begin].num = x;
orders[begin].type = 7;
//cout << "a" << endl;
for (int i = begin + n;i < size;i++)
{
orders[i - n + 1].num = orders[i].num;
orders[i - n + 1].type = orders[i].type;
}
size -= (n - 1);
}
void Negative()//负号判别
{
for (int i = 1;i < size;i++)
{
if (orders[i].type == 2 && orders[i].num == 1 && (orders[i - 1].type == 2 || orders[i - 1].type == 4 || orders[i - 1].type == -1 ||
(orders[i - 1].type == 0 && (orders[i - 1].num == 0 || orders[i - 1].num == 2 || orders[i - 1].num == 4))))
{
ReplaceOrder(i, 2, (-orders[i + 1].num));
}
}
}
void TransWord()//针对单词转化为识别码
{
for (int i = 0;i < size;i++)
{
if (orders[i].type == 3)
{
orders[i].num = hash.Trans(orders[i].num);
}
}
}
double Grammar(int i)//关键词语法分析
{
functioninput();
double x;
Cmatrix matx;
int place = orders[i].num / 100;
int ordinal = (int)orders[i].num % 100;
//cout << place << endl;
//cout << ordinal << endl;
switch (place)
{
case 1:
matx = compute_1(matrixvar.GetMatrix(orders[i + 2].num), function_1[ordinal]);
x = matrixvar.AddMatrix(matx);
return x;
case 2:
matx = compute_2(matrixvar.GetMatrix(orders[i + 2].num), matrixvar.GetMatrix(orders[i + 4].num), function_2[ordinal]);
x = matrixvar.AddMatrix(matx);
return x;
default:
break;
}
}
void WordAnalyze()//关键词扫描合并
{
while (true)
{
//PrintOrder();
bool op = false;
int begin;
for (int i = 1;i < size;i++)
{
if (orders[i].type == 0 && orders[i].num == 2) begin = i;
else if (orders[i].type == 0 && orders[i].num == 3)
{
op = true;
ReplaceMatrix(begin - 1, i - begin + 2, Grammar(begin - 1));
break;
}
}
if (op == false) return;
}
}
void OperatorAnalyze()//中缀表达式扫描合并
{
while (true)
{
bool op = false;
for (int i = 1;i < size - 1;i++)
{
if (orders[i].type == 2 && orders[i].num == 2
&& orders[i - 1].type == 1 && orders[i + 1].type == 1)
{
ReplaceOrder(i - 1, 3, orders[i - 1].num * orders[i + 1].num);
op = true;
i--;
}
else if (orders[i].type == 2 && orders[i].num == 3
&& orders[i - 1].type == 1 && orders[i + 1].type == 1)
{
ReplaceOrder(i - 1, 3, orders[i - 1].num / orders[i + 1].num);
op = true;
i--;
}
}
for (int i = 1;i < size - 1;i++)
{
if (orders[i].type == 2 && orders[i].num == 0
&& orders[i - 1].type == 1 && orders[i + 1].type == 1)
{
ReplaceOrder(i - 1, 3, orders[i - 1].num + orders[i + 1].num);
op = true;
i--;
}
else if (orders[i].type == 2 && orders[i].num == 1
&& orders[i - 1].type == 1 && orders[i + 1].type == 1)
{
ReplaceOrder(i - 1, 3, orders[i - 1].num - orders[i + 1].num);
op = true;
i--;
}
}
for (int i = 1;i < size - 1;i++)
{
if (orders[i - 1].type == 0 && orders[i - 1].num == 0
&& orders[i].type == 1
&& orders[i + 1].type == 0 && orders[i + 1].num == 1)
{
ReplaceOrder(i - 1, 3, orders[i].num);
op = true;
i--;
}
}
if (op == false)break;
//PrintOrder();
}
}
void Assign()//变量替换
{
for (int i = 2;i < size;i++)
{
if (orders[i].type == 3)
{
if (i < size - 1 && orders[i + 1].type == 0 && orders[i + 1].num == 2) continue;
else
{
orders[i].type = 1;
orders[i].num = var.CheckQuantity(orders[i].num);
}
}
}
}
void MatrixAssign()//矩阵变量替换
{
for (int i = 2;i < size;i++)
{
if (orders[i].type == 3)
{
if (i < size - 1 && orders[i + 1].type == 0 && orders[i + 1].num == 2) continue;
else
{
orders[i].type = 7;
//cout << "a" << endl;
orders[i].num = matrixvar.CheckMatrix(orders[i].num);
}
}
}
for (int i = 2;i < size;i++)
{
if (orders[i].type == 4 && orders[i].num == 1)
{
for (int j = i - 1;j >= 2;j--)
{
if (orders[j].type == 0 && orders[j].num == 0)
{
Cmatrix mata;
for (int k = j + 1;k < size;k++)
{
if (orders[k].type == 1) mata.Adddata(orders[k].num);
else if (orders[k].type == 4 && orders[k].num == 1) mata.Change();
else if (orders[k].type == 0 && orders[k].num == 1)
{
ReplaceMatrix(j, k - j + 1, (double)matrixvar.AddMatrix(mata));
i = j;
break;
}
}
break;
}
}
}
}
int begin = 0;
for (int i = 1;i < size;i++)
{
if (orders[i].type == 0 && orders[i].num == 0) begin = i;
else if (orders[i].type == 0 && orders[i].num == 1)
{
bool bz = true;
for (int j = begin + 1;j < i;j++)
{
if (orders[j].type != 1 && orders[j].type != 4 && orders[j].type != -1)
{
bz = false;
break;
}
}
if (bz == true && orders[begin - 1].type != 3)
{
Cmatrix matz;
for (int j = begin + 1;j < i;j++)
{
if (orders[j].type == 1)
{
matz.Adddata(orders[j].num);
}
}
//cout << matz << endl;
ReplaceMatrix(begin, i - begin + 1, (double)matrixvar.AddMatrix(matz));
i = begin;
}
}
}
for (int i = 2;i < size;i++)
{
if (orders[i].type == 1)
{
Cmatrix matb;
matb.Adddata(orders[i].num);
orders[i].type = 7;
//cout << "a" << endl;
orders[i].num = (double)matrixvar.AddMatrix(matb);
}
}
//PrintOrder();
}
void MatrixOperatorAnalyze()//中缀表达式扫描合并
{
while (true)
{
bool op = false;
for (int i = 1;i < size - 1;i++)
{
if (orders[i].type == 2 && orders[i].num == 2
&& orders[i - 1].type == 7 && orders[i + 1].type == 7)
{
a = matrixvar.GetMatrix((int)orders[i - 1].num);
b = matrixvar.GetMatrix((int)orders[i + 1].num);
matx = a * b;
ReplaceMatrix(i - 1, 3, (double)matrixvar.AddMatrix(matx));
op = true;
i--;
}
else if (orders[i].type == 2 && orders[i].num == 3
&& orders[i - 1].type == 7 && orders[i + 1].type == 7)
{
a = matrixvar.GetMatrix((int)orders[i - 1].num);
b = matrixvar.GetMatrix((int)orders[i + 1].num);
matx = a / b;
ReplaceMatrix(i - 1, 3, (double)matrixvar.AddMatrix(matx));
op = true;
i--;
}
}
for (int i = 1;i < size - 1;i++)
{
if (orders[i].type == 2 && orders[i].num == 0
&& orders[i - 1].type == 7 && orders[i + 1].type == 7)
{
a = matrixvar.GetMatrix((int)orders[i - 1].num);
b = matrixvar.GetMatrix((int)orders[i + 1].num);
matx = a + b;
ReplaceMatrix(i - 1, 3, (double)matrixvar.AddMatrix(matx));
op = true;
i--;
}
else if (orders[i].type == 2 && orders[i].num == 1
&& orders[i - 1].type == 7 && orders[i + 1].type == 7)
{
a = matrixvar.GetMatrix((int)orders[i - 1].num);
b = matrixvar.GetMatrix((int)orders[i + 1].num);
matx = a - b;
ReplaceMatrix(i - 1, 3, (double)matrixvar.AddMatrix(matx));
op = true;
i--;
}
}
for (int i = 1;i < size - 1;i++)
{
if (orders[i - 1].type == 0 && orders[i - 1].num == 0
&& orders[i].type == 7
&& orders[i + 1].type == 0 && orders[i + 1].num == 1)
{
ReplaceMatrix(i - 1, 3, orders[i].num);
op = true;
i--;
}
}
if (op == false) break;
//PrintOrder();
}
}
void MatrixWordAnalyze()//关键词扫描合并
{
while (true)
{
//PrintOrder();
bool op = false;
int begin = 0;
for (int i = 1;i < size;i++)
{
if (orders[i].type == 0 && orders[i].num == 2) begin = i;
else if (orders[i].type == 0 && orders[i].num == 3)
{
op = true;
//cout << "a" << endl;
ReplaceMatrix(begin - 1, i - begin + 2, Grammar(begin - 1));
break;
}
}
if (op == false) return;
}
}
Cmatrix DefMatrix()
{
Cmatrix mata;
mata.matrixname = orders[2].num;
for (int i = 2;i < size;i++)
{
if (orders[i].type == 1) mata.Adddata(orders[i].num);
else if (orders[i].type == 4 && orders[i].num == 1) mata.Change();
}
return mata;
}
void Analyze()
{
int flag = 0;
while (true)
{
MatrixOperatorAnalyze();
cout << "a" << endl;
//PrintOrder();
MatrixWordAnalyze();
if (flag == 0)
{
//PrintOrder();
flag++;
}
if (orders[1].type == 0 && orders[1].num == 4
&& orders[2].type == 7
&& orders[3].type == 0 && orders[3].num == 5) break;
}
}
void out(int x)
{
char p;
if (x < 10)
{
cout << x;
}
else
{
p = 'A' + x - 10;
cout << p;
}
}
void Hex(int n, int x)
{
int ans[1000];
int i = 0;
int na = n;
while (na >= x)
{
i++;
ans[i] = na % x;
na = na / x;
}
cout << x << "进制转换结果为:";
out(na);
for (int q = i; q >= 1; q--)
{
out(ans[q]);
}
cout << endl << endl;
}
void Draw2D()
{
Point2DList a;
double begin = orders[4].num;
double end = orders[6].num;
double x = (end - begin) / 100.0;
cout << x << endl;
DeleteOrder(2, 6);
Data other[1000];
int othersize;
othersize = size;
for (int i = 0;i < size;i++)
{
other[i].num = orders[i].num;
other[i].type = orders[i].type;
}
for (double j = begin;j <= end;j += x)
{
for (int i = 1;i < size;i++)
{
if (orders[i].type == 3 && orders[i].num == 24)
{
orders[i].type = 1;
orders[i].num = j;
}
}
while (true)
{
OperatorAnalyze();
//PrintOrder();
WordAnalyze();
//PrintOrder();
if (orders[1].type == 0 && orders[1].num == 4
&& orders[2].type == 1
&& orders[3].type == 0 && orders[3].num == 5)
{
a.AddPoint2D(j, orders[2].num);
break;
}
}
size = othersize;
for (int i = 0;i < othersize;i++)
{
orders[i].num = other[i].num;
orders[i].type = other[i].type;
}
}
a.LimitPoint2D();
a.Print();
}
void SolveEquation(int n)
{
for (int i = 1;i < size - 1;i++)
{
if (orders[i].type == 2 && orders[i].num == 1)
{
if (orders[i + 1].type != 3) ReplaceOrder(i, 2, (-orders[i + 1].num));
else
{
for (int j = size - 1;j > i;j--)
{
orders[j + 1].num = orders[j].num;
orders[j + 1].type = orders[j].type;
}
size++;
orders[i].type = 2;
orders[i].num = 0;
orders[i + 1].type = 1;
orders[i + 1].num = -1;
}
}
else if (orders[i].type != 1 && orders[i + 1].type == 3)
{
for (int j = size - 1;j > i;j--)
{
orders[j + 1].num = orders[j].num;
orders[j + 1].type = orders[j].type;
}
size++;
orders[i + 1].type = 1;
orders[i + 1].num = 1;
}
}
//PrintOrder();
UnknownList b;
int line = 0;
double xs = 1.0;
for (int i = 2;i < size;i++)
{
if (orders[i].type == 3) b.Add(orders[i].num, line, xs * orders[i - 1].num);
else if (orders[i].type == 1 && orders[i + 1].type != 3) b.Add(0, line, (-xs) * orders[i].num);
else if (orders[i].type == 5) xs *= -1;
else if (orders[i].type == 4 && orders[i].num == 1)
{
line++;
xs = 1.0;
}
}
line++;
//b.Print();
//cout << endl;
int x = b.Getzero();
Cmatrix matb;
for (int j = 0;j < line;j++)
{
for (int i = 0;i < b.UnknownSize;i++)
{
if (i == x) continue;
matb.Adddata(b.Check(j, i));
}
matb.Adddata(b.Check(j, x));
if (j != line - 1) matb.Change();
}
cout << matb << endl;
}
void TotalFunc()//总功能分类
{
//cout << orders[0].num << endl;
if (orders[0].num == 2066)//"cal"
{
Negative();
MatrixAssign();
TransWord();
//matrixvar.PrintMatrix();
Analyze();
cout << "结果为:" << endl << matrixvar.GetMatrix((int)orders[2].num) << endl;
}
else if (orders[0].num == 2840)//"def"
{
Negative();
//PrintOrder();
Cmatrix x;
x = DefMatrix();
matrixvar.AddMatrix(x);
//matrixvar.PrintMatrix();
cout << endl;
}
else if (orders[0].num == 82521)//"draw"
{
Negative();
if (orders[2].type == 1 && orders[2].num == 2) Draw2D();
}
else if (orders[0].num == 5562)//"hex"
{
Hex(orders[2].num, orders[4].num);
}
else if (orders[0].num == 13246)//"sol"
{
SolveEquation(orders[2].num);
}
//cout << "b" << endl;
}
};
进制转换功能
就是几个常见进制如八进制、二进制、十进制、十六进制之间彼此的互相转换,感觉计算机的学生可能会用到这个功能:
void Hex(int n, int x)
{
int ans[1000];
int i = 0;
int na = n;
while (na >= x)
{
i++;
ans[i] = na % x;
na = na / x;
}
cout << x << "进制转换结果为:";
out(na);
for (int q = i; q >= 1; q--)
{
out(ans[q]);
}
cout << endl << endl;
}
二维及三维点的绘制
分别定义了一个二维和三维的类,用来存储多个坐标,然后Draw就行了,目前功能尚不确定(因为不是我写的:
class Point2D
{
private:
double x = 0;
double y = 0;
public:
void AddPoint(double x, double y)
{
this->x = x;
this->y = y;
}
friend class Point2DList;
friend class Order;
};
class Point2DList
{
private:
Point2D* list;
int Point2Dsize;
public:
Point2DList()
{
list = new Point2D[200];
Point2Dsize = 0;
}
~Point2DList()
{
if (list)
{
delete[] list;
list = 0;
}
}
void AddPoint2D(double x, double y)
{
list[Point2Dsize].AddPoint(x, y);
Point2Dsize++;
}
void LimitPoint2D()
{
double xmax = fabs(list[0].x), ymax = fabs(list[0].y);
for (int i = 1;i < Point2Dsize;i++)
{
if (fabs(list[i - 1].x) < fabs(list[i].x)) xmax = fabs(list[i].x);
if (fabs(list[i - 1].y) < fabs(list[i].y)) ymax = fabs(list[i].y);
}
double kx = 5 / xmax, ky = 4 / ymax;
for (int i = 0;i < Point2Dsize;i++)
{
list[i].x *= kx;
list[i].y *= ky;
}
}
void Print()
{
for (int i = 0;i < Point2Dsize;i++) cout << list[i].x << ' ' << list[i].y << endl;
}
};
Point2D的绘制函数:
void Draw2D()
{
Point2DList a;
double begin = orders[4].num;
double end = orders[6].num;
double x = (end - begin) / 100.0;
cout << x << endl;
DeleteOrder(2, 6);
Data other[1000];
int othersize;
othersize = size;
for (int i = 0;i < size;i++)
{
other[i].num = orders[i].num;
other[i].type = orders[i].type;
}
for (double j = begin;j <= end;j += x)
{
for (int i = 1;i < size;i++)
{
if (orders[i].type == 3 && orders[i].num == 24)
{
orders[i].type = 1;
orders[i].num = j;
}
}
while (true)
{
OperatorAnalyze();
//PrintOrder();
WordAnalyze();
//PrintOrder();
if (orders[1].type == 0 && orders[1].num == 4
&& orders[2].type == 1
&& orders[3].type == 0 && orders[3].num == 5)
{
a.AddPoint2D(j, orders[2].num);
break;
}
}
size = othersize;
for (int i = 0;i < othersize;i++)
{
orders[i].num = other[i].num;
orders[i].type = other[i].type;
}
}
a.LimitPoint2D();
a.Print();
}
部分功能展示
矩阵的加法:
矩阵的求逆和转置:
矩阵的化行最简式和求解方程组:
完整代码示例
下面是本次项目的完整代码:
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <cstring>
#include <ctime>
#include <Windows.h>
using namespace std;
int ifnotadd = 0;
int ifnotsub = 0;
int ifnotmul = 0;
int ifnotdiv = 0;
class Dictionary
{
private:
int* dic;//哈希表,支持五位长度的单词
public:
Dictionary()
{
dic = new int[100000000];
char path[] = "../hash.txt";
ifstream fin(path);
int i = 0;
while (!fin.eof())
{
char name[6];
int xname = 0;
int value = 0;
fin >> name;
fin >> value;
for (int i = 0;i < 6;i++)
{
if (name[i] >= 'a' && name[i] <= 'z')
{
xname = xname * 26 + (name[i] - 'a' + 1);
}
else if (name[i] >= 'A' && name[i] <= 'Z')
{
xname = xname * 26 + (name[i] - 'A' + 1);
}
else break;
}
dic[xname] = value;
/*cout << xname << ' ' << value << endl;*/
}
fin.close();
}
~Dictionary()
{
if (dic)
{
delete[] dic;
dic = 0;
}
}
int Trans(int word)
{
if (dic[word] < 0)return -1;
else return dic[word];
}
};
class Quantity
{
private:
int quaname;
double quanum;
friend class QuantityList;
};
class QuantityList
{
private:
Quantity* list;
int quantitysize;
public:
QuantityList()
{
list = new Quantity[1001];
quantitysize = 0;
}
~QuantityList()
{
if (list)
{
delete[] list;
list = 0;
}
}
void AddQuantity(int name, double num)
{
for (int i = 0;i < quantitysize;i++)
{
if (list[i].quaname == name)
{
list[i].quanum = num;
return;
}
}
list[quantitysize].quaname = name;
list[quantitysize].quanum = num;
quantitysize++;
}
void PrintQuantity()
{
cout << "共" << quantitysize << "个变量" << endl;
for (int i = 0;i < quantitysize;i++)
{
cout << "变量名: " << list[i].quaname << endl;
cout << "值: " << list[i].quanum << endl << endl;
}
}
double CheckQuantity(int name)
{
for (int i = 0;i < quantitysize;i++)
{
if (list[i].quaname == name)
{
return list[i].quanum;
}
}
return 0;
}
friend class Order;
};
class Cmatrix//from刘彦迪
{
private:
double matrixname;
double rat;
int row;
int col;
int rownow;
int colnow;
double** Matrix;
public:
Cmatrix()
{
row = col = colnow = rownow = 0;
rat = 1;
Matrix = new double* [1000];
for (int i = 0; i < 1000; i++)
Matrix[i] = new double[1000];
}
Cmatrix(int number)
{
row = col = number;
rat = 1;
Matrix = new double* [1000];
for (int i = 0; i < 1000; i++)
Matrix[i] = new double[1000];
for (int i = 0; i < row; i++)
for (int j = 0; j < col; j++)
{
Matrix[i][j] = 0;
}
for (int i = 0; i < number; i++)
{
Matrix[i][i] = 1;
}
}
double Getrat() { return this->rat; }
const int Getrow() const { return this->row; }
const int Getcol() const { return this->col; }
const double Getrat() const { return this->rat; }
void Setrow(int rownum) { this->row = rownum; }
void Setcol(int colnum) { this->col = colnum; }
void Setrat(double ratnum) { this->col = ratnum; }
const double Getname() const { return this->matrixname; }
const double Getmatrix(int row, int col) const { return this->Matrix[row][col]; }
double** Getmatrixi() { return this->Matrix; }
void Modify(int row, int col, double x) { this->Matrix[row][col] = x; }
void Adddata(double data)
{
if (row == 0)row++;
Matrix[rownow][colnow] = data;
colnow++;
col = colnow;
}
void Change()
{
row++;
rownow++;
colnow = 0;
}
Cmatrix Plus(Cmatrix another)
{
Cmatrix temp;
temp.row = this->row;
temp.col = this->col + another.col;
for (int i = 0; i < this->row; i++)
for (int j = 0; j < this->col; j++)
{
temp.Matrix[i][j] = this->Matrix[i][j];
}
int start = this->col;
for (int i = 0; i < this->row; i++)
for (int j = start; j < temp.col; j++)
{
temp.Matrix[i][j] = another.Matrix[i][j - start];
}
return temp;
}
Cmatrix inv()
{
if (this->det() == 0 || this->row != this->col)
{
cout << "无逆矩阵!" << endl;
return *this;
}
Cmatrix tempo(this->row);
Cmatrix tempo2 = this->Plus(tempo);
Cmatrix tempo3 = tempo2.Lst();
Cmatrix tempo4;
tempo4.row = this->row; tempo4.col = this->col;
for (int i = 0; i < tempo4.row; i++)
for (int j = 0; j < tempo4.col; j++)
{
tempo4.Matrix[i][j] = tempo3.Matrix[i][j + this->col];
}
return tempo4;
}
Cmatrix& operator=(const Cmatrix& m)
{
this->matrixname = m.Getname();
this->row = m.Getrow();
this->col = m.Getcol();
rownow = 0;
colnow = 0;
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
this->Matrix[i][j] = m.Matrix[i][j];
}
}
return *this;
}
Cmatrix operator +(Cmatrix& another)
{
if ((this->row != another.row) || (this->col != another.col))
{
cout << "无法进行相加" << endl;
ifnotadd = 1;
return *this;
}
Cmatrix tempo;
tempo.row = row;
tempo.col = col;
for (int i = 0; i < row; i++)
for (int j = 0; j < col; j++)
tempo.Matrix[i][j] = this->Matrix[i][j] + another.Matrix[i][j];
return tempo;
}
Cmatrix operator -(Cmatrix& another)
{
if ((this->row != another.row) || (this->col != another.col))
{
cout << "无法进行相减" << endl;
ifnotsub = 1;
return *this;
}
Cmatrix tempo;
tempo.row = row;
tempo.col = col;
for (int i = 0; i < row; i++)
for (int j = 0; j < col; j++)
tempo.Matrix[i][j] = this->Matrix[i][j] - another.Matrix[i][j];
return tempo;
}
Cmatrix operator *(Cmatrix& another)
{
if (this->col != another.row)
{
cout << "无法进行相乘" << endl;
ifnotmul = 1;
return *this;
}
Cmatrix tempo;
tempo.row = this->row;
tempo.col = another.col;
for (int i = 0; i < tempo.row; i++)
for (int j = 0; j < tempo.col; j++)
{
double numbernow = 0;
for (int p = 0; p < this->col; p++)
numbernow += this->Matrix[i][p] * another.Matrix[p][j];
tempo.Matrix[i][j] = numbernow;
}
return tempo;
}
Cmatrix operator /(Cmatrix& another)
{
if (another.det() == 0)
{
cout << "无法进行相除" << endl;
ifnotdiv = 1;
return *this;
}
Cmatrix tempo = another.inv();
Cmatrix tempo2 = (*this) * tempo;
return tempo2;
}
void Swap(int row1, int col1, int row2, int col2)
{
double tempo;
tempo = Matrix[row1 - 1][col1 - 1];
Matrix[row1 - 1][col1 - 1] = Matrix[row2 - 1][col2 - 1];
Matrix[row2 - 1][col2 - 1] = tempo;
}
void Multi(int rownum, double ratio)
{
if (rownum <= 0 || rownum > row) throw"发现错误,所在行数超出范围!";
for (int i = 0; i < col; i++)
{
if (Matrix[rownum - 1][i] != 0)
Matrix[rownum - 1][i] *= ratio;
}
rat /= ratio;
}
Cmatrix ilog()
{
if (this->row != 1 && this->col != 1)
{
cout << "没法采用log计算" << endl;
return *this;
}
Cmatrix tempo;
tempo.row = 1; tempo.col = 1;
tempo.Matrix[0][0] = log(this->Matrix[0][0]);
return tempo;
}
Cmatrix iexp()
{
if (this->row != 1 && this->col != 1)
{
cout << "没法采用exp计算" << endl;
return *this;
}
Cmatrix tempo;
tempo.row = 1; tempo.col = 1;
tempo.Matrix[0][0] = exp(this->Matrix[0][0]);
return tempo;
}
Cmatrix matt()
{
Cmatrix tempo;
tempo.row = this->col;
tempo.col = this->row;
for (int i = 0; i < tempo.row; i++)
{
for (int j = 0; j < tempo.col; j++)
{
tempo.Matrix[i][j] = this->Matrix[j][i];
}
}
return tempo;
}
void Simplify()
{
for (int i = 0; i < this->row; i++)
for (int j = 0; j < this->col; j++)
{
if (abs(this->Matrix[i][j]) < 0.0001)
{
this->Matrix[i][j] = 0;
}
}
for (int i = 0; i < this->row; i++)
{
if (!Checkzero(i + 1)) continue;
else
{
int p = i + 1;
for (; p < this->row; p++)
{
if (!Checkzero(p + 1))
{
for (int j = 0; j < this->col; j++)
Swap(i + 1, j + 1, p + 1, j + 1);
break;
}
}
if (p == this->row) break;
}
}
}
bool Checkzero(int rownum)
{
for (int i = 0; i < col; i++)
{
if (Matrix[rownum - 1][i] != 0)
return false;
}
return true;
}
Cmatrix Sol(Cmatrix answ)
{
int n = 0;
Cmatrix tempo5 = this->Plus(answ);
if (this->row != answ.row)
{
return *this;
}
if (this->ranks() != tempo5.ranks())
{
n = 1;
}
else
{
n = 2;
}
Cmatrix tempo;
if (n == 1) tempo = this->Plus(answ);
if (n == 2)
{
Cmatrix thisT = this->matt() * (*this);
Cmatrix answ2 = this->matt() * answ;
tempo = thisT.Plus(answ2);
}
Cmatrix tempo2 = tempo.Lst();
Cmatrix tempo3 = tempo2;
int freedom = this->col - this->ranks();
cout << "自由变量有" << freedom << "个" << endl;
tempo3.Simplify();
cout << "tempo3为:" << endl;
for (int i = 0; i < tempo3.row; i++)
{
for (int j = 0; j < tempo3.col; j++)
{
cout << tempo3.Matrix[i][j] << " ";
}
cout << endl;
}
cout << endl;
int* trueorfalse; trueorfalse = new int[this->col];
for (int i = 0; i < this->col; i++)
trueorfalse[i] = 0;
for (int i = 0; i < this->row; i++)
{
int seed = 0;
for (int j = 0; j < tempo3.ranks(); j++)
{
if (tempo3.Matrix[i][j] == 0) seed++;
else
{
if (trueorfalse[seed] == 0)
{
trueorfalse[seed] = 1;
}
}
}
}
int* freedomnum = new int[freedom];
int record = 0;
for (int i = 0; i < this->col; i++)
{
if (trueorfalse[i] == 0)
{
freedomnum[record] = i; record++;
}
}
Cmatrix answer; answer.row = this->col; answer.col = 1;
for (int i = 0; i < answer.row; i++)
{
if (trueorfalse[i] == 1)
answer.Matrix[i][0] = tempo3.Matrix[i][tempo3.col - 1];
else
answer.Matrix[i][0] = 0;
}
Cmatrix answer2; answer2.row = this->col; answer2.col = freedom;
int j = 0;
for (; j < answer2.col; j++)
{
for (int i = 0; i < answer2.row; i++)
{
if (i != freedomnum[j] && tempo3.Matrix[i][freedomnum[j]] != 0)
answer2.Matrix[i][j] = -tempo3.Matrix[i][freedomnum[j]];
else if (i != freedomnum[j] && tempo3.Matrix[i][freedomnum[j]] == 0)
answer2.Matrix[i][j] = 0;
else
answer2.Matrix[i][j] = 1;
}
}
Cmatrix total = answer.Plus(answer2);
return total;
}
Cmatrix Lst()//化行最简式
{
Cmatrix tempo;
tempo.row = this->row;
tempo.col = this->col;
for (int i = 0; i < tempo.row; i++)
{
for (int j = 0; j < tempo.col; j++)
tempo.Matrix[i][j] = this->Matrix[i][j];
}
double ratio = 0;
f:for (int i = 0; i < tempo.row; i++)
{
for (int j = 0; j < i; j++)
{
if (tempo.Matrix[j][j] == 0 && j != tempo.row - 2)
{
for (int p = i + 1; p < tempo.row; p++)
{
if (tempo.Matrix[p][j] != 0)
{
for (int y = 0; y < tempo.col; y++)
{
tempo.Swap(j + 1, y + 1, p + 1, y + 1);
}
break;
}
}
goto f;
}
if (tempo.Matrix[j][j] == 0 && tempo.Matrix[i][j] != 0 && j == tempo.row - 2)
{
for (int y = 0; y < tempo.col; y++)
{
tempo.Swap(j + 1, y + 1, tempo.row, y + 1);
}
}
if (tempo.Matrix[j][j] == 0 && tempo.Matrix[i][j] == 0 && j == tempo.row - 2)
{
int seed = j + 1;
while (tempo.Matrix[j][seed] == 0 && seed < tempo.col)
{
seed++;
}
if (seed == tempo.col)
{
for (int i = 0; i < tempo.row; i++)
{
if (tempo.Checkzero(i + 1)) continue;
for (int j = 0; j < tempo.col; j++)
{
if (tempo.Matrix[i][j] != 0)
{
tempo.Multi(i + 1, 1 / tempo.Matrix[i][j]); break;
}
}
}
goto g;
}
ratio = tempo.Matrix[i][seed] / tempo.Matrix[j][seed];
for (int start = seed; start < tempo.col; start++)
{
tempo.Matrix[i][start] -= ratio * tempo.Matrix[j][start];
}
break;
}
ratio = tempo.Matrix[i][j] / tempo.Matrix[j][j];
for (int start = j; start < tempo.col; start++)
tempo.Matrix[i][start] -= ratio * tempo.Matrix[j][start];
}
}
tempo.Simplify();
for (int i = 0; i < tempo.row; i++)
{
if (tempo.Checkzero(i + 1)) continue;
for (int j = 0; j < tempo.col; j++)
{
if (tempo.Matrix[i][j] != 0)
{
tempo.Multi(i + 1, 1 / tempo.Matrix[i][j]); break;
}
}
}
tempo.Simplify();
g:int rank = 0;
for (int i = 0; i < row; i++)
{
if (!tempo.Checkzero(i + 1)) rank++;
else break;
}
for (int i = 1; i < rank; i++)
{
int seed = 0;
for (int j = 0; j < tempo.col; j++)
{
if (tempo.Matrix[rank - i][j] == 0) seed++;
else
{
break;
}
}
for (int p = 0; p < rank - i; p++)
{
ratio = tempo.Matrix[p][seed];
for (int y = seed; y < tempo.col; y++)
{
tempo.Matrix[p][y] -= ratio * tempo.Matrix[rank - i][y];
}
}
}
tempo.Simplify();
this->rat = tempo.rat;
return tempo;
}
Cmatrix Sch()
{
for (int j = 0; j < this->col; j++)
{
if (Checkzero2(j + 1))
{
cout << "这个矩阵不能施密特正交化" << endl;
return *this;
}
}
Cmatrix tem = *this;
for (int j = 1; j < tem.col; j++)
{
Cmatrix reserve = tem.vectorn(j + 1);
for (int p = 0; p < j; p++)
{
Cmatrix tempo = tem.vectorn(p + 1);
double ratio = -reserve.inpro(tempo) / tempo.inpro(tempo);
tem.Swap_add(j + 1, p + 1, ratio);
}
}
return tem;
}
void Swap_add(int colnum1, int colnum2, double ratio)
//colnum1为实际操作列,colnum2为标准列,ratio为比例
{
for (int i = 0; i < this->row; i++)
this->Matrix[i][colnum1 - 1] += this->Matrix[i][colnum2 - 1] * ratio;
}
Cmatrix vectorn(int colnum)
{
if (colnum <= 0 || colnum > this->col)
{
cout << "输入列数超出范围!" << endl;
return *this;
}
Cmatrix tempo; tempo.row = this->row; tempo.col = 1;
for (int i = 0; i < tempo.row; i++)
{
tempo.Matrix[i][0] = this->Matrix[i][colnum - 1];
}
return tempo;
}
bool Checkzero2(int colnum)//检查某一列元素是否全为0,是则返回true,不是返回false
{
if (colnum <= 0 || colnum > this->col)
{
cout << "所检查的列数超出矩阵范围" << endl;
return false;
}
for (int i = 0; i < row; i++)
{
if (Matrix[row][colnum] != 0)
return false;
}
return true;
}
double inpro(Cmatrix another)
{
if ((this->col != 1 || another.col != 1) || (this->row != another.row))
{
cout << "这两个至少有一个不是n维向量或两个向量所含元素个数不同" << endl;
return 0;
}
double totalnum = 0;
for (int i = 0; i < this->row; i++)
{
totalnum += this->Matrix[i][0] * another.Matrix[i][0];
}
return totalnum;
}
double det()
{
if (this->row != this->col) std::abort();
if (this->ranks() < this->row) return 0;
Cmatrix temp = this->Lst();
double det = this->rat;
for (int i = 0; i < temp.col; i++)
det *= temp.Matrix[i][i];
return det;
}
int ranks()
{
Cmatrix a; a.row = this->row; a.col = this->col;
for (int i = 0; i < a.row; i++)
for (int j = 0; j < a.col; j++)
a.Matrix[i][j] = this->Matrix[i][j];
Cmatrix b = a.Lst();
int rank = 0;
for (int i = 0; i < row; i++)
{
if (!b.Checkzero(i + 1)) rank++;
else break;
}
return rank;
}
friend class MatrixQuantityList;
friend class Order;
friend ostream& operator <<(ostream& o, const Cmatrix& one)
{
//cout << "矩阵名: " << one.matrixname << endl;
//cout << one.Getrow() <<' '<< one.Getcol() << endl;
for (int i = 0; i < one.Getrow(); i++)
{
for (int j = 0; j < one.Getcol(); j++)
o << one.Getmatrix(i, j) << " ";
o << endl;
}
return o;
}
};
class MatrixQuantityList
{
private:
Cmatrix* matrixlist;
int matrixsize;
public:
MatrixQuantityList()
{
matrixlist = new Cmatrix[100];
matrixsize = 0;
}
~MatrixQuantityList()
{
if (matrixlist)
{
delete[] matrixlist;
matrixlist = 0;
}
}
int GetMatrixQuantityListSize() { return matrixsize; }
Cmatrix GetMatrix(int i) { return matrixlist[i]; }
int AddMatrix(Cmatrix& other)
{
for (int i = 0;i < matrixsize;i++)
{
if (matrixlist[i].matrixname == other.matrixname && matrixlist[i].matrixname != 0)
{
matrixlist[i] = other;
return i;
}
}
matrixlist[matrixsize] = other;
matrixsize++;
return matrixsize - 1;
}
int CheckMatrix(double x)
{
for (int i = 0;i < matrixsize;i++)
{
if (matrixlist[i].matrixname == x)
{
return i;
}
}
return 0;
}
void PrintMatrix()
{
cout << "共" << matrixsize << "个矩阵" << endl;
for (int i = 0;i < matrixsize;i++)
{
cout << matrixlist[i] << endl;
}
}
friend class Order;
};
class Point2D
{
private:
double x = 0;
double y = 0;
public:
void AddPoint(double x, double y)
{
this->x = x;
this->y = y;
}
friend class Point2DList;
friend class Order;
};
class Point2DList
{
private:
Point2D* list;
int Point2Dsize;
public:
Point2DList()
{
list = new Point2D[200];
Point2Dsize = 0;
}
~Point2DList()
{
if (list)
{
delete[] list;
list = 0;
}
}
void AddPoint2D(double x, double y)
{
list[Point2Dsize].AddPoint(x, y);
Point2Dsize++;
}
void LimitPoint2D()
{
double xmax = fabs(list[0].x), ymax = fabs(list[0].y);
for (int i = 1;i < Point2Dsize;i++)
{
if (fabs(list[i - 1].x) < fabs(list[i].x)) xmax = fabs(list[i].x);
if (fabs(list[i - 1].y) < fabs(list[i].y)) ymax = fabs(list[i].y);
}
double kx = 5 / xmax, ky = 4 / ymax;
for (int i = 0;i < Point2Dsize;i++)
{
list[i].x *= kx;
list[i].y *= ky;
}
}
void Print()
{
for (int i = 0;i < Point2Dsize;i++) cout << list[i].x << ' ' << list[i].y << endl;
}
};
class UnknownNum
{
private:
double name = 0;
int line = 0;
int col = 0;
double value = 0;
friend class UnknownList;
};
class UnknownList
{
private:
UnknownNum list[20];
int size = 0;
int UnknownSize = 0;
public:
void Add(double text, int linenum, double num)
{
bool bz = false;
for (int i = 0;i < size;i++)
{
if (list[i].name == text)
{
if (list[i].line == linenum)
{
list[i].value += num;
return;
}
else
{
bz = true;
list[size].col = list[i].col;
}
}
}
if (bz == false)
{
list[size].col = UnknownSize;
UnknownSize++;
}
list[size].name = text;
list[size].line = linenum;
list[size].value = num;
size++;
}
void Print()
{
cout << "共" << size << "个 有" << UnknownSize-1 << "个未知数" << endl;
for (int i = 0;i < size;i++)
{
cout << list[i].name << ' ' << list[i].line << ' ' << list[i].col << ' ' << list[i].value << endl;
}
}
int Getzero()
{
for (int i = 0;i < size;i++)
{
if (list[i].name == 0) return list[i].col;
}
}
double Check(int line, int col)
{
for (int i = 0;i < size;i++)
{
if (list[i].line == line && list[i].col == col ) return list[i].value;
}
return 0.0;
}
friend class Order;
};
//定义一个double型二维数组,第一位存储数据类型,第二位存储值
//数据类型:括号-0;数字-1;中缀运算符-2;关键字-3;断字符-4;等于号-5;变量-6;矩阵-7
//括号:小左-0;小右-1;中左-2;中右-3;大左-4;大右-5
//中缀:加-0;减-1;乘-2;除-3
//断字符:逗号-0;分号-1;
class Data
{
private:
double num;
int type;
friend class Order;
};
Cmatrix(*function_1[100])(Cmatrix a);
Cmatrix(*function_2[100])(Cmatrix a, Cmatrix b);
//一元运算符
Cmatrix compute_1(Cmatrix a, Cmatrix(*func)(Cmatrix a)) { return func(a); }
Cmatrix Abs(Cmatrix a);
Cmatrix Lst(Cmatrix a);
Cmatrix matt(Cmatrix a);
Cmatrix inv(Cmatrix a);
Cmatrix Sch(Cmatrix a);
Cmatrix ilog(Cmatrix a);
Cmatrix iexp(Cmatrix a);
//二元运算符
Cmatrix compute_2(Cmatrix a, Cmatrix b, Cmatrix(*func)(Cmatrix a, Cmatrix b)) { return func(a, b); }
Cmatrix add(Cmatrix a, Cmatrix b);
Cmatrix sub(Cmatrix a, Cmatrix b);
Cmatrix mul(Cmatrix a, Cmatrix b);
Cmatrix div(Cmatrix a, Cmatrix b);
Cmatrix Sol(Cmatrix a, Cmatrix b);
void functioninput()
{
function_1[1] = Abs;
function_1[2] = Lst;
function_1[3] = matt;
function_1[4] = inv;
function_1[5] = Sch;
function_1[6] = ilog;
function_1[7] = iexp;
function_2[1] = add;
function_2[2] = sub;
function_2[3] = mul;
function_2[4] = div;
function_2[5] = Sol;
}
QuantityList var;
MatrixQuantityList matrixvar;
Cmatrix matx;
Cmatrix a;
Cmatrix b;
class Order
{
private:
Data* orders;
int size;
Dictionary hash;
public:
Order()
{
orders = new Data[1001];
size = 0;
}
~Order()
{
if (orders)
{
delete[] orders;
orders = 0;
}
}
void GetOrder()//初始指令读取&处理
{
char original[5000];
char c;
int n = 0;
//读取
while ((c = getchar()) != '\n')
{
//if (c == ' ') continue;
if (c >= 'A' && c <= 'Z') c = c - ('A' - 'a');
original[n] = c;
n++;
}
//从前向后处理
for (int i = 0;i < n;i++)
{
//括号判别
if (original[i] == '(')
{
orders[size].type = 0;
orders[size].num = 0;
size++;
}
else if (original[i] == ')')
{
orders[size].type = 0;
orders[size].num = 1;
size++;
}
else if (original[i] == '[')
{
orders[size].type = 0;
orders[size].num = 2;
size++;
}
else if (original[i] == ']')
{
orders[size].type = 0;
orders[size].num = 3;
size++;
}
else if (original[i] == '{')
{
orders[size].type = 0;
orders[size].num = 4;
size++;
}
else if (original[i] == '}')
{
orders[size].type = 0;
orders[size].num = 5;
size++;
}
//数字判别
else if (original[i] >= '0' && original[i] <= '9')
{
double x = 0;
while (true)
{
x = x * 10.0 + (original[i] - '0');
if (original[i + 1] < '0' || original[i + 1] > '9') break;
i++;
}
if (original[i + 1] == '.')//如果下一位是小数点
{
i += 2;//跳过小数点
double rate = 0.1;
while (true)
{
x += (original[i] - '0') * rate;
if (original[i + 1] < '0' || original[i + 1] > '9') break;
i++;
rate *= 0.1;
}
}
orders[size].type = 1;
orders[size].num = x;
size++;
}
//中缀表达式判别
else if (original[i] == '+')
{
orders[size].type = 2;
orders[size].num = 0;
size++;
}
else if (original[i] == '-')
{
orders[size].type = 2;
orders[size].num = 1;
size++;
}
else if (original[i] == '*')
{
orders[size].type = 2;
orders[size].num = 2;
size++;
}
else if (original[i] == '/')
{
orders[size].type = 2;
orders[size].num = 3;
size++;
}
//关键字判别
else if (original[i] >= 'a' && original[i] <= 'z')
{
double x = 0;
while (true)
{
x = x * 26 + (original[i] - 'a' + 1);
if (original[i + 1] < 'a' || original[i + 1] > 'z') break;
i++;
}
orders[size].type = 3;
orders[size].num = x;
size++;
}
//断字符判别
else if (original[i] == ',')
{
orders[size].type = 4;
orders[size].num = 0;
size++;
}
else if (original[i] == ';')
{
orders[size].type = 4;
orders[size].num = 1;
size++;
}
//等于号判别
else if (original[i] == '=')
{
orders[size].type = 5;
orders[size].num = 0;
size++;
}
else
{
orders[size].type = -1;
orders[size].num = 0;
size++;
}
}
//cout << "a" << endl;
}
void PrintOrder()
{
cout << "数据个数: " << size << endl << endl;
for (int i = 0;i < size;i++)
{
if (orders[i].type == 3 && orders[i].num < 0) cout << i + 1 << ": 类型-3 数据-错误" << endl;
else cout << i + 1 << ": 类型-" << orders[i].type << " 数据-" << orders[i].num << endl;
}
}
void AddOrder(int begin, int n)
{
for (int i = size - 1;i >= begin;i--)
{
orders[i].num = orders[i + n].num;
orders[i].type = orders[i + n].type;
}
size += n;
}
void DeleteOrder(int begin, int n)
{
for (int i = begin + n;i < size;i++)
{
orders[i - n].num = orders[i].num;
orders[i - n].type = orders[i].type;
}
size -= n;
}
void ReplaceOrder(int begin, int n, double x)
{
orders[begin].num = x;
orders[begin].type = 1;
for (int i = begin + n;i < size;i++)
{
orders[i - n + 1].num = orders[i].num;
orders[i - n + 1].type = orders[i].type;
}
size -= (n - 1);
}
void ReplaceMatrix(int begin, int n, double x)
{
orders[begin].num = x;
orders[begin].type = 7;
//cout << "a" << endl;
for (int i = begin + n;i < size;i++)
{
orders[i - n + 1].num = orders[i].num;
orders[i - n + 1].type = orders[i].type;
}
size -= (n - 1);
}
void Negative()//负号判别
{
for (int i = 1;i < size;i++)
{
if (orders[i].type == 2 && orders[i].num == 1 && (orders[i - 1].type == 2 || orders[i - 1].type == 4 || orders[i - 1].type == -1 ||
(orders[i - 1].type == 0 && (orders[i - 1].num == 0 || orders[i - 1].num == 2 || orders[i - 1].num == 4))))
{
ReplaceOrder(i, 2, (-orders[i + 1].num));
}
}
}
void TransWord()//针对单词转化为识别码
{
for (int i = 0;i < size;i++)
{
if (orders[i].type == 3)
{
orders[i].num = hash.Trans(orders[i].num);
}
}
}
double Grammar(int i)//关键词语法分析
{
functioninput();
double x;
Cmatrix matx;
int place = orders[i].num / 100;
int ordinal = (int)orders[i].num % 100;
//cout << place << endl;
//cout << ordinal << endl;
switch (place)
{
case 1:
matx = compute_1(matrixvar.GetMatrix(orders[i + 2].num), function_1[ordinal]);
x = matrixvar.AddMatrix(matx);
return x;
case 2:
matx = compute_2(matrixvar.GetMatrix(orders[i + 2].num), matrixvar.GetMatrix(orders[i + 4].num), function_2[ordinal]);
x = matrixvar.AddMatrix(matx);
return x;
default:
break;
}
}
void WordAnalyze()//关键词扫描合并
{
while (true)
{
//PrintOrder();
bool op = false;
int begin;
for (int i = 1;i < size;i++)
{
if (orders[i].type == 0 && orders[i].num == 2) begin = i;
else if (orders[i].type == 0 && orders[i].num == 3)
{
op = true;
ReplaceMatrix(begin - 1, i - begin + 2, Grammar(begin - 1));
break;
}
}
if (op == false) return;
}
}
void OperatorAnalyze()//中缀表达式扫描合并
{
while (true)
{
bool op = false;
for (int i = 1;i < size - 1;i++)
{
if (orders[i].type == 2 && orders[i].num == 2
&& orders[i - 1].type == 1 && orders[i + 1].type == 1)
{
ReplaceOrder(i - 1, 3, orders[i - 1].num * orders[i + 1].num);
op = true;
i--;
}
else if (orders[i].type == 2 && orders[i].num == 3
&& orders[i - 1].type == 1 && orders[i + 1].type == 1)
{
ReplaceOrder(i - 1, 3, orders[i - 1].num / orders[i + 1].num);
op = true;
i--;
}
}
for (int i = 1;i < size - 1;i++)
{
if (orders[i].type == 2 && orders[i].num == 0
&& orders[i - 1].type == 1 && orders[i + 1].type == 1)
{
ReplaceOrder(i - 1, 3, orders[i - 1].num + orders[i + 1].num);
op = true;
i--;
}
else if (orders[i].type == 2 && orders[i].num == 1
&& orders[i - 1].type == 1 && orders[i + 1].type == 1)
{
ReplaceOrder(i - 1, 3, orders[i - 1].num - orders[i + 1].num);
op = true;
i--;
}
}
for (int i = 1;i < size - 1;i++)
{
if (orders[i - 1].type == 0 && orders[i - 1].num == 0
&& orders[i].type == 1
&& orders[i + 1].type == 0 && orders[i + 1].num == 1)
{
ReplaceOrder(i - 1, 3, orders[i].num);
op = true;
i--;
}
}
if (op == false)break;
//PrintOrder();
}
}
void Assign()//变量替换
{
for (int i = 2;i < size;i++)
{
if (orders[i].type == 3)
{
if (i < size - 1 && orders[i + 1].type == 0 && orders[i + 1].num == 2) continue;
else
{
orders[i].type = 1;
orders[i].num = var.CheckQuantity(orders[i].num);
}
}
}
}
void MatrixAssign()//矩阵变量替换
{
for (int i = 2;i < size;i++)
{
if (orders[i].type == 3)
{
if (i < size - 1 && orders[i + 1].type == 0 && orders[i + 1].num == 2) continue;
else
{
orders[i].type = 7;
//cout << "a" << endl;
orders[i].num = matrixvar.CheckMatrix(orders[i].num);
}
}
}
for (int i = 2;i < size;i++)
{
if (orders[i].type == 4 && orders[i].num == 1)
{
for (int j = i - 1;j >= 2;j--)
{
if (orders[j].type == 0 && orders[j].num == 0)
{
Cmatrix mata;
for (int k = j + 1;k < size;k++)
{
if (orders[k].type == 1) mata.Adddata(orders[k].num);
else if (orders[k].type == 4 && orders[k].num == 1) mata.Change();
else if (orders[k].type == 0 && orders[k].num == 1)
{
ReplaceMatrix(j, k - j + 1, (double)matrixvar.AddMatrix(mata));
i = j;
break;
}
}
break;
}
}
}
}
int begin = 0;
for (int i = 1;i < size;i++)
{
if (orders[i].type == 0 && orders[i].num == 0) begin = i;
else if (orders[i].type == 0 && orders[i].num == 1)
{
bool bz = true;
for (int j = begin + 1;j < i;j++)
{
if (orders[j].type != 1 && orders[j].type != 4 && orders[j].type != -1)
{
bz = false;
break;
}
}
if (bz == true && orders[begin - 1].type != 3)
{
Cmatrix matz;
for (int j = begin + 1;j < i;j++)
{
if (orders[j].type == 1)
{
matz.Adddata(orders[j].num);
}
}
//cout << matz << endl;
ReplaceMatrix(begin, i - begin + 1, (double)matrixvar.AddMatrix(matz));
i = begin;
}
}
}
for (int i = 2;i < size;i++)
{
if (orders[i].type == 1)
{
Cmatrix matb;
matb.Adddata(orders[i].num);
orders[i].type = 7;
//cout << "a" << endl;
orders[i].num = (double)matrixvar.AddMatrix(matb);
}
}
//PrintOrder();
}
void MatrixOperatorAnalyze()//中缀表达式扫描合并
{
while (true)
{
bool op = false;
for (int i = 1;i < size - 1;i++)
{
if (orders[i].type == 2 && orders[i].num == 2
&& orders[i - 1].type == 7 && orders[i + 1].type == 7)
{
a = matrixvar.GetMatrix((int)orders[i - 1].num);
b = matrixvar.GetMatrix((int)orders[i + 1].num);
matx = a * b;
ReplaceMatrix(i - 1, 3, (double)matrixvar.AddMatrix(matx));
op = true;
i--;
}
else if (orders[i].type == 2 && orders[i].num == 3
&& orders[i - 1].type == 7 && orders[i + 1].type == 7)
{
a = matrixvar.GetMatrix((int)orders[i - 1].num);
b = matrixvar.GetMatrix((int)orders[i + 1].num);
matx = a / b;
ReplaceMatrix(i - 1, 3, (double)matrixvar.AddMatrix(matx));
op = true;
i--;
}
}
for (int i = 1;i < size - 1;i++)
{
if (orders[i].type == 2 && orders[i].num == 0
&& orders[i - 1].type == 7 && orders[i + 1].type == 7)
{
a = matrixvar.GetMatrix((int)orders[i - 1].num);
b = matrixvar.GetMatrix((int)orders[i + 1].num);
matx = a + b;
ReplaceMatrix(i - 1, 3, (double)matrixvar.AddMatrix(matx));
op = true;
i--;
}
else if (orders[i].type == 2 && orders[i].num == 1
&& orders[i - 1].type == 7 && orders[i + 1].type == 7)
{
a = matrixvar.GetMatrix((int)orders[i - 1].num);
b = matrixvar.GetMatrix((int)orders[i + 1].num);
matx = a - b;
ReplaceMatrix(i - 1, 3, (double)matrixvar.AddMatrix(matx));
op = true;
i--;
}
}
for (int i = 1;i < size - 1;i++)
{
if (orders[i - 1].type == 0 && orders[i - 1].num == 0
&& orders[i].type == 7
&& orders[i + 1].type == 0 && orders[i + 1].num == 1)
{
ReplaceMatrix(i - 1, 3, orders[i].num);
op = true;
i--;
}
}
if (op == false) break;
//PrintOrder();
}
}
void MatrixWordAnalyze()//关键词扫描合并
{
while (true)
{
//PrintOrder();
bool op = false;
int begin = 0;
for (int i = 1;i < size;i++)
{
if (orders[i].type == 0 && orders[i].num == 2) begin = i;
else if (orders[i].type == 0 && orders[i].num == 3)
{
op = true;
//cout << "a" << endl;
ReplaceMatrix(begin - 1, i - begin + 2, Grammar(begin - 1));
break;
}
}
if (op == false) return;
}
}
Cmatrix DefMatrix()
{
Cmatrix mata;
mata.matrixname = orders[2].num;
for (int i = 2;i < size;i++)
{
if (orders[i].type == 1) mata.Adddata(orders[i].num);
else if (orders[i].type == 4 && orders[i].num == 1) mata.Change();
}
return mata;
}
void Analyze()
{
int flag = 0;
while (true)
{
MatrixOperatorAnalyze();
cout << "a" << endl;
//PrintOrder();
MatrixWordAnalyze();
if (flag == 0)
{
//PrintOrder();
flag++;
}
if (orders[1].type == 0 && orders[1].num == 4
&& orders[2].type == 7
&& orders[3].type == 0 && orders[3].num == 5) break;
}
}
void out(int x)
{
char p;
if (x < 10)
{
cout << x;
}
else
{
p = 'A' + x - 10;
cout << p;
}
}
void Hex(int n, int x)
{
int ans[1000];
int i = 0;
int na = n;
while (na >= x)
{
i++;
ans[i] = na % x;
na = na / x;
}
cout << x << "进制转换结果为:";
out(na);
for (int q = i; q >= 1; q--)
{
out(ans[q]);
}
cout << endl << endl;
}
void Draw2D()
{
Point2DList a;
double begin = orders[4].num;
double end = orders[6].num;
double x = (end - begin) / 100.0;
cout << x << endl;
DeleteOrder(2, 6);
Data other[1000];
int othersize;
othersize = size;
for (int i = 0;i < size;i++)
{
other[i].num = orders[i].num;
other[i].type = orders[i].type;
}
for (double j = begin;j <= end;j += x)
{
for (int i = 1;i < size;i++)
{
if (orders[i].type == 3 && orders[i].num == 24)
{
orders[i].type = 1;
orders[i].num = j;
}
}
while (true)
{
OperatorAnalyze();
//PrintOrder();
WordAnalyze();
//PrintOrder();
if (orders[1].type == 0 && orders[1].num == 4
&& orders[2].type == 1
&& orders[3].type == 0 && orders[3].num == 5)
{
a.AddPoint2D(j, orders[2].num);
break;
}
}
size = othersize;
for (int i = 0;i < othersize;i++)
{
orders[i].num = other[i].num;
orders[i].type = other[i].type;
}
}
a.LimitPoint2D();
a.Print();
}
void SolveEquation(int n)
{
for (int i = 1;i < size - 1;i++)
{
if (orders[i].type == 2 && orders[i].num == 1)
{
if (orders[i + 1].type != 3) ReplaceOrder(i, 2, (-orders[i + 1].num));
else
{
for (int j = size - 1;j > i;j--)
{
orders[j + 1].num = orders[j].num;
orders[j + 1].type = orders[j].type;
}
size++;
orders[i].type = 2;
orders[i].num = 0;
orders[i + 1].type = 1;
orders[i + 1].num = -1;
}
}
else if (orders[i].type != 1 && orders[i + 1].type == 3)
{
for (int j = size - 1;j > i;j--)
{
orders[j + 1].num = orders[j].num;
orders[j + 1].type = orders[j].type;
}
size++;
orders[i + 1].type = 1;
orders[i + 1].num = 1;
}
}
//PrintOrder();
UnknownList b;
int line = 0;
double xs = 1.0;
for (int i = 2;i < size;i++)
{
if (orders[i].type == 3) b.Add(orders[i].num, line, xs * orders[i - 1].num);
else if (orders[i].type == 1 && orders[i + 1].type != 3) b.Add(0, line, (-xs) * orders[i].num);
else if (orders[i].type == 5) xs *= -1;
else if (orders[i].type == 4 && orders[i].num == 1)
{
line++;
xs = 1.0;
}
}
line++;
//b.Print();
//cout << endl;
int x = b.Getzero();
Cmatrix matb;
for (int j = 0;j < line;j++)
{
for (int i = 0;i < b.UnknownSize;i++)
{
if (i == x) continue;
matb.Adddata(b.Check(j, i));
}
matb.Adddata(b.Check(j, x));
if (j != line - 1) matb.Change();
}
cout << matb << endl;
}
void TotalFunc()//总功能分类
{
//cout << orders[0].num << endl;
if (orders[0].num == 2066)//"cal"
{
Negative();
MatrixAssign();
TransWord();
//matrixvar.PrintMatrix();
Analyze();
cout << "结果为:" << endl << matrixvar.GetMatrix((int)orders[2].num) << endl;
}
else if (orders[0].num == 2840)//"def"
{
Negative();
//PrintOrder();
Cmatrix x;
x = DefMatrix();
matrixvar.AddMatrix(x);
//matrixvar.PrintMatrix();
cout << endl;
}
else if (orders[0].num == 82521)//"draw"
{
Negative();
if (orders[2].type == 1 && orders[2].num == 2) Draw2D();
}
else if (orders[0].num == 5562)//"hex"
{
Hex(orders[2].num, orders[4].num);
}
else if (orders[0].num == 13246)//"sol"
{
SolveEquation(orders[2].num);
}
//cout << "b" << endl;
}
};
int main()
{
while (true)
{
Order a;
a.GetOrder();
//a.PrintOrder();
a.TotalFunc();
}
}
//函数表达式部分 from刘彦迪
Cmatrix Abs(Cmatrix a)
{
for (int i = 0; i < a.Getrow(); i++)
{
for (int j = 0; j < a.Getcol(); j++)
{
double x = a.Getmatrix(i, j);
if (x < 0) a.Modify(i, j, -x);
}
}
return a;
}
Cmatrix Lst(Cmatrix a)//化行最简式
{
Cmatrix tempo;
tempo.Setrow(a.Getrow());
tempo.Setcol(a.Getcol());
for (int i = 0; i < tempo.Getrow(); i++)
{
for (int j = 0; j < tempo.Getcol(); j++)
tempo.Getmatrixi()[i][j] = a.Getmatrixi()[i][j];
}
double ratio = 0;
f:for (int i = 0; i < tempo.Getrow(); i++)
{
for (int j = 0; j < i; j++)
{
if (tempo.Getmatrixi()[j][j] == 0 && j != tempo.Getrow() - 2)
{
for (int p = i + 1; p < tempo.Getrow(); p++)
{
if (tempo.Getmatrixi()[p][j] != 0)
{
for (int y = 0; y < tempo.Getcol(); y++)
{
tempo.Swap(j + 1, y + 1, p + 1, y + 1);
}
break;
}
}
goto f;
}
if (tempo.Getmatrixi()[j][j] == 0 && tempo.Getmatrixi()[i][j] != 0 && j == tempo.Getrow() - 2)
{
for (int y = 0; y < tempo.Getcol(); y++)
{
tempo.Swap(j + 1, y + 1, tempo.Getrow(), y + 1);
}
}
if (tempo.Getmatrixi()[j][j] == 0 && tempo.Getmatrixi()[i][j] == 0 && j == tempo.Getrow() - 2)
{
int seed = j + 1;
while (tempo.Getmatrixi()[j][seed] == 0 && seed < tempo.Getcol())
{
seed++;
}
if (seed == tempo.Getcol())
{
tempo.Simplify();
return tempo;
}
ratio = tempo.Getmatrixi()[i][seed] / tempo.Getmatrixi()[j][seed];
for (int start = seed; start < tempo.Getcol(); start++)
{
tempo.Getmatrixi()[i][start] -= ratio * tempo.Getmatrixi()[j][start];
}
break;
}
ratio = tempo.Getmatrixi()[i][j] / tempo.Getmatrixi()[j][j];
for (int start = j; start < tempo.Getcol(); start++)
tempo.Getmatrixi()[i][start] -= ratio * tempo.Getmatrixi()[j][start];
}
}
tempo.Simplify();
for (int i = 0; i < tempo.Getrow(); i++)
{
if (tempo.Checkzero(i + 1)) continue;
for (int j = 0; j < tempo.Getcol(); j++)
{
if (tempo.Getmatrixi()[i][j] != 0)
{
tempo.Multi(i + 1, 1 / tempo.Getmatrixi()[i][j]); break;
}
}
}
tempo.Simplify();
int rank = 0;
for (int i = 0; i < a.Getrow(); i++)
{
if (!tempo.Checkzero(i + 1)) rank++;
else break;
}
for (int i = 1; i < rank; i++)
{
int seed = 0;
for (int j = 0; j < tempo.Getcol(); j++)
{
if (tempo.Getmatrixi()[rank - i][j] == 0) seed++;
else
{
break;
}
}
for (int p = 0; p < rank - i; p++)
{
ratio = tempo.Getmatrixi()[p][seed];
for (int y = seed; y < tempo.Getcol(); y++)
{
tempo.Getmatrixi()[p][y] -= ratio * tempo.Getmatrixi()[rank - i][y];
}
}
}
tempo.Simplify();
a.Setrat(tempo.Getrat());
return tempo;
}
Cmatrix matt(Cmatrix thismat)
{
Cmatrix tempo;
tempo.Setrow(thismat.Getcol());
tempo.Setcol(thismat.Getrow());
for (int i = 0; i < tempo.Getrow(); i++)
{
for (int j = 0; j < tempo.Getcol(); j++)
{
tempo.Getmatrixi()[i][j] = thismat.Getmatrixi()[j][i];
}
}
return tempo;
}
Cmatrix inv(Cmatrix thismat)
{
if (thismat.det() == 0 || thismat.Getrow() != thismat.Getcol())
{
cout << "无逆矩阵!" << endl;
return thismat;
}
Cmatrix tempo(thismat.Getrow());
Cmatrix tempo2 = thismat.Plus(tempo);
Cmatrix tempo3 = tempo2.Lst();
Cmatrix tempo4;
tempo4.Setrow(thismat.Getrow()); tempo4.Setcol(thismat.Getcol());
for (int i = 0; i < tempo4.Getrow(); i++)
for (int j = 0; j < tempo4.Getcol(); j++)
{
tempo4.Getmatrixi()[i][j] = tempo3.Getmatrixi()[i][j + thismat.Getcol()];
}
return tempo4;
}
Cmatrix Sch(Cmatrix a)
{
for (int j = 0; j < a.Getcol(); j++)
{
if (a.Checkzero2(j + 1))
{
cout << "这个矩阵不能施密特正交化" << endl;
return a;
}
}
Cmatrix tem = a;
for (int j = 1; j < tem.Getcol(); j++)
{
Cmatrix reserve = tem.vectorn(j + 1);
for (int p = 0; p < j; p++)
{
Cmatrix tempo = tem.vectorn(p + 1);
double ratio = -reserve.inpro(tempo) / tempo.inpro(tempo);
tem.Swap_add(j + 1, p + 1, ratio);
}
}
return tem;
}
Cmatrix ilog(Cmatrix a)
{
if (a.Getrow() != 1 && a.Getcol() != 1)
{
cout << "没法采用log计算" << endl;
return a;
}
Cmatrix tempo;
tempo.Setrow(1); tempo.Setcol(1);
double answ= log(a.Getmatrixi()[0][0]);
tempo.Getmatrixi()[0][0] = answ;
return tempo;
}
Cmatrix iexp(Cmatrix a)
{
if (a.Getrow() != 1 && a.Getcol() != 1)
{
cout << "没法采用exp计算" << endl;
return a;
}
Cmatrix tempo;
tempo.Setrow(1); tempo.Setcol(1);
tempo.Getmatrixi()[0][0] += 1;
return tempo;
}
Cmatrix add(Cmatrix a, Cmatrix b) { return a + b; }
Cmatrix sub(Cmatrix a, Cmatrix b) { return a - b; }
Cmatrix mul(Cmatrix a, Cmatrix b) { return a * b; }
Cmatrix div(Cmatrix a, Cmatrix b) { return a / b; }
Cmatrix Sol(Cmatrix a, Cmatrix b)
{
int n = 0;
Cmatrix tempo5 = a.Plus(b);
if (a.Getrow() != b.Getrow())
{
return a;
}
if (a.ranks() != tempo5.ranks())
{
n = 1;
}
else
{
n = 2;
}
Cmatrix tempo;
if (n == 1) tempo = a.Plus(b);
if (n == 2)
{
Cmatrix thisT = a.matt() * (a);
Cmatrix answ2 = a.matt() * b;
tempo = thisT.Plus(answ2);
}
Cmatrix tempo2 = tempo.Lst();
Cmatrix tempo3 = tempo2;
int freedom = a.Getcol() - a.ranks();
tempo3.Simplify();
cout << "tempo3为:" << endl;
for (int i = 0; i < tempo3.Getrow(); i++)
{
for (int j = 0; j < tempo3.Getcol(); j++)
{
cout << tempo3.Getmatrixi()[i][j] << " ";
}
cout << endl;
}
cout << endl;
int* trueorfalse; trueorfalse = new int[a.Getcol()];
for (int i = 0; i < a.Getcol(); i++)
trueorfalse[i] = 0;
for (int i = 0; i < a.Getrow(); i++)
{
int seed = 0;
for (int j = 0; j < tempo3.ranks(); j++)
{
if (tempo3.Getmatrixi()[i][j] == 0) seed++;
else
{
if (trueorfalse[seed] == 0)
{
trueorfalse[seed] = 1;
}
}
}
}
int* freedomnum = new int[freedom];
int record = 0;
for (int i = 0; i < a.Getcol(); i++)
{
if (trueorfalse[i] == 0)
{
freedomnum[record] = i; record++;
}
}
Cmatrix answer; answer.Setrow(a.Getcol()); answer.Setcol(1);
for (int i = 0; i < answer.Getrow(); i++)
{
if (trueorfalse[i] == 1)
answer.Getmatrixi()[i][0] = tempo3.Getmatrixi()[i][tempo3.Getcol() - 1];
else
answer.Getmatrixi()[i][0] = 0;
}
Cmatrix answer2; answer2.Setrow (a.Getcol()); answer2.Setcol(freedom);
int j = 0;
for (; j < answer2.Getcol(); j++)
{
for (int i = 0; i < answer2.Getrow(); i++)
{
if (i != freedomnum[j] && tempo3.Getmatrixi()[i][freedomnum[j]] != 0)
answer2.Getmatrixi()[i][j] = -tempo3.Getmatrixi()[i][freedomnum[j]];
else if (i != freedomnum[j] && tempo3.Getmatrixi()[i][freedomnum[j]] == 0)
answer2.Getmatrixi()[i][j] = 0;
else
answer2.Getmatrixi()[i][j] = 1;
}
}
Cmatrix total = answer.Plus(answer2);
return total;
}
进一步的思考
当然这次这个项目总共就持续了三周多,所以我们能够实现的功能还是很有限的,比如精美的界面就没有实现(actually我依稀记得最后我们是利用Qt实现了的,这个展示的不是最终的版本。但是界面毕竟涉及到的就是另一个方面的东西了。就我个人而言,项目还是有如下几个继续优化的方向:
- 精美的用户界面
- 追求更少的bug,如化行最简式等方法还可以有简化的空间
- 追求更快的计算速度和更少的占用内存
- 更多的关于矩阵计算的功能,如绘图等
- 使用Qt库,结合上一篇C++程序设计的文章做一个精致的iMatlab的exe,这个iMatlab可以包含矩阵计算、文本分析以及其他功能
总结
无论如何,作为一门大一下C++课程设计的作业,它确实激发了我对C++编程的好奇心,也巩固了我在课上学到的很多关于类、友元函数、模板、运算符重载等的知识,也学会在编程中不断地找出问题并debug,也提醒了我注释的重要性(这次再拿出来好多代码看不懂了~。不论以后会不会成为一个码农,掌握编程的技巧和发现问题解决问题的方法论对于一个工科生而言不可谓不重要。
欢迎对ECE/CS/AI感兴趣的小伙伴关注我,如果你对我的内容有什么建议或想法的话,也欢迎在评论区留下你的声音。
