大作!!!超级计算机!

这个计算机可以帮助你计算高难度的东西(有些小bug 勿喷)

#include<iostream>
#include<string>
#include<deque>
#include<stack>
#include<vector>
#include<algorithm>
#include<iterator>
#include<cmath>
#include<Windows.h>
using namespace std;
vector<string> ivec;
double key1_2[6] = {0};
string exp1_2[6];
double key3_4[6] = {0};
string exp3_4[6];
double key12_3[6] = {0};
string exp12_3[6];
double key123_4[6] = {0};
string exp123_4[6];
double key12_34[6] = {0};
string exp12_34[6];
int Permutation(int[], int[][4]);
void Calc(double, double, double[], string[], string, string);
void Work(int[], int[][4], int);
void ersi()
{
    int num[4] = {0};
    int array[24][4] = {0};
    int count = 0;
    
    cout << "请输入4个1-13之间的整数,中间以空格隔开" << endl;
    
    /* 读入数据 */
    for (int i = 0; i < 4; i++)
    {
        cin >> num[i];
    }
    
    /* 待检测数据的数量 */
    count = Permutation(num, array);
    
    /* 求解24点 */
    Work(num, array, 24);
    
    /* 对结果进行排序 */
    sort(ivec.begin(), ivec.end());
    
    /* 去掉重复的解 */
    vector<string>::iterator iter = unique(ivec.begin(), ivec.end());
    
    /* 输出解集 */
    if (ivec.size() != 0)
    {
        cout << "该组数据的解为:" << endl;
        for (vector<string>::iterator it = ivec.begin(); it != iter; it++)
        {
            cout << *it << endl;
        }
    }
    else
    {
        cout << "该组数据无解" << endl;
    }
    
    system("pause");
}

/* 计算2个数,保存值及表达式 */
void Calc(double a, double b, double key[], string exp[], string expa, string expb)
{
    key[0] = a + b;
    exp[0] = '(' + expa + '+' + expb + ')';
    
    key[1] = a - b;
    exp[1] = '(' + expa + '-' + expb + ')';
    
    key[2] = b - a;
    exp[2] = '(' + expb + '-' + expa + ')';
    
    key[3] = a * b;
    exp[3] = '(' + expa + '*' + expb + ')';
    
    if (b > 0)
    {
        key[4] = a / b;
        exp[4] = '(' + expa + '/' + expb + ')';
    }
    
    if (a > 0)
    {
        key[5] = b / a;
        exp[5] = '(' + expb + '/' + expa + ')';
    }
}
int Permutation(int num[], int array[][4])
{
    int flag;
    int k = 0;
    int count = 0;
    int i, j, m, n, s;
    for (i = 0; i < 4; i++)
    {
        for (j = 0; j < 4; j++)
        {
            for (m = 0; m < 4; m++)
            {
                for (n = 0; n < 4; n++)
                {
                    if (i != j && i != m && i != n && j != m && j != n && m != n)
                    {
                        flag = 1;
                        for(s = 0; s < k; s++)
                        {
                            if(array[s][0] == num[i] && array[s][1] == num[j] && array[s][2] == num[m] && array[s][3] == num[n])
                            {
                                flag = 0;
                            }
                        }
                        if (flag == 1)
                        {
                            array[k][0] = num[i];
                            array[k][1] = num[j];
                            array[k][2] = num[m];
                            array[k][3] = num[n];
                            k++;
                            count++;
                        }
                    }
                }
            }
        }
    }
    return count;
}
void Work(int num[], int array[][4], int count)
{
    for (int i = 0; i < count; i++)
    {
        char buffer[20];
        string expa, expb;
        
        /* 转换第1个数字为表达式 */
        itoa(array[i][0], buffer, 10);
        expa = buffer;
        
        /* 转换第2个数字为表达式 */
        itoa(array[i][1], buffer, 10);
        expb = buffer;
        
        /* 计算第1个数和第2个数 */
        Calc(array[i][0], array[i][1], key1_2, exp1_2, expa, expb);
        
        /* (((A,B),C),D)形式 */
        for (int j = 0; j < 6; j++)
        {
            /* 转换第3个数字为表达式 */
            itoa(array[i][2], buffer, 10);
            expb = buffer;
            
            /* 计算第3个数和前2个数 */
            Calc(key1_2[j], array[i][2], key12_3, exp12_3, exp1_2[j], expb);
            
            for (int k = 0; k < 6; k++)
            {
                /* 转换第4个数字为表达式 */
                itoa(array[i][3], buffer, 10);
                expb = buffer;
                
                /* 计算第4个数和前3个数 */
                Calc(key12_3[k], array[i][3], key123_4, exp123_4, exp12_3[k], expb);
                
                for (int t = 0; t < 6; t++)
                {
                    if (fabs(key123_4[t] - 24) < 1e-6)
                    {
                        ivec.push_back(exp123_4[t]);
                    }
                }
            } 
        }
        
        /* 转换第3个数字为表达式 */
        itoa(array[i][2], buffer, 10);
        expa = buffer;
        
        /* 转换第4个数字为表达式 */
        itoa(array[i][3], buffer, 10);
        expb = buffer;
        
        /* 计算第3个数和第4个数 */
        Calc(array[i][2], array[i][3], key3_4, exp3_4, expa, expb);
        
        /* ((A,B),(C,D))形式 */
        for (int j = 0; j < 6; j++)
        {
            for (int k = 0; k < 6; k++)
            {
                /* 计算前2个数和后2个数 */
                Calc(key1_2[j], key3_4[k], key12_34, exp12_34, exp1_2[j], exp3_4[k]);
                for (int t = 0; t < 6; t++)
                {
                    if (fabs(key12_34[t] - 24) < 1e-6)
                    {
                        ivec.push_back(exp12_34[t]);
                    }
                }
            }
        }
    }
}
void yiyuan() {
    cout<<"方程等式:";
    string s;
    cin >> s;
    int sym = 1, flag = 1;  //sym表示数字之前的符号,flag表示等号左右
    int a = 0, b = 0;//系数,常数
    int i = 0;
    while (i < s.size()) {
        if (s[i] == '=') {
            sym = 1;
            flag = -1;
        }
        else if (s[i] == '+')
            sym = 1;
        else if (s[i] == '-')
            sym = -1;
        else { //遇到数字或x
            int t = 0;
            while (i < s.length() && s[i] >= '0'&&s[i] <= '9') {
                t = 10 * t + (s[i] - '0');
                i++;
            }
            if (s[i] == 'x'&&t == 0) {
                a += sym * flag;
            }
            else if (s[i] == 'x')
                a += t * sym*flag;
            else {
                b += t * sym*flag;
                continue;  //直接进行下一次循环是因为:上面while循环中处理数字之后已经++i
            }
        }
        i++;
    }
    if (a == 0 && b == 0) {
        printf("无数解\n");
    }
    else if (a != 0 && b % a == 0) {
        printf("x=%d\n", -b / a);
    }
    else {
        printf("无解\n");
    }
    system("pause");
}
bool isPra(char c) 
{
    if(c=='('||c==')') 
        return true; 
    else 
        return false;
}
 
