题目
从有序表中删除所有其值重复的元素,使表中所有的元素的值均有不同
算法设计
解法一
用类似于直接插入排序的思想,初试时将第一个元素视为非重复的有序表,之后依次判断后面的元素是否与前面的非重复元素有序表的最后一个元素相同,若相同则继续向后判断,若不同则插入前面的非重复有序表的,最后直至判断到表尾为止
bool del(sqlist &L)
{
if(L.length==0)
return false;
int i,j;//i存储第一个不相同的元素,j为工作指针
for(i=0,j=1;j<L.length;j++)
if(L.data[i]!=L.data[j])//查找下一个与上个元素不同的元素
L.data[++i]=L.data[j];//找到后,将元素前移
L.length=i+1;
return true;
}
解法二
每遇到一个重复的就将后面的整体向前移动一个,以此类推
bool Delete_Same(SqList &L)
{
for(int i=0;i<L.length;i++)
{
int k=0;
for(int j=i+1;j<L.length;j++)
{
if (L.data[i] == L.data[j])
k++;
else
L.data[j-k]=L.data[j];
}
L.length=L.length-k;
}
return true;
}
实验
整体实验如下:
#include <iostream>
#include <cstdio>
using namespace std;
typedef struct
{
int *data;
int Maxsize=10,length;
}sqlist;
void init(sqlist &L)//初始化
{
for(int i=0;i<L.Maxsize;i++)
L.data[i]=0;
L.length=0;
}
bool create(sqlist &L)//创建
{
for(int i=0;i<L.Maxsize;i++)
{
cin>>L.data[i];
L.length++;
}
return true;
}
int print(sqlist &L)//打印
{
for(int i=0;i<L.length;i++)
cout<<L.data[i]<<" ";
printf("\n");
return true;
}
bool del(sqlist &L)//删除重复元素
{
/*bool Delete_Same(SqList &L)
{
for(int i=0;i<L.length;i++)
{
int k=0;
for(int j=i+1;j<L.length;j++)
{
if (L.data[i] == L.data[j])
k++;
else
L.data[j-k]=L.data[j];
}
L.length=L.length-k;
}
return true;
}*/
if(L.length==0)
return false;
int i,j;
for(i=0,j=1;j<L.length;j++)
if(L.data[i]!=L.data[j])
L.data[++i]=L.data[j];
L.length=i+1;
return true;
}
int main()
{
sqlist L;
init(L);
create(L);
//print(L);
del(L);
print(L);
cout<<"length = "<<L.length<<endl;
}
结果
如下:
此题本想设一个k来计数,作为重复的元素,每遇到一个重复的元素就前移k个,但是忽略了向前移动后,留在原地的元素其实又和元素自己向前移动后的位置元素重复了,造成k计数不准,然后就只能没遇到一个元素就将后面所有的元素都向前移一个(解法二),不知道有没有大佬能解决我遇到的问题,每遇到一个都前移的话,效率不够高。