高山 发表于 2022-11-27 20:36:43

【C\C++版块提升计划】每周一练第18期:适当加括号(限免)

每周一练 第18期 适当加括号作者作者介绍本帖作者:每周一练@tommyyu 自由投稿
原稿:https://fishc.com.cn/forum.php?m ... =221250&pid=6062618
声明内容
版权声明:转载于@dolly_yos2 (点此查看原稿)
免责声明:本帖由“本帖作者”栏目的作者投稿,任何违规行为每周一练机构没有任何责任!!!
自由投稿:请前往 https://fishc.com.cn/thread-221250-1-1.html
static/image/hrline/1.gif
题目
编写一个程序,在不改变算式的基础上,使这个程序对输入的算式的适当的地方加上括号,改变这个算式的运算顺序,以让这个算式能够从左往右逐步计算,且添加括号的数目尽可能少。只需要添加英文半角小括号这一种括号。
输入输出格式
输入:一个不带空格的算式,比如1*2*3*4,其中只有加、减、乘、除四种运算,分别用+、-、*、/四个符号来表示
输入输出样例
样例一:
输入
1+2+3*4输出
(1+2+3)*4样例二:
输入
7+8*9+10输出
(7+8)*9+10数据范围
输入的长度小于等于100 。
题解
**** Hidden Message *****
代码:
**** Hidden Message *****

奖励规则:
代码效率等方面最优,选为最佳答案,得到13鱼币+8荣誉+3贡献+1技术值
代码运行正确,奖励3鱼币
代码运行错误奖励将会折扣
仅支持使用C\C++语言编写
如果喜欢,别忘了评分{:10_281:} :



zhangjinxuan 发表于 2022-11-27 20:36:44

本帖最后由 zhangjinxuan 于 2022-11-27 21:23 编辑

何必呢?
#include <bits/stdc++.h>
using namespace std;

char opts, c;
int nums, n = 1;
void solve(int l) {
    bool flag = false;
    if (l > 1) {
      if ((opts == '*' || opts == '/') && (opts == '+' || opts == '-')) {
            flag = true;
            printf("(");
      }
      solve(l - 1);
    } else printf("%d", nums);
    if (flag) printf(")");
    printf("%c", opts);
    if (l != n) printf("%d", nums);
}
int main() {
    scanf("%d", &nums);
    while ((c = getchar()) != '\n'){
      opts = c;
      scanf("%d", &nums);
      ++n;
    }
    int st = clock();
    solve(n);
    int en = clock();
    printf("\n用时:%dms", en - st);
    return 0;
}

高山 发表于 2022-11-27 20:36:44

@zhangjinxuan @编程追风梦 @陈尚涵 @元豪 @xiaosi4081 @漫星闪 @hveagle

zhangjinxuan 发表于 2022-11-27 21:01:15

其实我有答案,就交给别人回答吧^_^

zhiwen 发表于 2022-11-27 21:07:46

回复看看答案

编程追风梦 发表于 2022-11-28 05:17:31

回去睡觉啦,白天再看{:10_256:}

zhangjinxuan 发表于 2022-11-28 08:00:39

还忘了一个!数字确定不会爆 int,题目要说出来啊,意思是,数字的大小最大是多少,最小是多少?

zhangjinxuan 发表于 2022-11-28 08:01:34

就是说我们输入一个 11111111111111111+2222222222222222222222222222222 之类的算式我们是不是就歇菜了?{:10_256:}

xiaosi4081 发表于 2022-11-28 14:17:33

这......
提供个思路吧:
将从左到右运算优先级小的加括号
可以考虑用树

Clamb 发表于 2022-11-28 14:17:41

