【问题标题】:Java, Shifting Elements in an ArrayJava,在数组中移动元素
【发布时间】:2011-12-19 17:29:39
【问题描述】:

我在 Java 中有一组对象,我试图将一个元素拉到顶部并将其余元素向下移动一个。

假设我有一个大小为 10 的数组,并且我正在尝试提取第五个元素。第五个元素进入位置0,所有从 0 到 5 的元素都将向下移动 1。

这个算法没有正确地移动元素:

Object temp = pool[position];

for (int i = 0; i < position; i++) {                
    array[i+1] = array[i];
}
array[0] = temp;

我该如何正确操作?

【问题讨论】:

  • 正如@PaulSassik 所说,如果您需要转移,那么这不是一个很好的使用数组。要么使用链表,要么使用某种指向缓冲区的指针(是的,您可以使用类似于 java 中的指针的东西)。
  • 考虑使用System.arraycopy()

标签: java arrays algorithm shift


【解决方案1】:

从逻辑上讲它不起作用,你应该反转你的循环:

for (int i = position-1; i >= 0; i--) {                
    array[i+1] = array[i];
}

你也可以使用

System.arraycopy(array, 0, array, 1, position);

【讨论】:

  • 不要忘记创建一个比原来更大的新数组。 String[] newArray = new String[myArray.length +1]; System.arraycopy(myArray, 0, newArray, 1, myArray.length);
  • 如果性能是一个问题,我的测试表明覆盖原始数组比使用 System.arraycopy() 快得多。初始化新数组似乎相当昂贵。
  • @Hugo Greesse 您不需要创建数组的临时副本。请参阅 arraycopy 的手册页。
  • @Tullochgorum System.arraycopy 可以移动元素,您不应创建数组的新副本。手册说“如果 src 和 dest 参数引用相同的数组对象,则执行复制就像位置 srcPos 到 srcPos+length-1 的组件首先复制到临时数组。 ..”,这句话中的关键词是“好像”。
【解决方案2】:

假设您的数组是 {10,20,30,40,50,60,70,80,90,100}

你的循环所做的是:

迭代 1: array[1] = array[0]; {10,10,30,40,50,60,70,80,90,100}

迭代 2: array[2] = array[1]; {10,10,10,40,50,60,70,80,90,100}

你应该做的是

Object temp = pool[position];

for (int i = (position - 1); i >= 0; i--) {                
    array[i+1] = array[i];
}

array[0] = temp;

【讨论】:

  • 显然写for(int i = position; i&gt;0; i--) { array[i] = array[i-1]; }会更好
  • 生成代码的差异是微不足道的((position - 1) 的额外减法),但 position&gt; 的清晰度和清洁度而不是 (position - 1)&gt;= 很重要。
【解决方案3】:

你可以使用Collections.rotate(List&lt;?&gt; list, int distance)

使用Arrays.asList(array) 转换为List

更多信息请访问:https://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#rotate(java.util.List,%20int)

