※上記の広告は60日以上更新のないWIKIに表示されています。更新することで広告が下部へ移動します。

1244 Molecular Formula

http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1244
簡略化された原子の重さと化学式が与えられるので化学式の重さの総計を答える問題。

再帰下降構文解析で解きます。
英文字がきたら、2文字読めるか1文字読めるか試します。
その次が数字ならその数字分重さを掛けて、数字でないなら重さを単純に足します。
開きカッコがきたら関数を読んでネスト、閉じかっこか文字列の終わりに到達したら関数はリターンします。


#include<stdio.h>
#include<map>
#include<string>
#include<iostream>
std::map<std::string,int> memo;
int p;
std::string A,text;//原子の種類
bool allOK;
long long int saiki(){
std::string str1="",str2="";
char c;
long long int bai=0,tAns=0,m=0;
bool isDegit=false;
while(p<=text.length()&&allOK==true){
	c=text[p];
	if('0'<=c&&c<='9'){
		bai=bai*10+c-'0';
		isDegit=true;
	}else if(isDegit==true){
		tAns=tAns+m*(bai==0?1:bai);
		bai=0;
		isDegit=false;
	}
	if(c=='('){
		bai=0;
		p++;
		m=saiki();
		isDegit=true;
	}else if(c==')' || c=='\0'){
		return tAns;
	}else if(!('0'<=c&&c<='9')){
		str1=c;
		str2=c;
		m=-1;
		bai=0;
		if(p<text.length()-1){
			str2+=text[p+1];
			if(memo.find(str2)!=memo.end()){
				m=memo[str2];
				p++;
				isDegit=true;
			}else if(memo.find(str1)!=memo.end()){
				m=memo[str1];
				isDegit=true;
			}
		}else if(memo.find(str1)!=memo.end()){
			m=memo[str1];
			isDegit=true;
		}
		if(m==-1)allOK=false;
	}
	if(p<text.length())p++;
}
return tAns;
}
int main(){

int m;//重さ
while(1){
	std::cin>>A;
	if(A=="END_OF_FIRST_PART")break;
	std::cin>>m;
	memo[A]=m;
}
while(1){
	std::cin>>text;
	if(text=="0")break;
	p=0,allOK=true;
	long long int ans=saiki();
	if(allOK==false)std::cout<<"UNKNOWN\n";
	else std::cout<<ans<<"\n";
}
}