华为OD机试 - 字符串化繁为简 (c++并查集)

 

#include <iostream>
#include <vector>
#include <deque>
#include <string>
using namespace std;

// 定义并查集类
class UnionFindSet {
public:
    vector<int> fa; // 存储每个节点的父节点
    int count; // 当前连通块的数量

    UnionFindSet(int n) : count(n) { // 构造函数,初始化父节点为自身
        fa.resize(n);
        for (int i = 0; i < n; i++) fa[i] = i;
    }

    int find(int x,int mnum) { // 查找节点的根节点
        if (x != fa[x]) {
            fa[x] = find(fa[x],min(mnum,fa[x])); // 路径压缩
        }
        fa[x]=min(mnum,fa[x]);
        return fa[x];
    }

    void unionSet(int x, int y) { // 合并两个节点所在的连通块
        int x_fa = find(x,fa[x]);
        int y_fa = find(y,fa[y]);

        if (x_fa != y_fa) { // 如果两个节点不在同一个连通块中,则合并
            
            fa[max(x_fa,y_fa)] = min(x_fa,y_fa); // 将y所在的连通块合并到x所在的连通块中
            count--; // 连通块数量减1
        }
    }
};

int main() {
    
    UnionFindSet s(150);
    vector<int> is(150,0); 
    string str;
    deque<int> q1,q2;
    cin >> str;
    int temp=0;
    for(char c:str){
        if(c=='('){
            temp=1;
        }
        else if(c==')'){
            temp=0;
            int i;
            if(!q2.empty()){
                i=q2.front();
            }
            while(!q2.empty()){
                s.unionSet(i, q2.front());
                is[q2.front()]=1;
                if(q2.front()>='a'){
                    if(is[q2.front()-'a'+'A']==1)
                        s.unionSet(q2.front()-'a'+'A', q2.front());
                    
                }
                else{
                    if(is[q2.front()+'a'-'A']==1)
                        s.unionSet(q2.front()+'a'-'A', q2.front());
                }
                q2.pop_front();
            }
        }
        else if(temp==0){
            q1.push_back(c);
        }
        else{
            q2.push_back(c);
        }
    }
    if(q1.empty())
        cout <<0;
    while(!q1.empty()){
        
        cout << char(s.find(q1.front(),q1.front()));
        q1.pop_front();
    }
    
    return 0;
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值