CSDN第67期编程竞赛活动经验

这次题目看着不难,但是没全通过,这次提交的代码可以下下来了,可以贴代码了

题目1、正则匹配

给你一个字符串s和一个字符模式p,请你来原生实现一个支持 . 和 * 的正则表达式匹配。点号表示匹配任意字符,星号表示匹配前一项字符零个或多个。必须匹配到整个字符串,才可视为匹配成功;否则,无匹配结果或只匹配到部分字符串,视为匹配失败。

暴力求解,优先考虑完全匹配
如ac 可以匹配aac,aaaac
如a
a可以匹配 aaaaa,也可以匹配aaa,关键是处理这个*的覆盖度,尽可能满足就行
其它注意点,*也可以为空,.相对于万能牌
我这边通过率是90%

#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> 

int checkstr(const char*str1, const char*str2, int pos1, int pos2, int len1, int len2) {
    int bFindXin = 0;
    char perch = 0;
    while (pos2 < len2 && pos1 < len1) {
        char ch1 = str1[pos1];
        char ch2 = str2[pos2];
        if (ch2 == ch1) {
            if (checkstr(str1, str2, pos1 + 1, pos2 + 1, len1, len2)) {
                return 1;
            }
        }
        if (bFindXin == 1 && (ch1 == perch || perch == 0)) {
            pos1++;
        } else if (ch2 == '.') {
            pos1++;
            pos2++;
            bFindXin = 0;
            perch = 0;
        } else if (ch2 == '*') {
            pos1++;
            pos2++;
            bFindXin = 1;
        } else if (ch2 == ch1) {
            pos1++;
            pos2++;
            perch = ch1;
            bFindXin = 0;
        } else {
            return 0;
        }
    }
    if (pos2 == len2 || (pos2 == len2 - 1 && str2[len2 - 1] == '*')) {
        if (pos1 == len1 || bFindXin == 1) {
            return 1;
        } else {
            return 0;
        }
    } else {
        return 0;
    }
    return 0;
}

int main() {
    char str1[10240] = {0};
    char str2[10240] = {0};
    scanf(" %s", str1);
    scanf(" %s", str2);
    int len1 = strlen(str1);
    int len2 = strlen(str2);
    int pos1 = 0;
    int pos2 = 0;
    int ret = checkstr(str1, str2, pos1, pos2, len1, len2);
    if (ret) {
        printf("true");
    } else {
        printf("false");
    }
    return 0;
}

题目2、生命进化书

小A有一本生命进化书,以一个树形结构记载了所有生物的演化过程。为了探索和记录其中的演化规律,小A提出了一种方法,可以以字符串的形式将其复刻下来,规则如下:初始只有一个根节点,表示演化的起点,依次记录01字符串中的字符,如果记录0,则在当前节点下添加一个子节点,并将指针指向新添加的子节点;否则,将指针回退到当前节点的父节点处。现在需要应用上述的记录方法,复刻下它的演化过程。请返回能够复刻演化过程的字符串中,字典序最小的01字符串;注意:节点指针最终可以停在任何节点上,不一定要回到根节点。

把树画出来也就是树的深度优先遍历,
先遍历最长的(前面0多)
有相同的就遍历下一层子孩子最多的(这里可能有问题,估计就这而造成没全过,情况比较复杂)
想想,所有遍历情况都打印出来比较应该也就行了

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

typedef struct _TREE {
    int pid;
    int localdeep; //自己的深度 

    int maxcdeep; //最大的子深度 
    int bUsed;
    int cids[1024]; //子孩子遍历 
    int cnum;
    int bFind;
} TREE;
int bFindnum = 0;
int maxid = 0;

int max(int a, int b) {
    return a > b ? a : b;
}
//更新父中子孩子的最大深度 

int UpdatePDeep(TREE*datas, int cid) {
    int pid = datas[cid].pid;
    if (pid == -1) {
        return 0;
    }
    datas[pid].maxcdeep = max(datas[pid].maxcdeep, datas[cid].maxcdeep);
    return UpdatePDeep(datas, pid);
}
//查找子中最高的 

int FindMax(TREE*datas, int*cids, int cnum) {
    int id = -1;
    int maxcdeep = -1;
    int checknum = -1;
    //printf("%d %d\n",id,cnum); 
    for (int i = 0; i < cnum; i++) {
        int cid = cids[i];
        if (datas[cid].bFind) {
            continue;
        }
        if (datas[cid].maxcdeep > maxcdeep) {
            id = cid;
            maxcdeep = datas[cid].maxcdeep;
            checknum = datas[cid].cnum;
        } else if (datas[cid].maxcdeep == maxcdeep && datas[cid].cnum > checknum) {
            id = cid;
            maxcdeep = datas[cid].maxcdeep;
            checknum = datas[cid].cnum;
        }
    }
    return id;
}

int showtree(TREE*datas) {
    int id = 0;
    while (datas[id].bUsed) {
        printf("id:%d pid:%d deep:%d mdeep:%d\n", id, datas[id].pid, datas[id].localdeep, datas[id].maxcdeep);
        id++;
    }
    return 0;
}

int looptree(TREE*datas, int id) {
    if (id != 0) {
        printf("0");
    }
    int cid = -1;
    while ((cid = FindMax(datas, datas[id].cids, datas[id].cnum)) != -1) {
        bFindnum++;
        datas[cid].bFind = 1;
        looptree(datas, cid);
    }
    //printf("\nid:%d %d %d\n",id,bFindnum,maxid); 
    //if(id!=0 && (bFindnum+1)!=maxid){ 
    if ((bFindnum + 1) != maxid) {
        printf("1");
    }
    return 0;
}

int main() {
    TREE data[1024] = {0};
    memset(data, 0, sizeof (TREE)*1024);
    char buff[128] = {0};
    int pos = 0;
    char ch = 0;
    int id = 0;
    while ((ch = getchar()) != -1) {
        if (ch == '[') {
            continue;
        }
        if (ch == ',' || ch == ']') {
            int pid = atoi(buff);
            data[id].pid = pid;
            data[id].bUsed = 1;
            if (pid != -1) {
                data[pid].cids[data[pid].cnum++] = id;
                data[id].localdeep = data[pid].localdeep + 1;
                data[id].maxcdeep = data[id].localdeep;
                UpdatePDeep(data, id);
            }
            id++;
            pos = 0;
            memset(buff, 0, sizeof (buff));
            continue;
        }
        if (ch == ']') {
            break;
        }
        buff[pos++] = ch;
    }
    maxid = id;
    //showtree(data); 
    looptree(data, 0);
    return 0;
}```

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值