【讨论】:

    【解决方案4】:

    您可以使用这样的模块使此功能更通用,而不是移动一个位置。

    int[] original = { 1, 2, 3, 4, 5, 6 };
    int[] reordered = new int[original.length];
    int shift = 1;
    
    for(int i=0; i<original.length;i++)
         reordered[i] = original[(shift+i)%original.length];
    

    【讨论】:

    • mod 的完美解决方案。
    • 测试失败:original = [3, 8, 9, 7, 6], shift = 3
    • @AliRezaiyan 我只是根据您的输入运行它,它会返回正确的值。 [3, 8, 9, 7, 6] shift 3 --> [7, 6, 3, 8, 9]
    【解决方案5】:

    仅出于完整性考虑:自 Java 8 以来的 Stream 解决方案。

    final String[] shiftedArray = Arrays.stream(array)
            .skip(1)
            .toArray(String[]::new);
    

    我想我在你的情况下坚持使用System.arraycopy()。但最好的长期解决方案可能是将所有内容都转换为不可变集合(GuavaVavr),只要这些集合是短暂的。

    【讨论】:

    • .skip(n) 不删除第一个 n 元素吗?
    【解决方案6】:

    如您所见,以这种方式操作数组很容易出错。更好的选择可能是在您的情况下使用LinkedList。使用链表和所有 Java 集合,数组管理是在内部处理的,因此您不必担心移动元素。使用 LinkedList,您只需调用 remove,然后调用 addLast,就完成了。

    【讨论】:

    • 是的,我知道 - 尽管我知道它不是最佳选择,但我还是出于其他原因选择了数组。
    • 有很多集合可供选择,包括通用集合。如果您与我们分享您为什么需要使用普通数组,也许我们可以提供一些其他替代建议。
    【解决方案7】:

    试试这个:

    Object temp = pool[position];
    
    for (int i = position-1; i >= 0; i--) {                
        array[i+1] = array[i];
    }
    
    array[0] = temp;
    

    看这里看看它是否工作:http://www.ideone.com/5JfAg

    【讨论】:

    • @Nayefc:您首先将元素 0 复制到 1。然后将 new 元素 1 复制到 2。依此类推。所以基本上,除了索引 0 之外,之后的所有内容都具有相同的值。
    【解决方案8】:

    在循环的第一次迭代中,您覆盖了array[1] 中的值。您应该以相反的顺序浏览这些指标。

    【讨论】:

      【解决方案9】:
      static void pushZerosToEnd(int arr[])
          {   int n = arr.length;
              int count = 0;  // Count of non-zero elements
              // Traverse the array. If element encountered is non-zero, then
              // replace the element at index 'count' with this element
              for (int i = 0; i < n; i++){
                  if (arr[i] != 0)`enter code here`
                     // arr[count++] = arr[i]; // here count is incremented
                      swapNumbers(arr,count++,i);
              }
              for (int j = 0; j < n; j++){
                  System.out.print(arr[j]+",");
              }
           }
      
          public static void swapNumbers(int [] arr, int pos1, int pos2){
              int temp  = arr[pos2];
              arr[pos2] = arr[pos1];
              arr[pos1] = temp;
          }
      

      【讨论】:

        【解决方案10】:

        如果您将数组数据作为 Java-List 的另一种变化

            listOfStuff.add( 
                    0, 
                    listOfStuff.remove(listOfStuff.size() - 1) );
        

        只是分享我为此遇到的另一个选项,但我认为@Murat Mustafin 的答案是使用列表的方式

        【讨论】:

          【解决方案11】:
          public class Test1 {
          
              public static void main(String[] args) {
          
                  int[] x = { 1, 2, 3, 4, 5, 6 };
                  Test1 test = new Test1();
                  x = test.shiftArray(x, 2);
                  for (int i = 0; i < x.length; i++) {
                      System.out.print(x[i] + " ");
                  }
              }
          
              public int[] pushFirstElementToLast(int[] x, int position) {
                  int temp = x[0];
                  for (int i = 0; i < x.length - 1; i++) {
                      x[i] = x[i + 1];
                  }
                  x[x.length - 1] = temp;
                  return x;
              }
          
              public int[] shiftArray(int[] x, int position) {
                  for (int i = position - 1; i >= 0; i--) {
                      x = pushFirstElementToLast(x, position);
                  }
                  return x;
              }
          }
          

          【讨论】:

          • 您可能应该稍微解释一下您的代码,而且,我认为这行不通。您的方法 pushFirstElementToLast 接受参数位置,但随后不对其执行任何操作...此外,该方法的名称表明它只是将第一个元素移动到末尾,而不是将其插入到特定位置。
          • 该方法中的位置变量是不需要的,我接受,但如果我的代码不能解决原始问题,请提供输入和预期的输出,我会很乐意工作就在上面
          【解决方案12】:

          对大小为 n 的数组的左旋转操作将数组的每个元素单元向左移动,检查一下!!!!!!

          public class Solution {
              private static final Scanner scanner = new Scanner(System.in);
          
              public static void main(String[] args) {
                  String[] nd = scanner.nextLine().split(" ");
          
                  int n = Integer.parseInt(nd[0]);  //no. of elements in the array
          
                  int d = Integer.parseInt(nd[1]);  //number of left rotations
          
                  int[] a = new int[n]; 
          
                for(int i=0;i<n;i++){
                    a[i]=scanner.nextInt();
                }
          
                  Solution s= new Solution();     
          //number of left rotations
                  for(int j=0;j<d;j++){
                        s.rotate(a,n);
                  }
             //print the shifted array  
                  for(int i:a){System.out.print(i+" ");}
              }
          
          //shift each elements to the left by one 
             public static void rotate(int a[],int n){
                      int  temp=a[0];
                  for(int i=0;i<n;i++){
                      if(i<n-1){a[i]=a[i+1];}
                      else{a[i]=temp;}
                }}
          }
          

          【讨论】:

            【解决方案13】:

            您可以使用以下代码进行移位而不是旋转:

                int []arr = {1,2,3,4,5,6,7,8,9,10,11,12};
                        int n = arr.length;
                        int d = 3;
            

            将大小为n 的数组向左移动d 元素的程序:

                Input : {1,2,3,4,5,6,7,8,9,10,11,12}
                Output: {4,5,6,7,8,9,10,11,12,10,11,12}
            
                    public void shiftLeft(int []arr,int d,int n) {
                        for(int i=0;i<n-d;i++) {
                            arr[i] = arr[i+d];
                        }
                    }
            

            将大小为n 的数组向右移动d 元素的程序:

                Input : {1,2,3,4,5,6,7,8,9,10,11,12}
                Output: {1,2,3,1,2,3,4,5,6,7,8,9}
            
                    public void shiftRight(int []arr,int d,int n) {
            
                        for(int i=n-1;i>=d;i--) {
                            arr[i] = arr[i-d];
                        }
                    }
            

            【讨论】:

              【解决方案14】:
              import java.util.Scanner;
              
              public class Shift {
              
                  public static void main(String[] args) {
              
                      Scanner input = new Scanner (System.in);
                      int array[] = new int [5];
                      int array1[] = new int [5];
                      int i, temp;
              
                      for (i=0; i<5; i++) {
                          System.out.printf("Enter array[%d]: \n", i);
                          array[i] = input.nextInt(); //Taking input in the array
                      }
              
                      System.out.println("\nEntered datas are: \n");
                      for (i=0; i<5; i++) {
                          System.out.printf("array[%d] = %d\n", i, array[i]); //This will show the data you entered (Not the shifting one)
                      }
              
                      temp = array[4]; //We declared the variable "temp" and put the last number of the array there...
              
                      System.out.println("\nAfter Shifting: \n");
              
                      for(i=3; i>=0; i--) {
                          array1[i+1] = array[i]; //New array is "array1" & Old array is "array". When array[4] then the value of array[3] will be assigned in it and this goes on..
                          array1[0] = temp; //Finally the value of last array which was assigned in temp goes to the first of the new array
                      }
              
              
                      for (i=0; i<5; i++) {
                          System.out.printf("array[%d] = %d\n", i, array1[i]);
                      }
              
                      input.close();
              
                  }
              
              }
              

              【讨论】:

              • 你应该添加一些 cmets 你的代码是如何解决问题的。
              • OP 不想创建新数组。无论如何,您可以使用 System.arraycopy 来完成所有这些操作。
              【解决方案15】:

              编写一个Java程序,创建一个20个整数组成的数组,然后实现数组右移两个元素的过程。

              public class NewClass3 {
                  
                   public static void main (String args[]){
                   
                   int a [] = {1,2,};
                  
                   int temp ;
                   
                   for(int i = 0; i<a.length -1; i++){
                    
                       temp = a[i];
                       a[i] = a[i+1];
                       a[i+1] = temp;
                   
                   }
                   
                   for(int p : a)
                   System.out.print(p);
                   }
                  
              }
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2013-01-29
                • 1970-01-01
                • 1970-01-01
                • 2016-08-28
                • 1970-01-01
                相关资源
                最近更新 更多