qq_48889095 2024-03-29 00:06 采纳率: 100%
浏览 18
已结题

求差集那个函数有问题,有无佬可以解决

img


如上图所示,正确输出应该为gh,但却输出了空集

img


这个也是

img


但这样却可以正常输出

差集部分的代码如下

Node *difference(Node *L1,Node *L2){
    int k=0;
    for(int i=0;i<L1->length;i++){
        int j=0;
        while(j<L2->length){
            if(L1->str[i]==L2->str[j]){
             for(k;k<L1->length-1;k++){
                 L1->str[k]=L1->str[k+1];
             }
             L1->length--;
             i--;
             break;
                }
            j++;
        }
        //printf("%c\n",L1->str[i]);
    }
return L1;
}

完整代码如下


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <malloc.h>
#define MaxSize 100
typedef struct node{
    char *str;//存储空间基址 
    int length;//当前长度 
}Node;

void deletewrong(Node *L){//删除顺序表中重复的字符和错误的字符 
    for(int i=0;i<L->length;i++){//遍历顺序表 
        if(L->str[i]<'a'||L->str[i]>'z'){//如果为错误字符 
            for(int k=i;k<L->length;k++){//删除该字符(让当前位置之后的元素全都前移) 
                L->str[k]=L->str[k+1];
            }
            L->length--;//长度减一 
            i--; //让当前下标指向覆盖了刚刚删除的字符的元素 
        }
    }
    for(int i=0;i<L->length-1;i++){//遍历顺序表 
        char k=L->str[i];//固定字符 
        for(int j=i+1;j<L->length;j++){//遍历后面的字符 
            if(L->str[j]==k){//如果有相同的字符 
                for(int l=j;l<L->length;l++){//将第三个开始后面的字符全部往前移动,覆盖掉重复的字符 
                    L->str[l]=L->str[l+1];
                }
                L->length--;//长度减一 
                j--;//将下标重新定位到新字符(即被删除了的字符的下标)重新判断 
            }
        }
        
    }
}
void input(Node *L){        //输入顺序表 
    int i=0;
    if(!L->str)exit(-1);    //空间分配失败
    char ch=getchar();
    do                        //以回车键为标志的循环输入  
    {
        L->str[i++]=ch;
        ch=getchar();
    }while(ch!='\n');
    L->length=i;             //保存顺序表长度 
    deletewrong(L);            //删除顺序表重复及错误的字符 
}

void print(Node *L){        //打印顺序表 
    printf("集合={");
    for(int i=0;i<L->length;i++)//用一个循环打印 
    printf("%c",L->str[i]);
    printf("}\n");
}

Node* unioncharacter(Node *L1,Node *L2){//求两个顺序表集合的并集 
    int i=L1->length,j=0; 
    L1->length+=L2->length; 
    for(i,j;i<L1->length;i++,j++){//以L1作为头表,将L1、L2的字符都放入L1中
        L1->str[i]=L2->str[j];
    }
    deletewrong(L1);//删除L1表中重复的字符 
    return L1;
}
Node *intersection(Node *L1,Node *L2){//求两顺序表集合的交集 
    int k=0,j=0,i=0;
    for(int i=0;i<L1->length;i++){//从第一个字符开始,遍历L1 
        for(int j=0;j<L2->length;j++){//遍历L2,查找有无与L1相同的字符 
            if(L1->str[i]==L2->str[j]){ 
                L1->str[k++]=L1->str[i];//若有将该字符在L1中留下,并按下标从0开始的顺序保存 
                break;//退出循环 
            }
        }
    }
    L1->length=k;//更新L1的长度 
    return L1;
}
Node *difference(Node *L1,Node *L2){
    int k=0;
    for(int i=0;i<L1->length;i++){
        int j=0;
        while(j<L2->length){
            if(L1->str[i]==L2->str[j]){
             for(k;k<L1->length-1;k++){
                 L1->str[k]=L1->str[k+1];
             }
             L1->length--;
             i--;
             break;
                }
            j++;
        }
        //printf("%c\n",L1->str[i]);
    }
return L1;
}

