以下是将数组B
中的唯一元素合并到数组A
的代码。
例如:
输入:A={1, 3, 5, 7, 9}
,B={2, 4, 6, 9}
输出:A={1, 2, 3, 4, 5, 6, 7, 9}
但我在第46行遇到了分段错误。我假设它是数组绑定问题,但无法弄明白。有任何想法吗?
#include <stdio.h>
#define MAXSIZE 100
typedef int ElemType;
typedef struct{
ElemType data[MAXSIZE];
int length;
}SqList;
void CreateList(SqList *L, int n){
L->length=n;
printf("\ninput %d data: ", n);
int i;
for(i=0;i<n;i++)
scanf("%d", &L->data[i]);
}
void PrintList(SqList *L){
int i;
int n;
n=L->length;
printf("\noutput %d data: ", n);
for(i=0;i<n;i++)
printf("%d", L->data[i]);
}
ElemType GetElem(SqList *L,int i){
return L->data[i];
}
int LocateElem(SqList *L, ElemType e){
int i;
for(i=1;i<=L->length;i++){
if(L->data[i]==e){
return i;
break;
}
else return 0;
}
}
void ListInsert(SqList *L, ElemType e){
int n = L->length;
n++;
L->length=n;
L->data[n]=e; // Segmentation Fault Here !
}
void merge(SqList *La, SqList *Lb){
int i;
ElemType e;
for(i=0;i<Lb->length;i++){
e=GetElem(&Lb,i);
if(!LocateElem(&La,e))
ListInsert(&La,e);
}
}
int main(){
SqList La,Lb;
int n1,n2;
printf("\nInput number for La: ");
scanf("%d",&n1);
CreateList(&La,n1);
printf("\nInput number for Lb: ");
scanf("%d",&n2);
CreateList(&Lb,n2);
printf("Here is La:\n");
PrintList(&La);
printf("Here is Lb:\n");
PrintList(&Lb);
merge(&La,&Lb);
printf("Here is merged list:\n");
PrintList(&La);
return 0;
}
答案 0 :(得分:2)
您在&
代码
merge
void merge(SqList *La, SqList *Lb){
int i;
ElemType e;
for(i=0;i<Lb->length;i++){
e=GetElem(Lb,i);
if(!LocateElem(La,e))
ListInsert(La,e);
}
}
然后它不是段错误,但是我没有检查“逻辑”是否正确(我想它是)
添加强>
此外,需要修复ListInsert:
void ListInsert(SqList *L, ElemType e){
int n = L->length;
L->data[n]=e;
L->length++;
}
您的版本跳过数组元素,因为您使用“递增大小”来索引新元素,而新插入的值必须放在索引L->length
,然后您需要递增数组的长度(大小为N的数组的最后一个元素是N-1,因此将大小增加到N + 1,最后一个元素将具有索引N)。
当然你不检查数组边界,所以如果插入超过MAXSIZE元素就会遇到麻烦。
添加2
您的LocateElem也需要修复:
int LocateElem(SqList *L, ElemType e){
int i;
for(i=1;i<=L->length;i++){
if(L->data[i]==e){
return i;
}
}
return 0;
}
(我保留了使用0作为未找到的特殊值的想法,尽管阅读了关于它的评论和MAXSIZE语言;此外,您的更多代码需要修复才能始终如一地使用它)。这里的修复是关于当你发现第一个元素不等于e时返回的事实,而(我想)你想要返回0如果没有找到元素,或者如果你找到它则不返回-0。这个固定的代码探索整个数组(从1开始,如果保留0索引以获得特殊含义)
答案 1 :(得分:1)
您必须检查n是否超过MAXSIZE。分段错误很可能是由缓冲区溢出引起的。
答案 2 :(得分:1)
如果长度为n,则只应使用0到n-1的元素。当然你也可以写过MAXLIST-1。您应该始终添加要检查的代码,而不是L-&gt;长度&lt; = MAXLIST。
我很想知道你为什么选择这种相当复杂的方法。我会将ListInsert重命名为ListAppend,因为您只添加到列表的末尾。
答案 3 :(得分:0)
以下是可能导致问题的一些错误:
int LocateElem(SqList *L, ElemType e){
int i;
for(i=1;i<=L->length;i++){
if(L->data[i]==e){ // <-- You need to check data[i-1]
return i; // since you span [1,length] (off by one)
break;
}
else return 0; // <-- This goes to outside of the loop,
} // otherwise only the first item is queried
}
void ListInsert(SqList *L, ElemType e){
int n = L->length;
n++;
L->length=n;
L->data[n]=e; // <-- You want to modify data[n-1]
} // since n is already incremented here
答案 4 :(得分:0)
LocateElem函数看起来很麻烦。如果循环中的第一个测试失败,为什么它返回0?为什么在退货声明后休息?看起来有几行被洗牌......休息应该去,并且在阻止之后返回0。