三进制枚举子集+后缀表达式

Leetcode
在这里插入图片描述

把这题魔改一下,每个数字中间必须插入运算符,求最后符合条件的表达式。

#include <bits/stdc++.h>
using namespace std;
class Solution {
 public:
  unordered_map<char, int> pty;
  Solution() {
    pty['+'] = pty['-'] = 0;
    pty['*'] = 1;
  }
  ~Solution() { pty.clear(); }

  int pow3(int b) {
    int ans = 1, a = 3;
    while (b) {
      if (b & 1) {
        ans *= a;
      }
      b >>= 1;
      a *= a;
    }
    return ans;
  }

  int Log3(int nums) {
    int ans = 1, i = 0;
    for (; ans <= nums; i++) {
      ans *= 3;
    }
    return i - 1;
  }

  void ST(vector<int>& st, int nums) {
    for (auto& x : st)
      x = 0;
    int ans = 0;
    while (nums > 0) {
      int f = Log3(nums);
      st[f]++;
      nums -= pow3(f);
    }
  }

  void Slove(string& bds, vector<char>& sta) {
    stack<char> hz;
    int i = 0;
    for (auto& ch : bds) {
      if (ch != '+' && ch != '-' && ch != '*') {
        sta[i++] = ch;
      } else {
        if (hz.empty()) {
          hz.push(ch);
        } else {
          while (!hz.empty() && pty[ch] <= pty[hz.top()]) {
            sta[i++] = hz.top();
            hz.pop();
          }
          hz.push(ch);
        }
      }
    }
    while (!hz.empty()) {
      sta[i++] = hz.top();
      hz.pop();
    }
  }

  int Getans(vector<char>& sta) {
    stack<int> hz;
    for (auto& ch : sta) {
      if (ch != '+' && ch != '-' && ch != '*') {
        hz.push(ch - '0');
      } else {
        int x = hz.top();
        hz.pop();
        int y = hz.top();
        hz.pop();
        switch (ch) {
          case '+':
            hz.push(y + x);
            break;
          case '-':
            hz.push(y - x);
            break;
          case '*':
            hz.push(y * x);
            break;
        }
      }
    }
    return hz.top();
  }

  vector<string> addOperators(string num, int target) {
    int n = num.size() - 1;
    vector<int> st(n, 0);
    int b = pow3(n);

    vector<string> bds;
    vector<char> sta((n + 1) * 2 - 1, 0);
    for (int i = 0; i < b; i++) {
      ST(st, i);
      string ans;
      ans += num[0];
      for (int j = 0; j < n; j++) {
        if (st[j] < 0 || st[j] > 2) {
          cout << i << endl;
        }
        switch (st[j]) {
          case 0:
            ans += '-';
            break;
          case 1:
            ans += '+';
            break;
          case 2:
            ans += '*';
            break;
        }
        ans += num[j + 1];
      }
      Slove(ans, sta);
      if (Getans(sta) == target) {
        bds.push_back(ans);
      }
    }
    return bds;
  }
};

int main() {
  /*Test数据,数据范围(1-10)*/
  Solution slu;
  string bds = "1234567897";
  int target = 25;
  vector<string> result = slu.addOperators(bds, target);
  vector<char> _container(19, 0);
  for (auto& bds : result) {
    slu.Slove(bds, _container);
    cout << bds << ' ' << slu.Getans(_container) << endl;
  }
  return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值