uva 12219 Common Subexpression Elimination

https://vjudge.net/problem/UVA-12219 

 

这道题写得极度痛苦。题都看了半天

总结一下自己遇到的坑点:

1.map<node,int>和map<*node,int>。由于需要重载<符号,map<*node,int>无法调用struct node中的<重载。

2.hash=hash*27+s[p]-'a'+1中+1是必要的,如果不加,'aa','aaa'hash值为0,冲突

#include<iostream>
#include<algorithm>
#include<queue>
#include<cmath>
#include<math.h>
#include<string>
#include<string.h>
#include<map>
#include<unordered_map>
#include<unordered_set>
#include<set>
#include<stack>
#include<sstream>
#include<assert.h>
#include<vector>
#include<cstdio>
#include<string>
#include<map>
using namespace std;


char s[1000000];
int p = 0, cnt = 0;
struct node {
	int same_idx,hash,L_dictnum,R_dictnum,dictnum;
	string s;
	node *left;
	node *right;
    //dictnum:cur cnt
    //L_dictnum:curleft cnt
    //R_dictnum:curright cnt
    //same_idx:if cur exists, find the same in the map
    //hash: help to look for
	node() :s(""), same_idx(-1), dictnum(-1),hash(0), L_dictnum(-1), R_dictnum(-1), left(NULL), right(NULL) {};
	bool operator<(const node &nd) const {
			if (hash != nd.hash)
				return hash < nd.hash;
			if (L_dictnum != nd.L_dictnum)
				return L_dictnum < nd.L_dictnum;
			return R_dictnum < nd.R_dictnum;
	}
};
map<node, int> dict;
node* dfs() {
	node* nd = new node();
	++cnt;
	int temp = cnt;
	while (isalpha(s[p])) {
		nd->s += s[p];
		nd->hash += nd->hash * 27 + s[p] - 'a' + 1;
		p++;
	}
	if (s[p] == '(') {
		p++;
		nd->left = dfs();
		if(nd->left!=NULL)
			nd->L_dictnum = nd->left->dictnum;
		p++;
		nd->right = dfs();
		if (nd->right != NULL)
			nd->R_dictnum = nd->right->dictnum;
		p++;
	}
	if (dict.count(*nd)) {
		cnt--;
		nd->same_idx = dict[*nd];
		nd->dictnum = dict[*nd];
		return nd;
	}
	dict[*nd] = temp;
	nd->dictnum = temp;
	return nd;
}
void print(node* root) {
	if (root != NULL) {
		if (root->same_idx == -1)
			cout << root->s;
		else {
			cout << root->same_idx;
			return;
		}
		if (root->left != NULL) {
			cout << '(';
			print(root->left);
			cout << ',';
		}
		if (root->right != NULL) {
			print(root->right);
			cout << ')';
		}
	}
}
int main() {
	int t;
	node nd;
	cin >> t;
	while (t--) {
		cnt = p = 0;
		dict.clear();
		scanf("%s", &s);
		node* root = dfs();
		print(root);
		cout << endl;
	}
	return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值