将每一个结点用一个三元组来表示,然后映射到map中以去重 。 其中三元组中有一个string , 我们可以用hash来处理这个string 。
因为string最大长度为4, 所以我们可以这样处理 : int hash = 0; hash = hash * 27 + s[i] - ‘0‘ + 1;
将hash每次乘以27 是因为字符串只有小写字母,这样做可以完美的去重 ,保证了哈希表不会重复
#include<bits/stdc++.h>
using namespace std;
const int maxn = 60000;
int n,m,kase,cnt,done[maxn];
char s[maxn * 5], *p;
struct node{
string s;
int hash,l,r;
bool operator < (const node & u) const {
if(hash != u.hash) return hash < u.hash;
if(l != u.l) return l < u.l;
return r < u.r;
}
}nodes[maxn];
map<node,int> dict;
int parse(){
int id=cnt++;
node & u = nodes[id];
u.l=u.r=-1;
u.s="";
u.hash=0;
while(isalpha(*p)){
u.hash=u.hash*27+*p-'a'+1;
u.s.push_back(*p);
++p;
}
if(*p=='('){
p++; u.l=parse(); p++; u.r=parse(); p++;
}
if(dict.count(u)){
id--; cnt--;
return dict[u];
}
return dict[u]=id;
}
void print(int v){
if(done[v]==kase) printf("%d",v+1);
else {
done[v]=kase;
printf("%s",nodes[v].s.c_str());
if(nodes[v].l != -1){
printf("(");
print(nodes[v].l);
printf(",");
print(nodes[v].r);
printf(")");
}
}
}
int T;
int main()
{
scanf("%d",&T);
for(kase=1;kase<=T;kase++){
dict.clear();
cnt=0;
scanf("%s",s);
p=s;
print(parse());
printf("\n");
}
return 0;
}

本文介绍了一种使用三元组表示节点并结合哈希表进行去重的算法实现。该算法通过C++代码示例展示了如何处理字符串,并利用哈希函数确保唯一性,适用于字符串长度较小的情况。
1815

被折叠的 条评论
为什么被折叠?



