【问题标题】:Sorting two arrays simultaneously同时对两个数组进行排序
【发布时间】:2014-06-13 21:03:04
【问题描述】:

我现在正在学习和理解 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.util.Array.Sort()?你为什么不写你的排序方法?
  • 可以使用自定义排序方法。
  • 在我看来,编写模棱两可和不清楚的代码听起来不是“教育目的”。创建其他对象并正确执行。
  • 你不理解我,我这样做不是为了解决我的问题,我想发现一种仅使用循环将数组排序在一起的方法。对我来说,学习不仅仅是找到问题的解决方案,而是学习所有可能的解决方案。

标签: java arrays sorting


【解决方案1】:
   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);
  }

}

【讨论】:

    【解决方案2】:

    有些人建议做一个产品类型。只有当元素的数量很少时,这才是可行的。通过引入另一个对象,您会为每个元素增加对象开销(30+ 字节)和指针的性能损失(也会恶化缓存局部性)。

    没有对象开销的解决方案

    制作第三个数组。用从0size-1 的索引填充它。使用比较器函数轮询此数组,将其排序到您要排序的数组中。

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

    替代解决方案

    自己编写排序算法。这并不理想,因为您可能会犯错误并且排序效率可能会低于标准。

    【讨论】:

      【解决方案3】:

      这里是您查询的答案。

      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]);
              }
          }
      }
      

      【讨论】:

        【解决方案4】:

        下面是没有使用任何Map Collection 的代码,但是如果你想使用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]);
            }
        }
        

        【讨论】:

        • 非常感谢,这非常有效,我现在知道如何使用冒泡排序了。
        • 您介意发布一个 Gist 或 Pastebin,其中冒泡排序循环采用 'n' 个数组空间而不是 5 个吗?
        • for(int i = 0 ; i
        • @PrashantGurav,是否可以获得排序后的索引,以便之后可以使用该索引恢复原始顺序?
        • @PrashantGurav,我想通了,添加 int[] idx = new int[a1len]; Arrays.setAll(idx, i -&gt; i ); 和 sort idx 以及 b 将返回排序数组的索引。
        【解决方案5】:

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

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

        然后使用 custom comparator 对该数组进行排序。

        你的代码应该是这样的:

        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);
            }
        });
        

        【讨论】:

          【解决方案6】:

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

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

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

          【讨论】:

            【解决方案7】:

            你想要什么是不可能的,因为你不知道内部Arrays.sort如何交换你的String数组中的元素,所以没有办法相应地交换int数组中的元素。

            您应该创建一个包含String 名称和int 位置作为参数的类,然后仅使用名称对此类进行排序,为Arrays.sort 提供自定义比较器。

            如果您想保留当前代码(使用 2 个数组,但这不是理想的解决方案),请不要使用 Arrays.sort 并实现您自己的排序算法。交换两个名称时,获取它们的索引并相应地交换另一个数组中的两个整数。

            【讨论】:

            • 这是迄今为止最相关的答案,您对如何使用循环对数组进行排序有任何想法吗?
            • @VedantChandra 你可以看一些排序算法的实现(我会从最简单的开始,称为冒泡排序en.wikipedia.org/wiki/Bubble_sort)。这不是很有效,但实现起来很简单。完成后,您就可以开始实现更高效的排序算法了。
            • 冒泡排序听起来很完美,我该如何实现这是我的代码?
            • @VedantChandra 维基百科页面提供了实现它的所有必要信息。 IMO 这显然比我为您编写代码更适合您学习如何实现它(这并不难)。您只需要知道,在 Java 中比较对象时,它们必须实现可比较的接口(@98​​7654328@ 就是这种情况)并且您使用 compareTo 方法而不是 。
            • @VedantChandra 您可以编写第一个将字符串数组作为参数的方法。然后是一个更通用的,使用具有适当边界的泛型来确保元素具有可比性。你可以看看我回答的这个问题,和你基本一样的问题。 stackoverflow.com/questions/20270336/…
            【解决方案8】:

            您不应该有两个并行数组。相反,您应该有一个 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 是一种面向对象的语言,因此您应该使用对象。

            【讨论】:

              猜你喜欢
              • 2013-07-20
              • 2014-11-10
              • 2016-07-26
              • 2016-03-12
              • 1970-01-01
              • 2023-01-19
              • 2011-04-23
              相关资源
              最近更新 更多