日々精進

aikoと旅行とプログラミング

【AOJ 1346】Miscalculation

問題

Miscalculation | Aizu Online Judge

方針

  • ルール1は通常の優先順位(乗算→加算)で演算する.
  • ルール2は左から順番に計算する.
  • ルール1とルール2の結果が等しく, 入力した数字とも等しければU
  • ルール1が入力した数字と等しければM, ルール2と等しければL, それ以外はIを出力する.

コード

#include<cctype>
#include<iostream>

using namespace std;

typedef string::const_iterator State;

int number(State &begin){
  int ret = *begin - '0';
  begin++;
  return ret;
}

int term(State &begin){
  int ret = number(begin);
  
  while(true){
    if(*begin == '*'){
      begin++;
      ret *= number(begin);
    }else{
      break;
    }
  }

  return ret;
}

int expression(State &begin){
  int ret = term(begin);

  while(true){
    if(*begin == '+'){
      begin++;
      ret += term(begin);
    }else{
      break;
    }
  }

  return ret;
}

int rule2(string s){
  State begin = s.begin();
  int ret = *begin - '0';
  begin++;
  
  while(begin != s.end()){
    if(*begin == '+'){
      begin++;
      ret += *begin - '0';
    }else{
      begin++;
      ret *= *begin - '0';      
    }
    begin++;
  }

  return ret;
}

signed main(){
  string s;
  int n;
  int ans1, ans2;

  cin >> s;
  cin >> n;
  
  State begin = s.begin();
  ans1 = expression(begin);
  ans2 = rule2(s);
  
  if(ans1 == ans2 && ans1 == n){
    cout << "U" << endl;
  }else if(ans1 == n){
    cout << "M" << endl;
  }else if(ans2 == n){
    cout << "L" << endl;
  }else{
    cout << "I" << endl;
  }
  
}

参考

構文解析の部分は以下の記事を参考にしました.
構文解析 Howto · GitHub
これでAOJ-ICPCの200が全部埋まりましたー, やったー!