C语言 单链表 RE问题

题目
Description
给定n个括号序列,两两配对,问最多能组成多少对合法括号序列。(每一个括号序列只能在一对中出现)
Input
第一行输入整数 表示有 n个括号序列。
接下来 n行,每行输入一个只由“(”和”)“构成的字符串Si 。(字符串长度满足1<|Si|<1e5)
Output
输出一个整数,表示最大的合法括号序列对数。

相关内容我也放在了以下链接,便于您更好的观看
详细描述

代码

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
typedef long long int lli;
typedef struct Str{
    char arr[200000];
    lli left;
    lli right;
    struct Str *next;
}str;
//基本思路:使用链表储存字符串,链表为空时往里插结点,否则就用新的信息与链表内各节点比较
//先判断左右括号合起来是否相等(不等则肯定不成立)
//然后将两个字符串拼接(有两个顺序都要考虑)存左括号,遇到右括号弹出;
 
lli getl(char a[]){
    lli result=0;
    for(int i=0;i<strlen(a);i++){
        if(a[i]=='('){
            result++;
        }
    }
    return result;
}
 
lli getr(char a[]){
    lli result=0;
    for(int i=0;i<strlen(a);i++){
        if(a[i]==')'){
            result++;
        }
    }
    return result;
}
 
void reset(str *head,str *p){//重置尾结点
    p=head;
    while(p->next!=NULL){
        p=p->next;
    }
}
 
void getout(str *head,str *p){//脱开某个结点
    str *q=head;
    while(q->next!=p){
        q=q->next;
    }//停在q->next=p这,即q为p前一节点
    q->next=p->next;
    free(p);
}
 
int main(){
    lli result=0;
    lli n=0;
    scanf("%lld",&n);
    getchar();//吃空格
    //头指针
    str *head=(str*)malloc(sizeof(str));
    head->next=NULL;
    str *tail=head;//尾结点
    //读入后续结点
    for(lli i=1;i<=n;i++){
        //前置处理
        str *curr=(str*)malloc(sizeof(str));
        gets(curr->arr);
        curr->left=getl(curr->arr);
        curr->right=getr(curr->arr);
        //对于可能为第一个结点而言
        if(tail==head){//如果尾结点为头结点
            head->next=curr;
            curr->next=NULL;
            tail=tail->next;//尾结点指向curr
        }
        else{
            str *place=head->next;//走链表的指针
            int pp=0;//匹配状态
            while(place!=NULL){//脱出条件:走完全链表
                if(place->left+curr->left!=place->right+curr->right){//括号数量不匹配
                    place=place->next;
                }
                else{//括号匹配
                    char *cfront=strcat(curr->arr,place->arr);
                    lli lbox=0;
                    int status=1;
                    for(lli i=0;i<strlen(cfront);i++){
                        if(cfront[i]=='('){
                            lbox++;
                        }
                        else if(cfront[i]==')'){
                            if(lbox>0){
                                lbox--;
                            }
                            else{
                                status=0;
                                break;
                            }
                        }
                    }
                    if(status&&lbox==0){//匹配成功
                        result++;
                        pp=1;
                        getout(head,place);//断开place结点
                        free(curr);
                        reset(head,tail);//重置tail结点至尾结点
                        break;
                    }
                    char *cback=strcat(place->arr,curr->arr);
                    lbox=0;                    
                    status=1;
                    for(lli i=0;i<strlen(cback);i++){
                        if(cback[i]=='('){
                            lbox++;
                        }
                        else if(cback[i]==')'){
                            if(lbox>0){
                                lbox--;
                            }
                            else{
                                status=0;
                                break;
                            }
                        }
                    }
                    if(status&&lbox==0){//匹配成功
                        result++;
                        pp=1;
                        getout(head,place);//断开place结点
                        free(curr);
                        reset(head,tail);//重置tail结点至尾结点
                        break;
                    }
                    else{
                        place=place->next;
                    }
                }
            }
            if(pp==0){//走完,没有匹配的,加到链表尾端
                tail->next=curr;
                curr->next=NULL;
                tail=tail->next;
            }
        }    
    }
    printf("%lld\n",result);
}

结果是这样的:

img

束手无策了……

【以下回答由 GPT 生成】

对于给定的n个括号序列,你想要找出最多能组成多少对合法括号序列的问题。在这个问题中,每个括号序列只能在一对中出现。你想要一个具体的解决方案,并展示相关的代码。

我可以提供一个解决方案来解决这个问题。首先,我们可以使用一个单链表来存储括号序列。在链表中,每个节点将表示一个括号序列,同时还存储左括号和右括号的数量。

以下是一个基本的解决方案的代码:

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

typedef struct Node {
    char str[100];
    int left;
    int right;
    struct Node* next;
} Node;

int main() {
    int n;
    scanf("%d", &n);

    Node* head = NULL;
    Node* current = NULL;

    for (int i = 0; i < n; i++) {
        char str[100];
        scanf("%s", str);

        int left = 0;
        int right = 0;

        for (int j = 0; j < strlen(str); j++) {
            if (str[j] == '(') {
                left++;
            }
            else if (str[j] == ')') {
                if (left > 0) {
                    left--;
                }
                else {
                    right++;
                }
            }
        }

        if (head == NULL) {
            head = (Node*)malloc(sizeof(Node));
            current = head;
        }
        else {
            current->next = (Node*)malloc(sizeof(Node));
            current = current->next;
        }

        strcpy(current->str, str);
        current->left = left;
        current->right = right;
        current->next = NULL;
    }

    int pairCount = 0;

    current = head;

    while (current != NULL) {
        Node* temp = current->next;

        if (current->left == 0 && current->right == 0) {
            pairCount++;
            free(current);
        }

        current = temp;
    }

    printf("最大的合法括号序列对数: %d", pairCount);

    return 0;
}

这个解决方案使用一个头节点表示整个链表,并使用current指针来跟踪当前节点。在循环中,我们将输入的括号序列进行检查,计算左括号和右括号的数量。然后,我们创建一个新的节点,并将括号序列以及左右括号的数量存储在节点中。最后,我们遍历链表,计算符合要求的配对数并释放相应的节点。

希望这个解决方案对你有帮助!如果你有任何其他问题,请随时问我。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^