同时对两个数组进行排序

问题描述 投票:0回答:9

我现在正在学习和理解Java,在练习数组时我有一个疑问。我编写了以下代码作为示例:

class example
{
    public static void main(String args[])
    {
        String a[] = new String[] {"Sam", "Claudia", "Josh", "Toby", "Donna"};
        int b[] = new int[] {1, 2, 3, 4, 5};

        for(int n=0;n<5;n++)
        {
            System.out.print (a[n] + "...");
            System.out.println (b[n]);
        }
        System.out.println (" ");

        java.util.Arrays.sort(a);

        for(int n=0;n<5;n++)
        {
            System.out.print (a[n] + "...");
            System.out.println (b[n]);
        }
    }

简而言之,这个类创建了两个数组,每个数组有五个空格。其中一个填入了西翼人物的名字,另一个填入了从一到五的编号。可以说这两个字符串中的数据是一一对应的。

现在,程序使用

Arrays.sort()
对数组及其中的名称进行排序。再次打印数组后,您可以看到,虽然名称现在按字母顺序排列,但数字不再对应,因为第二个数组未更改。

如何打乱第二个数组的内容以匹配第一个数组的排序要求?解决方案还必须灵活,以允许程序范围和大小的更改。请不要发布任何答案要求我改变我的数组方法,或提出更“有效”的做事方式。这是出于教育目的,我想要一个对所提供的示例代码的直接解决方案。预先感谢!

编辑:我不想创建额外的类,但是我认为某种形式的嵌套循环排序可能是一种选择,而不是 Arrays.sort()。

java arrays sorting
9个回答
12
投票

有人建议通过将两个数组合并为一个来创建一种产品类型。仅当元素量较小时这才是可行的。通过引入另一个对象,您会增加每个元素的对象开销(30+ 字节)和指针的性能损失(也会恶化缓存局部性)。总体来说很慢。

无对象开销的解决方案

制作第三个数组。用从

0
size-1
的索引填充它。使用比较器函数轮询到您要排序的数组,对此数组进行排序。

最后,根据索引对两个数组中的元素重新排序。

String a[] = new String[] {"Sam", "Claudia", "Josh", "Toby", "Donna"};
int b[] = new int[] {1, 2, 3, 4, 5};
assert(a.length == b.length);

// fill third array with indices
int c[] = new int[a.length];
for (int i = 0; i < a.length; ++i) c[i] = i;

// sort third array, with the comparator peaking into original arrays
Arrays.sort(c, Comparator.comparing(i => {
  String aEl = a[i];
  int bEl = b[i];
  return aEl.length + bEl; // put your custom sort function here
}))

11
投票

下面的代码没有使用任何

Map
集合,但是如果你想使用
Map
那么它就变得非常简单。将两个数组添加到映射中并对其进行排序。

public static void main(String args[]) {
    String a[] = new String[] {
        "Sam", "Claudia", "Josh", "Toby", "Donna"
    };
    int b[] = new int[] {
        1, 2, 3, 4, 5
    };
    for (int n = 0; n < 5; n++) {
        System.out.print(a[n] + "...");
        System.out.println(b[n]);
    }
    System.out.println(" ");
    //java.util.Arrays.sort(a);
    /* Bubble Sort */
    for (int n = 0; n < 5; n++) {
        for (int m = 0; m < 4 - n; m++) {
            if ((a[m].compareTo(a[m + 1])) > 0) {
                String swapString = a[m];
                a[m] = a[m + 1];
                a[m + 1] = swapString;
                int swapInt = b[m];
                b[m] = b[m + 1];
                b[m + 1] = swapInt;
            }
        }
    }
    for (int n = 0; n < 5; n++) {
        System.out.print(a[n] + "...");
        System.out.println(b[n]);
    }
}

2
投票

您必须将两个数组压缩成一个数组,其中元素是类的实例,例如:

class NameNumber 
{

    public NameNumber(String name, int n) {
        this.name = name;
        this.number = n;
    }

