鱼C论坛

 找回密码
 立即注册
查看: 2589|回复: 19

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

[复制链接]
发表于 2022-11-27 20:36:43 | 显示全部楼层 |阅读模式
5鱼币
每周一练 第18期 适当加括号
作者
作者介绍
本帖作者:每周一练@tommyyu 自由投稿
原稿:https://fishc.com.cn/forum.php?m ... =221250&pid=6062618
声明内容
版权声明:转载于@dolly_yos2 (点此查看原稿
免责声明:本帖由“本帖作者”栏目的作者投稿,任何违规行为每周一练机构没有任何责任!!!
自由投稿:请前往 https://fishc.com.cn/thread-221250-1-1.html

                               
登录/注册后可看大图

题目
编写一个程序,在不改变算式的基础上,使这个程序对输入的算式的适当的地方加上括号,改变这个算式的运算顺序,以让这个算式能够从左往右逐步计算,且添加括号的数目尽可能少。只需要添加英文半角小括号这一种括号。
输入输出格式
输入:一个不带空格的算式,比如1*2*3*4,其中只有加、减、乘、除四种运算,分别用+、-、*、/四个符号来表示
输入输出样例
样例一:
输入
1+2+3*4
输出
(1+2+3)*4
样例二:
输入
7+8*9+10
输出
(7+8)*9+10
数据范围
输入的长度小于等于100 。

题解
游客,如果您要查看本帖隐藏内容请回复

代码:
游客,如果您要查看本帖隐藏内容请回复

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



最佳答案
2022-11-27 20:36:44
本帖最后由 zhangjinxuan 于 2022-11-27 21:23 编辑

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

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

最佳答案

评分

参与人数 1鱼币 +5 收起 理由
zhangjinxuan + 5 无条件支持楼主!

查看全部评分

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-11-27 20:36:44 | 显示全部楼层    本楼为最佳答案   
本帖最后由 zhangjinxuan 于 2022-11-27 21:23 编辑

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

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

点评

不错的啊  发表于 2022-11-28 18:22
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2022-11-27 20:36:44 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-11-27 21:01:15 | 显示全部楼层
其实我有答案,就交给别人回答吧^_^
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-11-27 21:07:46 | 显示全部楼层
回复看看答案
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-11-28 05:17:31 | 显示全部楼层
回去睡觉啦,白天再看
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-11-28 08:00:39 | 显示全部楼层
还忘了一个!数字确定不会爆 int,题目要说出来啊,意思是,数字的大小最大是多少,最小是多少?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-11-28 08:01:34 | 显示全部楼层
就是说我们输入一个 11111111111111111+2222222222222222222222222222222 之类的算式我们是不是就歇菜了?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-11-28 14:17:33 | 显示全部楼层
这......
提供个思路吧:
将从左到右运算优先级小的加括号
可以考虑用树

点评

我也没办法 你问rommyyu  发表于 2022-11-28 20:22
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-11-28 14:17:41 | 显示全部楼层
zhangjinxuan 发表于 2022-11-28 08:01
就是说我们输入一个 11111111111111111+2222222222222222222222222222222 之类的算式我们是不是就歇菜了?{ ...

或许得写一个大数的模拟运算?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-11-28 14:20:56 | 显示全部楼层
瞧瞧摸出我的逆波兰板子
#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[500];
char r[500];  // 存储逆波兰式的结果
int k;
void ReversePolish()   // 转化成逆波兰式
{
    mem(r);
    k = 0;
    int l = strlen(s);
    stack<char>q; // 临时栈(存储运算符)
    for(int i = 0; i < l; i++){
        if(s[i]==' ') continue;  // 去掉空格干扰
        if(isdigit(s[i])){   // 如果是运算数
            r[k++] = s[i];
            while(isdigit(s[i+1])&&i+1<l){
                r[k++] = s[i+1];
                ++i;
            }
            r[k++] = ' ';   // 用空格隔开
        }
        if(s[i]=='('){   // 左括号 直接入临时栈
            q.push(s[i]);
        }
        if(s[i]==')'){   // 右括号 将左右括号之间运算符放进逆波兰式中
            while(q.top()!='('){
                r[k++] = q.top();
                r[k++] = ' ';
                q.pop();
            }
            q.pop();
        } 
        while(jud1(s[i])==1){  // 运算符
            if(q.empty()||q.top()=='('||jud(s[i])>jud(q.top())){  
                // 栈为空,栈顶为左括号,当前运算符优先级大于栈顶运算符入栈
                q.push(s[i]);
                break;
            }else{
                // 将栈顶运算符放进逆波兰式中
                r[k++] = q.top();
                r[k++] = ' ';
                q.pop();
            }
        }
    }
    // 如果临时栈不为空,将剩余运算符放进逆波兰式中
    while(!q.empty()){
        r[k++] = q.top();
        r[k++] = ' ';
        q.pop();
    }
    cout << "Reverse Polish:";
    for(int i = 0; i < k; i++) cout << r[i]; // 输出逆波兰式
    CE;
}

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

点评

代码效率不是很好。  发表于 2022-11-28 20:23

评分

参与人数 1贡献 +2 收起 理由
高山 + 2 感谢楼主无私奉献!

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-11-28 14:25:25 | 显示全部楼层
Clamb 发表于 2022-11-28 14:17
或许得写一个大数的模拟运算?

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

点评

我很赞同!: 5.0
我很赞同!: 5
可以!!!  发表于 2022-11-28 18:18
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-11-29 19:27:14 | 显示全部楼层
本帖最后由 lxping 于 2022-11-29 19:30 编辑

还不会正则表达式,不然应该可以更简单匹配~~
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)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2022-11-29 19:30:38 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-11-29 19:32:23 | 显示全部楼层

python呀~~,只会这个
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2022-11-29 19:38:32 | 显示全部楼层
lxping 发表于 2022-11-29 19:32
python呀~~,只会这个

那……没办法
我是说C或C++
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-26 09:59

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表