目录
1.程序设计思路
1.框架构想
本程序的设计目的旨在使用C语言设计一个一元稀疏多项式计算器,其具有计算器可视化界面,多项式的加减法计算功能和自然语言的输入输出方式的功能,计算器根据用户输入的多项式和指定的功能来进行计算,最后输出计算结果。
2.数据结构的选择
由于多项式是稀疏多项式,故不应该使用数组的形式存储多项式,而应该使用链表存储多项式。
typedef struct
{
double coef; //多项式系数
int index; //多项式指数
}term;
typedef struct poly //多项式链表存储结构,稀疏多项式所以用链表存储结构
{
term data;
poly* next;
}poly_list;
2.相应功能的函数实现及程序变量解释
1.处理读入的字符串并将其转换成链表存储多项式信息
为了更加贴合日常使用的要求,该程序实现了自然语言读入的方式来进行多项式的输入。为了实现该功能需要将多项式中每项的系数和指数提取出来存入到数组里面,为此设计了Get_coef函数来从字符串当前位置获取一个数字,Getnum函数来处理整个字符串实现多项式信息的转换。
double Get_coef(char *str) //在输入的字符串中提取系数
{
double s = 0.0;
double d = 10.0; //处理大于10的系数
bool flag = false; //flag为false即为正数
while (*str == ' ')
str++;
if (*str == '-') //记录数字正负
{
flag = true;
str++;
if (*str == 'x' || *str == 'X') //如果系数为-1则直接返回
return -1.0;
}
else if ((*str == '+'&& (*(str + 1) == 'x' || *(str + 1) == 'X')) || (*str == 'x')) //系数为1则直接返回
return 1.0;
if (*str == '+' && (*(str + 1) >= '0' && *(str + 1) <= '9'))
str++;
if (!(*str >= '0' && *str <= '9')) //如果一开始非数字则退出,返回0.0
return s;
while (*str >= '0' && *str <= '9' && *str != '.') //计算小数点前整数部分
{
s = s * 10.0 + *str - '0';
str++;
}
if (*str == '.') //以后为小数部分
str++;
while (*str >= '0'&&*str <= '9') //计算小数部分
{
s = s + (*str - '0') / d;
d *= 10.0;
str++;
}
return s * (flag ? -1.0 : 1.0); //根据flag值返回相应的正负数
}
/*GetNums函数说明:
该函数实现将输入的字符串中的系数和指数提取存储到数组里面*/
void GetNums(int &cnt, double* coefs, int* indexs)
{
int i = 0;
cnt = 0;
double coef;
int expn = 0;
char str[80];
gets (str); //存放输入的字符串
while (*(str + i))
{
coef = Get_coef(str + i);
if (*(str + i) != 'x' && *(str + i ) != 'X')
i++;
while ((*(str + i) >= '0' && *(str + i) <= '9') || (*(str + i) == '.') || (*(str + i) == '-'))
i++;
if (*(str + i) == '+' || *(str + i) == '\0') //如果没有X则直接将指数赋值为零
expn = 0;
else if (*(str + i) == 'x' || *(str + i) == 'X')
{
i++;
if (*(str + i) == '+' || *(str + i) == '\0' || *(str + i) == '-') //只有x没有数字说明指数为1
expn = 1;
else if (*(str + i) == '^')
{
i++;
expn = (int)Get_coef(str + i);
if (*(str + i) == '-')
i++;
while ((*(str + i) >= '0'&&*(str + i) <= '9') || (*(str + i) == '.'))
i++;
}
}
coefs[cnt] = coef;
indexs[cnt] = expn;
cnt++;
}
}
在执行完Getnum函数后,从字符串中获得的多项式信息已经存储在coefs和indexs两个数组中,再使用create_poly函数实现将数组信息转化成链表。
/*Create_poly函数说明:
通过GetNums函数得到的系数和指数生成多项式链表*/
poly_list* Create_poly()
{
double coefs[80]; //存系数
int indexs[80]; //存指数
int count;
GetNums(count, coefs, indexs);
poly_list* head;
head = (poly_list*)malloc(sizeof(poly_list));
head->next = NULL;
poly_list* term_list;
for (int i = 0; i < count; i++)
{
term_list = (poly_list*)malloc(sizeof(poly_list));
term_list->next = NULL;
term_list->data.coef = coefs[i];
term_list->data.index = indexs[i];
Insert_list (head, term_list);
}
return head;
}
其中Insert_list函数实现将当前节点的指数按降序存储到链表中去。
int cmp (term a, term b) //比较两个多项式元素的指数大小
{
return a.index - b.index;
}
void Delete_list (poly_list* head, poly_list* q) //删除链表指定位置节点
{
poly_list* p;
p = head;
while (p->next != q)
p = p->next;
p->next = q->next;
}
/*Insert_list函数说明:
该函数实现将新的多项式元素插入多项式链表,并将链表按降序排列*/
void Insert_list (poly_list* head, poly_list* q)
{
poly_list* p = head;
poly_list* prior = head;
p = p->next;
while (p != NULL)
{
if (cmp (p->data, q->data) == 0) //若链表中存在的指数相同的项,则直接相加
{
p->data.coef += q->data.coef;
if (p->data.coef == 0) //遇到系数为0的极端情况删除该节点
Delete_list (head, p);
return;
}
else if (cmp (p->data, q->data) > 0) //指数小于当前节点则向后移
{
p = p->next;
prior = prior->next;
}
else //大于则插入链表
{
prior->next = q;
q->next = p;
return;
}
}
if (p == NULL) //空链表直接插入
{
prior->next = q;
q->next = NULL;
if (q->data.coef == 0)
Delete_list (head, q);
}
}
至此已经完成了所有链表创建的所有工作,链表信息存储在head头指针中。
2.多项式加减法的实现
AddDecrease_poly函数用于计算两个多项式p、q多项式的和或差,使用flag来控制计算模式,flag为1进行加法,flag为2进行减法,计算结果存储在result指针中。其具体实现逻辑并不难,在此不多说明。
/*AddDecrease_poly函数说明:
该函数用于计算两个多项式的和或差,通过flag的值来控制加法和减法来得到对应的结果*/
poly_list* AddorDecrease_poly (poly_list* p, poly_list* q, int flag) //多项式加法运算函数
{
poly_list* result; //存储结构的链表
result = (poly_list*)malloc(sizeof(poly_list));
result->next = NULL;
poly_list* term_list;
poly_list* index1 = p->next; //两个指针分别指向加数和被加数
poly_list* index2 = q->next;
while (index1 != NULL && index2 != NULL) //若当前两链表节点指数相同则直接相加
{
/*巧妙运用flag来控制加减法,仅用一个函数即可实现多项式加法和减法*/
term_list = (poly_list*)malloc(sizeof(poly_list));
term_list->next = NULL;
if (cmp (index1->data, index2->data) == 0 && flag == 1)
{
term_list->data.coef = index1->data.coef + index2->data.coef;
term_list->data.index = index1->data.index;
Insert_list (result, term_list);
index1 = index1->next;
index2 = index2->next;
}
else if (cmp (index1->data, index2->data) == 0 && flag == 2)
{
term_list->data.coef = index1->data.coef - index2->data.coef;
term_list->data.index = index1->data.index;
Insert_list (result, term_list);
index1 = index1->next;
index2 = index2->next;
}
else if (cmp(index1->data, index2->data) > 0) //将当前节点指数大的插入result链表
{
term_list->data.coef = index1->data.coef;
term_list->data.index = index1->data.index;
Insert_list (result, term_list);
index1 = index1->next;
}
else
{
term_list->data.coef = index2->data.coef;
term_list->data.index = index2->data.index;
Insert_list (result, term_list);
index2 = index2->next;
}
}
/*接下来判断两链表长度不相同的情况*/
if (index1 != NULL) //index1长的情况
while (index1 != NULL)
{
term_list = (poly_list*)malloc(sizeof(poly_list));
term_list->next = NULL;
term_list->data.coef = index1->data.coef;
term_list->data.index = index1->data.index;
Insert_list (result, term_list);
index1 = index1->next;
}
else if (index2 != NULL) //index2长的情况
while (index2 != NULL)
{
term_list = (poly_list*)malloc(sizeof(poly_list));
term_list->next = NULL;
term_list->data.coef = index2->data.coef;
term_list->data.index = index2->data.index;
Insert_list(result, term_list);
index2 = index2->next;
}
return result;
}
3.多项式升序和降序结果显示
Show_poly函数对传入参数head进行多项式输出,值得一提的是需要处理各种特殊的情况比如指数为1时不输出1,若系数为整数的时候不输出浮点数样式(使用Control_float来判断输出情况)
等等,在代码中都已经处理好了,实现方法不难,只是需要处理较多细节,读者请自行研究。
void Show_poly (poly_list* head) //将计算结果多项式链表输出
{
poly_list* p = head;
p = p->next;
if (p == NULL)
printf ("0");
/*各种极端情况的判断*/
while (