    public String name;
    public int number;
}  

并使用自定义比较器对该数组进行排序。

你的代码应该是这样的:

NameNumber [] zip = new NameNumber[Math.min(a.length,b.length)];
for(int i = 0; i < zip.length; i++)
{
    zip[i] = new NameNumber(a[i],b[i]);
}

Arrays.sort(zip, new Comparator<NameNumber>() {

    @Override
    public int compare(NameNumber o1, NameNumber o2) {
        return Integer.compare(o1.number, o2.number);
    }
});

1
投票

你不应该有两个并行的数组。相反,您应该有一个

WestWingCharacter
对象数组,其中每个对象都有一个字段
name
和一个字段
number

按名称对这个数组进行排序将是小菜一碟:

Collections.sort(characters, new Comparator<WestWingCharacter>() {
    @Override
    public int compare(WestWingCharacter c1, WestWingCharacter c2) {
        return c1.getName().compareTo(c2.getName();
    }
});

或者,使用 Java 8:

Collections.sort(characters, Comparator.comparing(WestWingCharacter::getName));

Java 是一种 OO 语言,因此你应该使用对象。


1
投票

你想要的是不可能的,因为你不知道内部如何

Arrays.sort
交换String数组中的元素,因此无法相应地交换int数组中的元素。

您应该创建一个包含

String
名称和
int
位置作为参数的类,然后仅使用名称对此类进行排序,从而为
Arrays.sort
提供自定义比较器。

如果您想保留当前代码(带有 2 个数组,但这不是理想的解决方案),请不要使用

Arrays.sort
并实现您自己的排序算法。当您交换两个名称时,获取它们的索引并相应地交换另一个数组中的两个整数。


0
投票

这是您的疑问的答案。

public class Main {
  public static void main(String args[]){

  String name[] = new String[] {"Sam", "Claudia", "Josh", "Toby", "Donna"};
        int id[] = new int[] {1, 2, 3, 4, 5};

        for ( int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                int dtmp=0;
                String stmp=null;
                if (id[i] > id[j]) {
                    dtmp = rate[i];
                    id[i] = id[j];
                    id[j] = dtmp;
                    stmp = name[i];
                    name[i]=name[j];
                    name[j]=stmp;
                }
            }
        }
        System.out.println("Details are :");
        for(int i=0;i<n;i++){
            System.out.println(name[i]+" - "+id[i]);
        }
    }
}

0
投票

相同的解决方案,作为可以添加到某些 utils 类中的函数:

public static final boolean INCREASING = true;
public static final boolean DECREASING = false;

@SuppressWarnings("unchecked")
public static <T extends Comparable, U extends Object> void bubbleSort(ArrayList<T> list1, ArrayList<U>list2, boolean order) {
  int cmpResult = (order ? 1 : -1);
  for (int i = 0; i < list1.size() - 1; i++) {
    for (int j = 0; j <= i; j++) {
      if (list1.get(j).compareTo(list1.get(j+1)) == cmpResult) {
        T tempComparable = list1.get(j);
        list1.set(j      , list1.get(j + 1));
        list1.set(j + 1  , tempComparable);
        U tempObject     = list2.get(j);
        list2.set(j      , list2.get(j + 1));
        list2.set(j + 1  , tempObject);
      }
    }
  }
}

-1
投票

数组没有以任何方式链接。就像有人指出的,看看

SortedMap
http://docs.oracle.com/javase/7/docs/api/java/util/SortedMap.html

TreeMap
http://docs.oracle.com/javase/7/docs/api/java/util/TreeMap.html


-2
投票
   import java.util.*;

class mergeArrays2
{
  public static void main(String args[])
  {
     String a1[]={"Sam", "Claudia", "Josh", "Toby", "Donna"};
     Integer a2[]={11, 2, 31, 24, 5};

     ArrayList ar1=new ArrayList(Arrays.asList(a1));

     Collections.sort(ar1);

     ArrayList ar2=new ArrayList(Arrays.asList(a2));

     Collections.sort(ar2);





     System.out.println("array list"+ar1+ " "+ar2);
  }

}
© www.soinside.com 2019 - 2024. All rights reserved.