Node *complement(Node *Li,Node *L){
    int k=0;
    char p='a';
    while(p>='a'&&p<='z'){
        int i=0,c=1;
        while(i<Li->length){
            if(p!=Li->str[i]){
                i++;
            }
            else{
                c=0;
                break;
            }
        }
        if(c==1){
            L->str[k++]=p;
        }
        p++;
    }
    L->length=k;
    return L; 
}
int main(){
    char number;
    Node *L1=new Node;
    Node *L2=new Node;
    Node *L=new Node;
    L1->str=(char*)calloc(MaxSize,sizeof(char));
    L2->str=(char*)calloc(MaxSize,sizeof(char));
    L->str=(char*)calloc(MaxSize,sizeof(char));
    L->length=0;
    while(1){
        printf("------------请输入命令------------\n");
        printf("1.表示输入的集合   ");
        printf("2.求并集   ");
        printf("3.求交集   ");
        printf("4.求差集(L1-L2)   ");
        printf("5.求补集   ");
        printf("6.退出\n");
    scanf("%d",&number);
    if(number>6||number<1){
        printf("命令错误!请重新输入 \n");
    }
    switch(number){
        case 1:
            printf("请输入字符集合:\n");
            input(L1);
            print(L1);
            break;
        case 2:
            printf("请输入字符集合L1:\n");
            input(L1);
            printf("请输入字符集合L2:\n");
            input(L2);
            print(unioncharacter(L1,L2));
            break;
        case 3:
            printf("请输入字符集合L1:\n");
            input(L1);
            printf("请输入字符集合L2:\n");
            input(L2);
            print(intersection(L1,L2));
            break;
        case 4:
            printf("请输入字符集合L1:\n");
            input(L1);
            printf("请输入字符集合L2:\n");
            input(L2);
            print(difference(L1,L2));
            break;
        case 5:
            printf("请输入字符集合L1:\n");
            input(L1);
            print(complement(L1,L2));
            break;
        case 6:
            printf("退出成功!\n");
            exit(-1);
    }
    }
    free(L1->str);
    L1->str=NULL;
    free(L2->str);
    L2->str=NULL;
    free(L1);
    L1=NULL;
    free(L2);
    L2=NULL;
    free(L->str);
    L->str=NULL;
    free(L);
    L=NULL;
    return 0;
}
  • 写回答

14条回答 默认 最新

  • bug菌¹ Java领域优质创作者 2024-03-29 10:30
    关注

    该回答引用ChatGPT,望对题主有所帮助/启发;若有帮助,还望采纳🤝🤝🤝


    您的差集函数 difference 的逻辑存在一些问题,导致在删除字符时出现了错误的循环和数组更新。以下是您的差集函数中存在的问题以及修正建议:

    存在的问题:

    1. 当找到一个在两个集合中都存在的字符时,您应该只移动后面的字符一次,而不是每次发现相同的字符就移动。
    2. 您的 for 循环中的 k 变量没有正确初始化,这可能会导致数组越界。
    3. 在删除字符后,您应该只减少 L1->length 而不是同时减少 i 的值,因为 i 的值在循环中用于跟踪当前位置。

    修正建议:

    以下是修正后的差集函数 difference

    Node *difference(Node *L1, Node *L2) {
        int i, j;
        for (i = 0; i < L1->length;) { // 外层循环遍历L1中的字符
            for (j = 0; j < L2->length; j++) { // 内层循环遍历L2中的字符
                if (L1->str[i] == L2->str[j]) {
                    // 找到相同的字符,将其从L1中删除
                    for (int k = i; k < L1->length - 1; k++) {
                        L1->str[k] = L1->str[k + 1];
                    }
                    L1->length--; // 减少L1的长度
                    break; // 跳出内层循环,继续检查L1中的下一个字符
                }
            }
            if (j < L2->length) { // 如果内层循环是因为找到字符而结束的,继续外层循环
                i++;
            }
        }
        return L1;
    }
    

    在这个修正版本中,我们使用一个额外的 if 条件来检查内层循环是否是因为找到了相同的字符而结束的。如果是这样,我们才增加 i 的值继续外层循环。这样可以确保在删除字符后,i 能够正确地指向下一个要检查的字符。

    请注意,这个修正假设 L1L2 都是有效的 Node 结构体,并且它们的 str 成员已经正确分配了内存。在实际使用中,您应该确保在调用 difference 函数之前,L1L2 都是有效的并且已经初始化。

    此外,您的 main 函数中创建 Node 结构体的方式也存在问题。您应该使用 malloc 来分配内存,而不是 calloccalloc 会将内存初始化为零,这可能会导致 str 指针为 NULL。以下是修正后的内存分配代码:

    L1->str = (char*)malloc(MaxSize * sizeof(char));
    L2->str = (char*)malloc(MaxSize * sizeof(char));
    L->str = (char*)malloc(MaxSize * sizeof(char));
    if (!L1->str || !L2->str || !L->str) {
        exit(-1); // 空间分配失败
    }
    

    确保在使用完内存后释放它,以避免内存泄漏。在您的 main 函数的最后,您已经正确地释放了所有分配的内存。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(13条)

报告相同问题?

问题事件

  • 系统已结题 4月6日
  • 已采纳回答 3月29日
  • 修改了问题 3月29日
  • 修改了问题 3月29日
  • 展开全部

悬赏问题

  • ¥170 如图所示配置eNSP
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改
  • ¥20 wireshark抓不到vlan
  • ¥20 关于#stm32#的问题:需要指导自动酸碱滴定仪的原理图程序代码及仿真
  • ¥20 设计一款异域新娘的视频相亲软件需要哪些技术支持
  • ¥15 stata安慰剂检验作图但是真实值不出现在图上
  • ¥15 c程序不知道为什么得不到结果
  • ¥15 键盘指令混乱情况下的启动盘系统重装