因为淋过雨所以想造福大家,以下代码可以完美实现多函数嵌套运算,四则运算表达式不在话下。大家放心使用。
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<bits/stdc++.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stdbool.h>
using namespace std;
const double pi=acos(-1);
#define MaxSize 100
#define MaxString 100
char str[MaxSize];// 存储中缀表达式
double composite_value[MaxSize];//去函数权值
int middle_f[MaxSize];//中缀表达式标志
int middle_len;// 中缀表达式长度
double post[MaxSize];//后缀表达式
int post_f[MaxSize];// 后缀各值类型
int cnt;//后缀表达式长度
typedef struct nd {
char c; double val;
}sq;
sq arr[MaxSize];
//type[]=1 :数字
//type[]=2 :字母
//type[]=3 :符号
//type[]=4 :函数标记合成处
//typedef char STDataType;
typedef struct Stack
{
double data[MaxSize];
int top;
//int capacity;
}ST;
//初始化
void StackInit(ST* ps)
{
ps->top = -1;
}
//push函数
void StackPush(ST* ps, double elem)
{
ps->top++;
ps->data[ps->top] = elem;
}
//pop函数
void StackPop(ST* ps)
{
ps->top--;
}
//返回栈大小
int StackSize(ST* ps)
{
return ps->top;
}
// 返回栈顶元素
double StackTop(ST* ps) {
return ps->data[ps->top];
}
// 判断栈是否为空
bool StackEmpty(ST* ps)
{
if (ps->top == -1) {
return 1;
}
return 0;
}
int Judge(char a, char b)
{
int v1, v2;
v1 = v2 = 0;
switch (a)
{
case '(':v1 = 1; break;
case '+':v1 = 3; break;
case '-':v1 = 3; break;
case '*':v1 = 5; break;
case '/':v1 = 5; break;
case '^':v1= 7; break;
case ')':v1= 9; break;
}
switch (b)
{
case '(':v2 = 1; break;
case '+':v2 = 3; break;
case '-':v2 = 3; break;
case '*':v2= 5; break;
case '/':v2 = 5; break;
case '^':v2= 7; break;
case ')':v2 = 9; break;
}
if (v1 >= v2) return 1;
else return 0;
}
//计算后缀表达式
double calPostfix()
{
ST* numsStack = (ST*)malloc(sizeof(ST));
StackInit(numsStack);
for (int i = 0; i < cnt; i++)
{
if (post_f[i] == 2 && ((post[i] >= 'A' && post[i] <= 'Z') || (post[i] >= 'a' && post[i] <= 'z'))) {
for (int j = 0; j < MaxSize; j++) {
if (arr[j].c == post[i]) {
StackPush(numsStack, arr[j].val);
break;
}
}
}
else if (post_f[i] == 1) {
StackPush(numsStack, post[i]);
}
else
{
double x = StackTop(numsStack);
StackPop(numsStack);
double y = StackTop(numsStack);
StackPop(numsStack);
double z = 0;
if (post[i] == '+') {
z = x + y;
}
else if (post[i] == '-') {
z = y - x;
}
else if (post[i] == '*') {
z = x * y;
}
else if (post[i] == '/') {
z = y / x;
}
StackPush(numsStack, z);
}
}
for (int i = 0; i <= cnt + 1; i++) {
post[i] = 0;
}
return StackTop(numsStack);
}
//假定+,-的优先级是1, *,/的优先级是2,数字是-1
// 中缀转后缀
double postfixNotation(int start, int end)
{
//s1保存结果,s2临时保存操作符
cnt = 0;
ST* s1 = (ST*)malloc(sizeof(ST));
StackInit(s1);
for (int i = start; i <= end; i++)
{
if (str[i] == ' ') {
continue;
}
if (middle_f[i] == 4) {
post_f[cnt] = 1;
post[cnt++] = composite_value[i];
continue;
}
if (str[i] == '(')
{
StackPush(s1, str[i]);
}
else if (str[i] >= '0' && str[i] <= '9') {
int p = i;
double k = 0;
int flag = 0;
while (str[i] >= '0' && str[i] <= '9') {
k *= 10;
k += (str[i] - '0');
str[i] = ' ';
i++;
if (str[i] == '.') { flag = 1; }
}
if (flag) {
i++; double cur_p = 1.0;
while ((str[i] >= '0' && str[i] <= '9')) {
cur_p *= 10;
k +=((str[i] - '0') / cur_p);
str[i] = ' ';
i++;
}
}
i--;
composite_value[p] = k;
post_f[cnt] = 1;
post[cnt++] = k;
}
else if ((str[i] >= 'A' && str[i] <= 'Z') || (str[i] >= 'a' && str[i] <= 'z')) {
post_f[cnt] = 2;
post[cnt++] = str[i];
}
else if (str[i] == ')')
{
while (StackTop(s1) != '(')
{
post_f[cnt] = 3;
post[cnt++] = StackTop(s1);
StackPop(s1);
}
StackPop(s1);
}
else
{
if (StackEmpty(s1))
{
StackPush(s1, str[i]);
}
else
{
char cc = StackTop(s1);
while (!StackEmpty(s1) && Judge(cc,str[i])) {
post_f[cnt] = 3;
post[cnt++] = StackTop(s1);
StackPop(s1);
if (!StackEmpty(s1)) {
cc = StackTop(s1);
}
}
StackPush(s1, str[i]);
}
}
}
while (!StackEmpty(s1))
{
post_f[cnt] = 3;
post[cnt++] = StackTop(s1);
StackPop(s1);
}
return calPostfix();
}
// 内处理 注意定义函数名 括号匹配原理
double inline_processing(int start, int funcname) {
int end=0;
int left = 0, right = 0; int ff = 0;//ff记录分隔符
for (int i = start; i < middle_len; i++) {
if (str[i] == ',') {
ff = i;
}
if (str[i] == '(') {
left++;
}
else if (str[i] == ')') {
right++;
}
if (left == right) {
end = i;
break;
}
}
double result=0;//max
if (funcname == 1) {
double aa = postfixNotation(start + 1, ff - 1);
double bb = postfixNotation(ff + 1, end - 1);
result = aa > bb ? aa : bb;
}//abs
else if (funcname == 2) {
result = postfixNotation(start + 1, end - 1);
result = abs(result);
}
else if (funcname == 3) {
double aa = postfixNotation(start + 1, ff - 1);
double bb = postfixNotation(ff + 1, end - 1);
result = aa < bb ? aa : bb;
}
else if (funcname == 4) {
result = postfixNotation(start + 1, end - 1);
result = sqrt(result);
}
else if (funcname == 5) {
result = postfixNotation(start + 1, end - 1);
result = sin(result);
}
else if (funcname == 6) {
result = postfixNotation(start + 1, end - 1);
result = cos(result);
}
else if (funcname == 7) {
result = postfixNotation(start + 1, end - 1);
result = tan(result);
}
if (funcname == 4) {
start -= 3;
}
else
start -= 2;
for (int i = start; i <= end; i++) {
middle_f[i] = -1;
//type[i] = -1;
str[i] = ' ';
}
return result;
}
// 预处理
void pre_process() {
//max 1
for (int i = middle_len-1; i >= 0; i--) {
if (str[i] == 'm' && str[i + 1] == 'a' && str[i + 2] == 'x') {str[i] = '!'; middle_f[i] = 4;double cur_val = inline_processing(i + 3, 1);
composite_value[i] = cur_val;}
//abs 2
if (str[i] == 'a' && str[i + 1] == 'b' && str[i + 2] == 's') { str[i] = '@';middle_f[i] = 4;double cur_val = inline_processing(i + 3, 2);
composite_value[i] = cur_val;}
// min 3
if (str[i] == 'a' && str[i + 1] == 'b' && str[i + 2] == 's') { str[i] = '#'; middle_f[i] = 4;double cur_val = inline_processing(i + 3, 3);
composite_value[i] = cur_val;}
//sqrt 4
if (str[i] == 's' && str[i + 1] == 'q' && str[i + 2] == 'r' && str[i + 3] == 't') { str[i] = '$';middle_f[i] = 4;double cur_val = inline_processing(i + 4, 4);
composite_value[i] = cur_val;}
//sin 5
if (str[i] == 's' && str[i + 1] == 'i' && str[i + 2] == 'n') {str[i] = '~';middle_f[i] = 4;double cur_val = inline_processing(i + 3, 5);
composite_value[i] = cur_val;}
// cos 6
if (str[i] == 'c' && str[i + 1] == 'o' && str[i + 2] == 's') {str[i] = '?';middle_f[i] = 4;double cur_val = inline_processing(i + 3, 6);
composite_value[i] = cur_val;}
// tan 7
if (str[i] == 't' && str[i + 1] == 'a' && str[i + 2] == 'n' ) {str[i] = '^';middle_f[i] = 4;double cur_val = inline_processing(i + 3, 7);
composite_value[i] = cur_val;}}}
int main()
{
printf("调用多函数解决并保留6位小数\n");
int times = 0;
printf("输入变量个数:\n");
cin >> times;
printf("输出变量\n");
printf("输入单个字符及其值:\n");
for (int k = 0; k < times; k++) {
cin >> arr[k].c >> arr[k].val;
}
if (times != 0) {
printf("你输入的变量为:\n");
}
for (int k = 0; k < times; k++) {
printf("%c=%g\n", arr[k].c, arr[k].val);
}
printf("\n");
flag:
printf("输入一个表达式:\n");
cin >> str;
middle_len = strlen(str);
for (int i = 0; i < middle_len; i++) {
if (str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/') {
middle_f[i] = 2;
}
}
pre_process();
double value;
cnt = middle_len;
value = postfixNotation(0, cnt - 1);
printf("表达式的值:");
printf("%g\n", value);
for (int i = 0; i < MaxSize; i++) {
composite_value[i] = 0;
post_f[i] = 0;
}
cout << endl;goto flag;
return 0;
}