【发布时间】:2013-05-02 06:47:17
【问题描述】:
我正在尝试通过合并排序对数组进行排序,并在排序时删除我认为相等的元素。我递归地调用合并排序然后合并。
我到了这一点,发现a 和c 是重复。
a b | c d
我根据某些标准确定我想要哪一个,然后选择 c。我增加右手计数器和左手计数器并比较b和d。说我选d,然后我选b。我希望我的最终列表只有元素
c d b
但是,在下一次递归调用中发生了什么,start 和 end 分别为 0 和 3,因此 d 在下一次调用时在数组中列出了两次。合并过程使用的数组是:
c d b d
这里是代码。提前致谢。
private static void merge(int[] data, int start, int mid, int end)
{
int firstCopied=0;
int secondCopied=0;
int index=0;
int length=end-start+1;
int[] temp = new int[end-start+1];
int firstSize=mid-start+1;
int secondSize=end-mid;
while(firstCopied < firstSize && secondCopied < secondSize)
{
if(data[start+firstCopied] < data[mid+1+secondCopied])
{
temp[index++] = data[start+firstCopied];
firstCopied++;
}
else if(data[start+firstCopied] > data[mid+1+secondCopied])
{
temp[index++] = data[mid+1+secondCopied];
secondCopied++;
}
else if(data[start+firstCopied]==data[mid+1+secondCopied])
{
boolean result = PickOne();
if(result)
{
temp[index++] = data[start+firstCopied];
}
else
{
temp[index++] = data[mid+1+secondCopied];
}
firstCopied++;
secondCopied++;
length--;
}
}
while(firstCopied < firstSize)
{
temp[index++] = data[start+firstCopied];
firstCopied++;
}
while(secondCopied < secondSize)
{
temp[index++] = data[mid+1+secondCopied];
secondCopied++;
}
for(int i=0; i<length; i++)
{
data[start+i]=temp[i];
}
}
【问题讨论】:
-
PickOne()是做什么的? -
在我看来,mergesort 已经足够复杂了,无需交织特殊用途的代码来删除其中的重复项。我建议使用两个单独的功能:首先对数据进行合并排序,然后删除重复项,这在排序后的数据中可能是连续的,因此很容易找到。
-
您已标记此 C 和 C++,但
private static void ...和int[] temp = new int[end-start+1];表明这是另一种语言。您实际使用的是哪种语言? -
带有重复删除的合并排序修改的工作示例(在 Delphi 中):stackoverflow.com/questions/12673633/…
-
感谢您的回复。我将其标记为mergeSort,但有人更改了它。这种语言是Java。我已经编写了代码来对数组进行后处理,但有人告诉我在合并时删除 dups。我还没有看到任何代码,只是模糊的建议“不要将重复项添加到您的列表中”。这不是问题,问题在于 mergeSort 是递归的,您无法更改它在每一步中考虑的数组的“块”。必须有办法做到这一点。