在排序一个具有重复元素

时间:2017-01-03 17:34:04

标签: java c++ sorting

我有两个阵列。 Array1=[5,4,3,3,2]Array2=[2,7,1,2,5]

我想平行使用这两个数组。就像当Array2的元素更改顺序时,Array1元素会相应地更改顺序。所以对于我的程序,我对Array2进行了排序,它变为Array2=[1,2,2,5,7]。因此,Array1必须更改为Array1=[3,3,5,2,4]

我想知道如何做到这一点(psudocode或java或c ++)。我在下面提供了我在C ++中尝试过的代码。 问题是当元素重复时它不起作用。因此在Array2[1,2,2,5,7]进行排序后,它会Array1更新为[3,5,5,2,4](你应该通过查看下面的代码了解它为什么提供此输出。

所以我的任务是更新Array2时(元素更改顺序),所以应Array1。当Array2具有重复元素时,它必须工作。

  k=0;
  for(int i=0;i<n;i++)
    {
    int a=arr1[i];
    for(int j=0;j<n;j++)
    {
        if(a==arr2[j])
        {
            arr4[k]=arr1[j];
            k++;
            break;
        }
    }
}

2 个答案:

答案 0 :(得分:1)

如果数组必须是并行的,那么对它们进行排序的更好方法是使用第三个索引数组,并根据Array2对这些整数进行排序。请注意,这是C ++代码,而不是Java:

#include <algorithm>
#include <array>
#include <iostream>

int main()
{
   std::array<int, 5> Array1 = {{5,4,3,3,2}};
   std::array<int, 5> Array2 = {{2,7,1,2,5}}; 
   std::array<int, 5> indices = {{0,1,2,3,4}};

   // only sort the indices, based on Array2
   std::sort(indices.begin(), indices.end(), [&](int n1, int n2)
              { return Array2[n1] < Array2[n2]; });

   // output results
   for (auto& i : indices)
      std::cout << Array1[i] << " ";
   std::cout << "\n";
   for (auto& i : indices)
      std::cout << Array2[i] << " ";
}

Output:
3 5 3 2 4 
1 2 2 5 7 

输出函数也可以这样写:

   // output results
   for (int i = 0; i < 5; ++i)
      std::cout << Array1[indices[i]] << " ";
   std::cout << "\n";
   for (int i = 0; i < 5; ++i)
      std::cout << Array2[indices[i]] << " ";

答案 1 :(得分:0)

我建议使用不同的解决方案,如果您不想使用,请丢弃。设计一个包含两个字段的类,一个用于array1中的数字,另一个用于数组2中的数字。而不是两个int数组,从这个类中创建一个对象数组。现在无论数组如何重新排序,每个原始数组的数字将始终相互关联。此外,根据需要,可以很容易地按第一个或第二个数字排序。

我没想到会为你编写代码,但是根据你的要求,这里有一些有用的Java代码片段可以帮助你入门。该类非常简单,有两个字段,构造函数和getter:

public class ParallelNumbers {

    /** number from array 1 */
    int elem1;
    /** number from array 2 */
    int elem2;

    public ParallelNumbers(int elem1, int elem2) {
        this.elem1 = elem1;
        this.elem2 = elem2;
    }

    public int getElem1() {
        return elem1;
    }

    public int getElem2() {
        return elem2;
    }
}

您当然可以添加toString方法以及您可能喜欢的其他方法。由于您更了解您的域名,因此您还可以为该班级找到更好的名称。有了这堂课,你可以这样做:

    ParallelNumbers[] all = new ParallelNumbers[] { new ParallelNumbers(5, 2), new ParallelNumbers(4, 7),
                    new ParallelNumbers(3, 1), new ParallelNumbers(3, 2), new ParallelNumbers(2, 5) };
    System.out.println("Numbers from array 1: " 
            + Arrays.stream(all).map(ParallelNumbers::getElem1).collect(Collectors.toList()));
    System.out.println("Numbers from array 2: " 
            + Arrays.stream(all).map(ParallelNumbers::getElem2).collect(Collectors.toList()));

您将在打印输出中识别原始阵列:

Numbers from array 1: [5, 4, 3, 3, 2]
Numbers from array 2: [2, 7, 1, 2, 5]

作为排序示例,以下是ParallelNumbers元素排序elem2元素,然后排序elem1(解决冲突)的方法:

    Arrays.sort(all, 
            Comparator.comparingInt(ParallelNumbers::getElem2).thenComparingInt(ParallelNumbers::getElem1));
    System.out.println("Numbers from array 1: " 
            + Arrays.stream(all).map(ParallelNumbers::getElem1).collect(Collectors.toList()));
    System.out.println("Numbers from array 2: " 
            + Arrays.stream(all).map(ParallelNumbers::getElem2).collect(Collectors.toList()));

这次打印:

Numbers from array 1: [3, 3, 5, 2, 4]
Numbers from array 2: [1, 2, 2, 5, 7]

正如你所要求的那样,不是吗?

编辑:以前写过类似的东西。例如,请参阅Anti-pattern: parallel collectionsParallel array