//获得符号的优先性
int getPri(char c) 
{
    switch(c) 
    {
    case '+':
    case '-':
        return 0;    //如果是加减,返回0
        break;
    case '*':
    case '/':
        return 1;    //如果是乘除,返回1
        break;
    case '(':
    case ')':
        return -1;  //注意,这里将括号设为最低优先级,因此括号不会被弹出,除非遇到右括号
        break;
     }
}
 
//判断符号的优先性
void check(char c, stack<char>& coll2, deque<char>& coll3) 
{  
    if(coll2.empty()) 
    {
        coll2.push(c);
        return;
    }
 
    if(isPra(c)) 
    {
        if(c=='(') 
            coll2.push(c);
        else 
        {
            //弹出所有元素直到遇到左括号
            while(coll2.top()!='(') 
            {  
                char ch = coll2.top();
                coll3.push_back(ch);
                coll2.pop();
            }
 
            //当遇到左括号时,弹出但不加入coll3(后缀表达式中)
            coll2.pop();  
        }
    }
    else    //如果不是括号
    {
        //取出栈顶元素,与当前符号进行优先性比较
        char sym = coll2.top();  
 
        //比较两符号的优先性
        if(getPri(c)<=getPri(sym))  
        {
            //如果c的优先性比栈顶符号小或等于,弹出栈顶元素
            coll2.pop();
            //并将其压入coll3(后缀表达式)中
            coll3.push_back(sym);
            //递归调用check,比较当前符号c与下一个栈顶符号的优先性
            check(c,coll2,coll3);    
        }
        else 
        {
            //如果c比栈顶符号优先级大,那将c压入coll2(操作符栈)中
            coll2.push(c);  
        }
    }
}
 
//从coll中取出元素,分配元素到coll2和coll3中
void allocate(deque<char>& coll1, stack<char>& coll2, deque<char>& coll3) 
{  
    while(!coll1.empty()) 
    {
        char c = coll1.front();
        coll1.pop_front();
 
        if(c>='0'&&c<='9')
        {
            coll3.push_back(c);
        }
        else 
        {
            //调用check函数,针对不同情况作出不同操作
            check(c,coll2,coll3);  
        }
 
    }
 
    //如果输入结束,将coll2的元素全部弹出,加入后缀表达式中
    while(!coll2.empty()) 
    {  
        char c = coll2.top();
        coll3.push_back(c);
        coll2.pop();
    }
}
 
//计算后缀表达式
void calculate(deque<char>& coll3, stack<int>& coll4) 
{  
    while(!coll3.empty()) 
    {
        char c = coll3.front();
        coll3.pop_front();
        if(c>='0'&&c<='9') 
        {
            int op = c-'0';    
            coll4.push(op);     
        }
        else     //如果是操作符,从栈中弹出元素进行计算
        { 
            int op1 = coll4.top();
            coll4.pop();
            int op2 = coll4.top();
            coll4.pop();
            switch(c) 
            {
            case '+':
                coll4.push(op2+op1);
                break;
            case '-':
                coll4.push(op2-op1);
                break;
            case '*':
                coll4.push(op2*op1);
                break;
            case '/':
                coll4.push(op2/op1); 
                break;
            }
        }
    }
} 
void kuohao()
{
    deque<char> coll1;  //盛放中缀表达式
    stack<char> coll2;  //盛放操作符
    deque<char> coll3;    //盛放后缀表达式
    stack<int>coll4;    //计算后缀表达式的辅助容器
    string str;
    cout<<"请输入表达式,按enter结束:"<<endl;
    cin>>str;
    for(int i=0;i!=str.size();++i) 
    {
        coll1.push_back(str[i]);  
    }
    allocate(coll1,coll2,coll3); 
    calculate(coll3,coll4);  
    cout<<"计算结果为:"<<coll4.top()<<endl;
    Sleep(2000);
}
int main(){
    while(1){
        system("cls");
        cout<<"超级计算机\n";
        cout<<"请问你要计算什么呢?我支持以下操作:\n1.一元一次方程\n2.带括号的四则运算\n3.解24点\n(填序号)\n序号:";
        int x;
        cin>>x;
        if(x==1){
            system("cls");
            yiyuan();
        }
        else if(x==2){
            system("cls");
            kuohao();
        }
        else if(x==3){
            system("cls");
            ersi();
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值