zhangjinxuan 发表于 2022-11-28 08:01
就是说我们输入一个 11111111111111111+2222222222222222222222222222222 之类的算式我们是不是就歇菜了?{ ...

或许得写一个大数的模拟运算?{:10_260:}

Clamb 发表于 2022-11-28 14:20:56

瞧瞧摸出我的逆波兰板子{:10_254:}
#include<bits/stdc++.h>
using namespace std;
#define pi acos(-1)
#define mod 998244353
#define INF 0x3f3f3f
#define fi first
#define se second
#define it iterator
#define ins insert
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define ll long long
#define ull unsigned long long
#define mem(a) memset(a,0,sizeof(a))
#define cio ios::sync_with_stdio(false)
#define gcd __gcd
ll lgcd(ll a,ll b){return b == 0? a:lgcd(b, a % b);}
int lowbit(int x){return x&(-x);}
#define T int t;scanf("%d",&t);while(t--)
#define CE cout << endl
#define C(n) cout << n << endl
#define CY cout << "YES" << endl
#define CN cout << "NO" << endl
#define Cy cout << "Yes" << endl
#define Cn cout << "No" << endl


int binaryPow(int a, int b){        // a^b%mod
        int ans = 1;
        while(b > 0){
                if(b & 1){
                        ans = ans * a % mod;
                }
                a = a * a % mod;
                b >>= 1;
        }
        return ans;
}

double Calculate(double a, double b, char f)// 进行加减乘除运算
{
    if(f=='+') return b+a;
    if(f=='-') return b-a;
    if(f=='*') return b*a;
    if(f=='/') return b/a;
    if(f=='^') return binaryPow(b,a);
    return 0;
}

int jud(char a)// 判断优先级
{
        if(a=='^') return 3;
    if(a=='*'||a=='/') return 2;
    if(a=='-'||a=='+') return 1;
    return 0;
}   

int jud1(char a)// 判断运算符
{
    if(a=='+'||a=='-'||a=='*'||a=='/'||a=='^') return 1;
    return 0;
}


char s;
char r;// 存储逆波兰式的结果
int k;
void ReversePolish()   // 转化成逆波兰式
{
    mem(r);
    k = 0;
    int l = strlen(s);
    stack<char>q; // 临时栈(存储运算符)
    for(int i = 0; i < l; i++){
      if(s==' ') continue;// 去掉空格干扰
      if(isdigit(s)){   // 如果是运算数
            r = s;
            while(isdigit(s)&&i+1<l){
                r = s;
                ++i;
            }
            r = ' ';   // 用空格隔开
      }
      if(s=='('){   // 左括号 直接入临时栈
            q.push(s);
      }
      if(s==')'){   // 右括号 将左右括号之间运算符放进逆波兰式中
            while(q.top()!='('){
                r = q.top();
                r = ' ';
                q.pop();
            }
            q.pop();
      }
      while(jud1(s)==1){// 运算符
            if(q.empty()||q.top()=='('||jud(s)>jud(q.top())){
                // 栈为空,栈顶为左括号,当前运算符优先级大于栈顶运算符入栈
                q.push(s);
                break;
            }else{
                // 将栈顶运算符放进逆波兰式中
                r = q.top();
                r = ' ';
                q.pop();
            }
      }
    }
    // 如果临时栈不为空,将剩余运算符放进逆波兰式中
    while(!q.empty()){
      r = q.top();
      r = ' ';
      q.pop();
    }
    cout << "Reverse Polish:";
    for(int i = 0; i < k; i++) cout << r; // 输出逆波兰式
    CE;
}

double Result()   // 计算逆波兰式
{
    stack<double>re;// 存储运算数
    for(int i = 0; i < k; i++){
      if(isdigit(r)){   // 运算数直接入栈
            double x = r-'0';
            while(r!=' '){
                x = x*10+r-'0';
            }
            re.push(x);
      }else if(jud1(r)==1){// 运算符 从栈顶取两个数运算,再将结果入栈
            double x1 = re.top();
            re.pop();
            double x2 = re.top();
            re.pop();
            // cout << x1 << " " << x2 << " " << r << endl;
            double x3 = Calculate(x1,x2,r);
            // cout << x3 << endl;
            re.push(x3);
      }
    }
    cout << "Result:";
    return re.top();
}

int main()
{   
    scanf("%s", s); // 读入一个四则运算
    ReversePolish();// 转化成逆波兰式
    double op =Result();// 计算结果
    printf("%.2lf\n", op);
    return 0;
}

zhangjinxuan 发表于 2022-11-28 14:25:25

Clamb 发表于 2022-11-28 14:17
或许得写一个大数的模拟运算?

没叫你运算,这样的话就只能运用大数读入,也麻烦不了多少

lxping 发表于 2022-11-29 19:27:14

本帖最后由 lxping 于 2022-11-29 19:30 编辑

还不会正则表达式,不然应该可以更简单匹配~~{:10_266:}
old = input("请输入计算式:")

old = old.replace("*", ")&")
old = old.replace("/", ")%")
old = old.replace("&", "*")
old = old.replace("%", "/")

templist = old.split(")")
temp = ""
for i in templist[:-1]:
    if "+" in i or "-" in i:
      i = i + ")"
      temp += i
    else:      
      temp += i
   
new = temp.count(")")*"(" + temp + templist[-1]

print(new)

高山 发表于 2022-11-29 19:30:38

lxping 发表于 2022-11-29 19:27


运行不过

lxping 发表于 2022-11-29 19:32:23

高山 发表于 2022-11-29 19:30
运行不过

python呀~~,只会这个

高山 发表于 2022-11-29 19:38:32

lxping 发表于 2022-11-29 19:32
python呀~~,只会这个

那……没办法
我是说C或C++
页: [1]
查看完整版本: 【C\C++版块提升计划】每周一练第18期:适当加括号(限免)