• MFC版链表实现稀疏多项式相加减


    链表实现多项式运算(加减)MFC可视化版
    ##题目 设计一个一元稀疏多项式简单计算器。 ##基本要求 (1)输入并建立两个多项式; (2)多项式a与b相加,建立和多项式c; (3)多项式a与b相减,建立差多项式d; (4)输出多项式a, b, c, d。输出格式:比如多项式a为:A(x)=c1xe1+ c2xe2+…+ cmxem,其中,ci和ei分别为第i项的系数和指数,且各项按指数的升幂排列,即0≤e1<e2<…<em。 ##实现提示 (1)用带头结点的单链表存储多项式。 (2)每个多项式链表中都只存储非零系数项。若多项式a与b中指数相等的两项相加/减后,系数为零,则在和/差多项式中不存储该指数项。

    思路

    其实说真的,看到链表就烦,没办法了,只能写了,无奈自己太菜,大部分代码还是用的书上的,不过再运算符重载的时候自己改动了一下,因为要MFC可视化的缘故,就把输入输出的重载删掉了。
    大致就和老师说的一样,重点在于建立多项式类,难点在于MFC可视化的计算器界面的数据输入输出,当然方法肯定很多,代码比较糙,将就着看吧,希望有对你有用的部分。
    样子差不多就是这样:

    输入

    输出

    1)输入数据处理

    输入时,用CString变量存编辑框的内容,同时具备按钮输入和键盘输入两种方法,时间比较急,没有检测非法输入,必须是合法输入才能运算。不过这个写起来也不难,完成作业就先这样吧,到时候要是她还有要求再说。先把所有输入存在串里,然后用函数分割开,存进多项式对象里,在分割时写了一个函数,感觉蛮好用的,这里还有一个操作可能比较多于,先用CString存,在取数据的时候又转换为string,对string熟一点。
    按键输入代码:

    void CCalculatorDlg::OnBnClickedButton1()
    {
    	UpdateData(TRUE);
    	m_Str += "1";
    	UpdateData(FALSE);
    	// TODO: 在此添加控件通知处理程序代码
    }
    
    
    void CCalculatorDlg::OnBnClickedButton0()
    {
    	UpdateData(TRUE);
    	m_Str += "0";
    	UpdateData(FALSE);
    	// TODO: 在此添加控件通知处理程序代码
    }
    
    
    void CCalculatorDlg::OnBnClickedButtonNod()
    {
    	UpdateData(TRUE);
    	m_Str += ".";
    	UpdateData(FALSE);
    	// TODO: 在此添加控件通知处理程序代码
    }
    
    
    void CCalculatorDlg::OnBnClickedButton2()
    {
    	m_Str += "2";
    	UpdateData(FALSE);
    	// TODO: 在此添加控件通知处理程序代码
    }
    
    
    void CCalculatorDlg::OnBnClickedButton3()
    {
    	UpdateData(TRUE);
    	m_Str += "3";
    	UpdateData(FALSE);
    	// TODO: 在此添加控件通知处理程序代码
    }
    
    
    void CCalculatorDlg::OnBnClickedButton4()
    {
    	UpdateData(TRUE);
    	m_Str += "4";
    	UpdateData(FALSE);
    	// TODO: 在此添加控件通知处理程序代码
    }
    
    
    void CCalculatorDlg::OnBnClickedButton5()
    {
    	m_Str += "5";
    	UpdateData(FALSE);
    	// TODO: 在此添加控件通知处理程序代码
    }
    
    
    void CCalculatorDlg::OnBnClickedButton6()
    {
    	UpdateData(TRUE);
    	m_Str += "6";
    	UpdateData(FALSE);
    	// TODO: 在此添加控件通知处理程序代码
    }
    
    
    void CCalculatorDlg::OnBnClickedButton7()
    {
    	UpdateData(TRUE);
    	m_Str += "7";
    	UpdateData(FALSE);
    	// TODO: 在此添加控件通知处理程序代码
    }
    
    
    void CCalculatorDlg::OnBnClickedButton8()
    {
    	UpdateData(TRUE);
    	m_Str += "8";
    	UpdateData(FALSE);
    	// TODO: 在此添加控件通知处理程序代码
    }
    
    
    void CCalculatorDlg::OnBnClickedButton9()
    {
    	m_Str += "9";
    	UpdateData(FALSE);
    	// TODO: 在此添加控件通知处理程序代码
    }
    
    
    void CCalculatorDlg::OnBnClickedButtonadd()
    {
    	UpdateData(TRUE);
    	m_Str += "+";
    	UpdateData(FALSE);
    	// TODO: 在此添加控件通知处理程序代码
    }
    
    
    void CCalculatorDlg::OnBnClickedButtonsub()
    {
    	UpdateData(TRUE);
    	m_Str += "-";
    	UpdateData(FALSE);
    	// TODO: 在此添加控件通知处理程序代码
    }
    
    
    void CCalculatorDlg::OnBnClickedButtonx()
    {
    	m_Str += "X";
    	UpdateData(FALSE);
    	// TODO: 在此添加控件通知处理程序代码
    }
    
    
    void CCalculatorDlg::OnBnClickedButtonleft()
    {
    	UpdateData(TRUE);
    	m_Str += "(";
    	UpdateData(FALSE);
    	// TODO: 在此添加控件通知处理程序代码
    }
    
    
    void CCalculatorDlg::OnBnClickedButtonright()
    {
    	UpdateData(TRUE);
    	m_Str += ")";
    	UpdateData(FALSE);
    	// TODO: 在此添加控件通知处理程序代码
    }
    
    
    void CCalculatorDlg::OnBnClickedButtonmul()
    {
    	UpdateData(TRUE);
    	m_Str += "^";
    	UpdateData(FALSE);
    	// TODO: 在此添加控件通知处理程序代码
    }
    
    
    void CCalculatorDlg::OnBnClickedButtonClear()
    {
    	m_Str = "";
    	UpdateData(FALSE);
    	// TODO: 在此添加控件通知处理程序代码
    }
    

    分割系数和指数函数:pos是开始时的串数组下标,exp是指数,返回系数

    float Search_Num(string a,int &pos,int&exp) {
    	float num = 0;
    	int cap = 0;
    	for (int i(pos); i < a.size(); i++) {
    		if (a[i] >= '0'&&a[i] <= '9') {
    			if (cap == 0)
    				num = num * 10 + a[i] - '0';
    			else num = num + (a[i] - '0')*pow(0.1, cap++);
    		}
    		else if (a[i] == '.') {
    			cap = 1;
    		}
    		else {
    			pos = i;
    			break;
    		}
    	}
    	exp = 0;
    	int tag = 1;
    	if (num == 0)
    		num = 1;
    	if (a[pos] == 'X') {
    		if (pos > a.size() -1||a[pos+1]=='-'||a[pos+1]=='+') {
    			exp = 1;
    			pos++;
    			return num;
    		}
    		if (a[pos + 2] == '-') {
    			tag = -1;
    			pos++;
    		}
    		for (int i(pos + 2); i < a.size(); i++) {
    			if (a[i] >= '0'&&a[i] <= '9') {
    				exp= exp* 10 + a[i] - '0';
    			}
    			else { 
    				pos = i;
    				exp *= tag;
    				return num;
    			}
    		}
    	}
    	else {
    		exp = 0;
    		return num;
    	}
    }
    

    2)存进多项式对象中

    类实现:

    #include<iostream>
    #include<string>
    #include<cmath>
    const double EXP = 1e-4;
    using namespace std;
    struct Term {
    	float coef;
    	int exp;
    	Term *link;
    	Term(float a, int b, Term* c = NULL) {
    		coef = a;
    		exp = b;
    		link = c;
    	}
    	Term *insertAfter(float a, int b);
    };
    Term *Term::insertAfter(float a, int b) {
    	link = new Term(a, b, link);
    	return link;
    }
    class Poly {
    private:
    	Term *first;
    	
    public:
    	Poly() {
    		first = new Term(0, -1);
    	}
    	Poly(Poly&R);
    	int maxOrder();
    	Term *GetHead() {
    		return first;
    	}
    	string GetString();
    	Poly operator+(Poly&);
    	Poly operator-(Poly&);
    };
    Poly::Poly(Poly &R) {
    	first = new Term(0, -1);
    	Term *destptr = first, *srcptr = R.GetHead()->link;
    	while (srcptr != NULL) {
    		destptr->insertAfter(srcptr->coef, srcptr->exp);
    		srcptr = srcptr->link;
    		destptr = destptr->link;
    	}
    }
    int Poly::maxOrder() {
    	Term *current = first;
    	while (current->link != NULL) {
    		current = current->link;
    	}
    	return current->exp;
    }
    string Poly::GetString()
    {
    	string s;
    	CString str;
    	Term *p = GetHead()->link;
    	bool flag = false;
    	while (p != NULL) {
    		str.Format(_T("%.5lf"), p->coef);
    		if (flag == true) {
    			if (p->coef >0) {
    				s += '+';
    			}
    		}
    		flag = true;
    		while (str[str.GetLength() - 1] == '0') {
    			str.Delete(str.GetLength() - 1, 1);
    		}
    		if (str[str.GetLength() - 1] == '.') {
    			str.Delete(str.GetLength() - 1, 1);
    		}
    		if(p->exp==0||(str!=_T("1")&&str!=(_T("-1"))))
    			s += (CT2A)str;
    		else if (str == _T("-1")) {
    			s += '-';
    		}
    		if (p->exp == 1) {
    			s += 'X';
    		}
    		else if(abs(p->exp)>1)
    			s += "X^";
    		str.Format(_T("%d"), p->exp);
    		if (abs(p->exp) > 1) {
    			s += (CT2A)str;
    		}
    		p = p->link;
    	}
    	return s;
    }
    Poly Poly::operator+(Poly&R) {
    	Term*pa, *pb, *pc, *p;
    	Poly C;
    	float temp;
    	pc = C.first;
    	pa = GetHead()->link;
    	pb = R.GetHead()->link;
    	while (pa != NULL && pb != NULL) {
    		if (pa->exp == pb->exp) {
    			temp = pa->coef + pb->coef;
    			if (abs(temp) > EXP) {
    				pc = pc->insertAfter(temp, pa->exp);
    			}
    			pa = pa->link;
    			pb = pb->link;
    		}
    		else if (pa->exp < pb->exp) {
    			pc = pc->insertAfter(pa->coef, pa->exp);
    			pa = pa->link;
    		}
    		else {
    			pc = pc->insertAfter(pb->coef, pb->exp);
    			pb = pb->link;
    		}
    	}
    	p = pa == NULL ? pb : pa;
    	while (p != NULL) {
    		pc = pc->insertAfter(p->coef, p->exp);
    		p = p->link;
    	}
    	return C;
    }
    Poly Poly::operator-(Poly&R) {
    	Term*pa, *pb, *pc, *p;
    	Poly C;
    	float temp;
    	pc = C.first;
    	pa = GetHead()->link;
    	pb = R.GetHead()->link;
    	while (pa != NULL && pb != NULL) {
    		if (pa->exp == pb->exp) {
    			temp = pa->coef - pb->coef;
    			if (abs(temp) > EXP) {
    				pc = pc->insertAfter(temp, pa->exp);
    			}
    			pa = pa->link;
    			pb = pb->link;
    		}
    		else if (pa->exp < pb->exp) {
    			pc = pc->insertAfter(pa->coef, pa->exp);
    			pa = pa->link;
    		}
    		else {
    			pc = pc->insertAfter(-pb->coef, pb->exp);
    			pb = pb->link;
    		}
    	}
    	p = pa == NULL ? pb : pa;
    	int flag = pa == NULL ? -1 : 1;
    	while (p != NULL) {
    		pc = pc->insertAfter(flag*p->coef, p->exp);
    		p = p->link;
    	}
    	return C;
    }
    

    按等于按钮开始读数据存进多项式A,B中:

    void CCalculatorDlg::OnBnClickedButtonCal()
    {
    	UpdateData(TRUE);
    	string s = (CT2A)m_Str;
    	if (s.empty()) {
    		AfxMessageBox(_T("请输入表达式!"));
    		return;
    	}
    	Poly A, B,C;
    	bool flag = false;
    	float num = 0;
    	int cap = 0;
    	int v = 1;
    	int pos_B;
    	for (int i(0); i < s.size(); i++) {
    		if (s[i] == ')') {
    			pos_B = i;
    			break;
    		}
    	}
    	int p = 0;
    	if (s[0] == '(')p++;
    	bool real = true;
    	Term *rear = A.GetHead();
    	while (p < pos_B) {
    		real = true;
    		if (s[p] == '+') {
    			real = true;
    			p++;
    		}
    		else if (s[p] == '-'){
    			real = false;
    			p++;
    		}
    		int temp_e;
    		num=Search_Num(s, p,temp_e);
    		v = real == true ? 1 : -1;
    		rear = rear->insertAfter(v*num, temp_e);
    	}
    	p += 3;
    	rear = B.GetHead();
    	while (p < s.size()-1) {
    		real = true;
    		if (s[p] == '+') {
    			real = true;
    			p++;
    		}
    		else if (s[p] == '-') {
    			real = false;
    			p++;
    		}
    		int temp_e;
    		num = Search_Num(s, p, temp_e);
    		v = real == true ? 1 : -1;
    		rear = rear->insertAfter(v*num, temp_e);
    	}
    	if (s[pos_B + 1] == '+') {
    		C = A + B;
    	}
    	else {
    		C = A - B;
    	}
    	string temp = C.GetString();
    	m_Str = temp.c_str();
    	UpdateData(FALSE);
    	// TODO: 在此添加控件通知处理程序代码
    }
    

    3)结果转换位字符串更新到Edit框中

    转字符串的函数就在类定义里面,也费了不少功夫,因为样例给的情况太全面了,刚开始没考虑到负指数,不过不要紧,还是改好了。面向对象的特点体现以后更改代码也比较方便~

    后记

    代码没有写注释,故意的。对,故意的。能理解的小伙伴应该能看懂,完全不懂的就有点困难了,相比不可视化,可视化对于输入和输出需要转化一下,其他的和不普通的差不多,当然写按钮也比较烦,,,
    界面很丑,之后可能会美化,再说吧,今天先睡了。
    2018/11/13 23:42:48

  • 相关阅读:
    免费部署Woocall到您自己的网站上
    服务器控件开发之复杂属性
    删除数据库的所有存储过程、主键、外键、索引等
    怎样在dropdownlist的每一项前加一个或多个空格
    Java的内部类学习
    StringUtils全览 (转)
    Java异常大全
    Java web 开发小问题总结(持续更新中)
    Java常用方法总结(持续更新中)
    Python 常用函数
  • 原文地址:https://www.cnblogs.com/Titordong/p/9955642.html
Copyright © 2020-2023  润新知