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
MFC版链表实现稀疏多项式相加减的更多相关文章
- MFC实现一元稀疏多项式运算器
MFC实现一元稀疏多项式运算器 基本要求 输入并建立两个多项式 多项式a与b相加,建立和多项式c 多项式a与b相减,建立差多项式d 输出多项式a, b, c, d.输出格式:比如多项式a为:A(x)= ...
- 【Weiss】【第03章】练习3.6:有序多项式相加
[练习3.6] 编写将两个多项式相加的函数.不要毁坏输入数据.用一个链表实现. 如果这两个多项式分别有M项和N项,那么你程序的时间复杂度是多少? 两个按幂次升序的多项式链表,分别维护一个指针. 幂较小 ...
- C语言关于利用sscanf实现字符串相加减
#include<stdio.h>#include<string.h>void main(){ int a; int b; char str1[10] = "9999 ...
- 关于leetcode中链表中两数据相加的程序说明
* Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */ ...
- 微端游戏启动器LAUNCHER的制作之MFC版一(序和进程通信)
额...刚开始信誓旦旦说要写launcher制作的博客,还没写完就被抛到脑后了真是没毅力.最近把之前写的wpf的launcher改成了mfc版,遇到很多问题,写了三个星期才写完,好好记录一下吧.我也想 ...
- LeetCode: 2_Add Two Numbers | 两个链表中的元素相加 | Medium
题目: You are given two linked lists representing two non-negative numbers. The digits are stored in r ...
- 植物大战僵尸作弊器源代码(MFC版)
控制版使用不太方便,此MFC版与控制台版内容一样.具体可以参考前面.此处只附源代码,不加以说明.......... 头文件 // jsMFCDlg.h : 头文件 // #pragma once // ...
- django 取出数据库的时间与当前时间相加减
1 转换时区utc比北京时间慢八个小时 from datetime import tzinfo, timedelta, datetime ZERO = timedelta(0) class UTC(t ...
- 两个多项式相加 ( C++ )
实现两个多项式进行相加 不开辟空间 ( 这要求实现进行相加,代价为两个原链表将被修改) 分析: this>other 就把other当前结点放置在this之前 this<other 就th ...
随机推荐
- C# 另一种提交表单
一般提交表单的方式就是:Get,Post 以及关联action 今天看了一种方式感觉不错: 可以在submit里面写 PostBackUrl="XXXX",即回发的URL,可以实现 ...
- [物理学与PDEs]第1章第2节 预备知识 2.2 Ampere-Biot-Savart 定律, 静磁场的散度与旋度
1. 电流密度, 电荷守恒定律 (1) 电荷的定向移动形成电流. (2) 电流密度 ${\bf j}$, 是描述导体内一点在某一时刻电流流动情况的物理量, 用单位时间内通过垂直于电流方向的单位面积的电 ...
- /etc/profile文件被改坏导致命令不可用
这几天在装一个软件,设置环境变量的时候,不小心把/etc/profile文件改坏了(就是没配置对),在source /etc/profile后导致所有命令都不可用了.出现如下报错: -bash: xx ...
- C++中数组作为形参进行传递(转)
有两种传递方法,一种是function(int a[]); 另一种是function(int *a) 这两种两种方法在函数中对数组参数的修改都会影响到实参本身的值! 对于第一种,根据之前所学,形参是实 ...
- Centos 05 系统目录讲解
本节内容 1.linux目录结构 2.主目录功能简介 3.重要子目录 linux目录结构 在linux里面,逻辑上所有目录只有一个顶点,根是所有目录的起点. 根下面是类似一个倒挂的树一样的层次结构 可 ...
- BootStrap分页教程
https://www.cnblogs.com/laowangc/p/8875526.html https://www.cnblogs.com/yinglunstory/p/6092834.html ...
- spring事务源码分析结合mybatis源码(二)
让我们继续上篇,分析下如果有第二个调用进入的过程. 代码部分主要是下面这个: if (isExistingTransaction(transaction)) { return handleExisti ...
- vue之生命周期钩子函数之运用
一.什么是生命周期钩子函数: 每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听.编译模板.将实例挂载到 DOM 并在数据变化时更新 DOM 等.同时在这个过程中也会运行 ...
- 【全网最全的博客美化系列教程】08.自定义地址栏Logo
全网最全的博客美化系列教程相关文章目录 [全网最全的博客美化系列教程]01.添加Github项目链接 [全网最全的博客美化系列教程]02.添加QQ交谈链接 [全网最全的博客美化系列教程]03.给博客添 ...
- 11.2.0.4 aix下运行第二个节点root.sh报错处理
第二个节点运行root.sh报错如下 Entries will be added to the /etc/oratab file as needed by Database Configuration ...