2011-02-02 18 views
30

Jak mogę usunąć element z tablicy, a następnie zmienić rozmiar tablicy na mniejszy? Podobnie, jak mogę zwiększyć pojemność, jeśli muszę dodać kolejny element?Usuwanie pozycji z tablicy i zmniejszanie tablicy

+0

jest „tablica” wymagana struktura danych dla przypadku użycia? Wygląda na to, że używasz niewłaściwego młotka –

Odpowiedz

0

Tablice mają ustalony rozmiar, nie można zmienić ich rozmiaru po ich utworzeniu. Można usunąć istniejący element ustawiając go null:

objects[4] = null; 

Ale nie będzie w stanie usunąć tę całą szczelinę przy tablicy i zmniejszyć jego rozmiar o 1.

Jeśli potrzebujesz dynamicznie -sized array, możesz użyć ArrayList. Dzięki niemu możesz obiektów add() i remove(), a będzie rosnąć i zmniejszać się w razie potrzeby.

+0

Czy mogę więc utworzyć nową tablicę bez elementu, który chcę usunąć? – Joe

+0

@Joe: To także możliwa opcja; spójrz na inne odpowiedzi. – BoltClock

15

Nie można zmienić tablicę per se, ale można utworzyć nową tablicę i efektywnie kopiowania elementów ze starej tablicy do nowej tablicy przy użyciu niektórych funkcji użyteczności takiego:

public static int[] removeElement(int[] original, int element){ 
    int[] n = new int[original.length - 1]; 
    System.arraycopy(original, 0, n, 0, element); 
    System.arraycopy(original, element+1, n, element, original.length - element-1); 
    return n; 
} 

A lepszym podejściem byłoby jednak użycie ArrayList (lub podobnej struktury List) do przechowywania danych, a następnie użycie ich metod do usuwania elementów w razie potrzeby.

+1

Ten kod zawiera błąd, który spowoduje, że zawsze będzie wyświetlał NPE. Edytowałem odpowiedź z poprawką. – Joel

+0

Pierwsze wywołanie metody System.arraycopy nie jest wymagane. – Stuart

1
object[] newarray = new object[oldarray.Length-1]; 

for(int x=0; x < array.Length; x++) 
{ 
    if(!(array[x] == value_of_array_to_delete)) 
    // if(!(x == array_index_to_delete)) 
    { 
    newarray[x] = oldarray[x]; 
    } 
} 

Nie ma sposobu na zmniejszenie rozmiaru tablicy po jej utworzeniu, ale można skopiować zawartość do innej tablicy o mniejszym rozmiarze.

+0

Co jeśli chcę po prostu zignorować ostatni bajt tablicy 640 bajtów ... – aProgrammer

+0

Wtedy twoja instancja byłaby 'object [] new array = new object [oldarray.Length-2];' pętla for zajmuje się przyrosty. – Mike

+0

Mam na myśli .. Czy musimy stworzyć nowy Array, nawet jeśli chcemy zignorować jeden bajt ... Czy nie możemy zmniejszyć Array? – aProgrammer

22

Rozmiar tablicy Javy jest ustalany podczas przydzielania go i nie można go zmienić.

  • Jeśli chcesz „rosnąć” lub „kurczyć” istniejącej macierzy, trzeba przydzielić nową tablicę o odpowiedniej wielkości i kopiowanie elementów tablicy; na przykład przy użyciu System.arraycopy(...) lub Arrays.copyOf(...). Pętla kopiowania również działa, chociaż wygląda trochę niezgrabnie ... IMO.

  • Jeśli chcesz "usunąć" element lub elementy z tablicy (w prawdziwym sensie ... nie tylko zastępując je wartością null), musisz przydzielić nową, mniejszą tablicę i skopiować elementy, które chcesz zatrzymać.

Istnieją alternatywy w postaci bibliotek 3rd-party (np Apache Commons ArrayUtils), ale może warto rozważyć, czy warto dodać zależność biblioteki tylko ze względu na sposób, który Cię mógł zaimplementować 5-10 linii kodu.


Lepiej (tj prostsze ... iw wielu przypadkach, bardziej wydajnych) użyć klasy List zamiast tablicy. To zajmie się (przynajmniej) zwiększeniem pamięci kopii zapasowej. Są też operacje, które zajmują się wstawianiem i usuwaniem elementów w dowolnym miejscu na liście.

Na przykład klasa ArrayList używa tablicy jako podkładu i automatycznie powiększa tablicę zgodnie z wymaganiami. Nie powoduje automatycznej redukcji rozmiaru tablicy podkładu, ale można to nakazać za pomocą metody trimToSize(); na przykład

ArrayList l = ... 
l.remove(21); 
l.trimToSize(); // Only do this if you really have to. 

1 - Powiedziałbym, że jest „bardziej skuteczne w wielu przypadkach”, ponieważ ArrayList używa prostego „podwoić wielkość” strategii, gdy potrzebuje się rozwijać tablicę podkładową. Oznacza to, że jeśli lista zostanie powiększona poprzez wielokrotne dołączanie do niej, każdy element zostanie skopiowany średnio jeden dodatkowy czas. W przeciwieństwie do tego, jeśli zrobiłbyś to z tablicą, skończyłbyś kopiowanie każdego elementu tablicy blisko N/2 razy średnio.

0

bez stosując metodę System.arraycopy można usunąć element z tablicy z następującym

int i = 0; 
    int x = 0; 
    while(i < oldArray.length){ 
     if(oldArray[i] == 3)i++; 

     intArray[x] = oldArray[i]; 
     i++; 
     x++; 
    } 

gdzie 3 jest wartością chcesz usunąć.

+0

To jest niekompletne. I tak naprawdę nie odpowiada na pytanie. –

11

Korzystanie z z org.apache.commons.lang jest zdecydowanie najłatwiejszym sposobem na zrobienie tego.

int[] numbers = {1,2,3,4,5,6,7}; 
//removing number 1 
numbers =(int[])ArrayUtils.removeElement(numbers, 1); 
+2

To tak naprawdę nie zmienia rozmiaru tablicy. Tworzy nową. Ale nie ma innego sposobu, ponieważ rozmiaru tablic nie można zmienić. – MrSmith42

+0

to dobry. – Simmant

2

Utworzyłem tę funkcję lub klasę. Im trochę nowy, ale mój przyjaciel to potrzebne także dlatego stworzyłem ten:

public String[] name(int index, String[] z){ 
    if(index > z.length){ 
     return z; 
    } else { 
     String[] returnThis = new String[z.length - 1]; 
     int newIndex = 0; 
     for(int i = 0; i < z.length; i++){ 
      if(i != index){ 
       returnThis[newIndex] = z[i]; 
       newIndex++; 
      } 
     } 
     return returnThis; 
    } 
} 

Ponieważ jest dość revelant, myślałem, że po to tutaj.

2

Ponieważ tablica ma stały rozmiar, który jest przydzielany podczas tworzenia, jedyną opcją jest utworzenie nowej tablicy bez elementu, który chcesz usunąć.

Jeśli element, który chcesz usunąć to ostatni element tablicy, staje się łatwe do wykonania przy użyciu Arrays.copy:

int a[] = { 1, 2, 3}; 
a = Arrays.copyOf(a, 2); 

Po uruchomieniu powyższego kodu, A będzie teraz wskazywać na nowej tablicy zawierającej tylko 1, 2.

W przeciwnym razie, jeśli element, który chcesz usunąć, nie jest ostatnim, musisz utworzyć nową tablicę w rozmiarze-1 i skopiować wszystkie elementy do niej oprócz tego, które chcesz usunąć.

Powyższe podejście nie jest skuteczne. Jeśli potrzebujesz zarządzać zmienną listą elementów w pamięci, lepiej użyj listy. W szczególności LinkedList usunie pozycję z listy w O(1) (najszybciej teoretycznie możliwe).

+0

Dla mnie najlepsze i najkrótsze działające rozwiązanie do obcinania tablicy. Dzięki! – Ruwen

-1

Zawsze możesz rozwinąć tablicę, zwiększając jej rozmiar, tworząc tablicę, lub możesz zmienić rozmiar po utworzeniu, ale zmniejszyć lub usunąć elementy. Alternatywne rozwiązanie bez tworzenia nowej tablicy to:

package sample; 

public class Delete { 
    int i; 
    int h=0; 
    int n=10; 
    int[] a; 
    public Delete() 
    { 
    a = new int[10]; 
    a[0]=-1; 
    a[1]=-1; 
    a[2]=-1; 
    a[3]=10; 
    a[4]=20; 
    a[5]=30; 
    a[6]=40; 
    a[7]=50; 
    a[8]=60; 
    a[9]=70; 
    } 
    public void shrinkArray() 
    { 
    for(i=0;i<n;i++) 
      { 
       if(a[i]==-1) 
        h++; 
       else 
        break; 
      } 
      while(h>0) 
       { 
        for(i=h;i<n;i++) 
        { 
         a[i-1]=a[i]; 
        } 
        h--; 
        n--; 
       } 
      System.out.println(n); 
    } 
    public void display() 
    { 
     for(i=0;i<n;i++) 
     { 
      System.out.println(a[i]); 
     } 
    } 

    public static void main(String[] args) { 
     // TODO Auto-generated method stub 
     Delete obj = new Delete(); 
     obj.shrinkArray(); 
     obj.display(); 

    } 

} 

Proszę o komentarz na temat błędów !!

+0

Nie zmienia to rozmiaru tablicy zgodnie z wymaganiami. –

-2

Nie stosowanie dowolnego wstępnie zdefiniowane funkcje, jak również efektywne: --- >>

public static void Delete(int d , int[] array) 
{  
    Scanner in = new Scanner (System.in); 

    int i , size = array.length; 

    System.out.println("ENTER THE VALUE TO DELETE? "); 

    d = in.nextInt(); 

     for (i=0;i< size;i++) 
     { 
       if (array[i] == d) 
         { 


          int[] arr3 =new int[size-1]; 
          int[] arr4 = new int[i]; 
          int[] arr5 = new int[size-i-1]; 

            for (int a =0 ;a<i;a++) 
            { 
             arr4[a]=array[a]; 
             arr3[a] = arr4[a]; 
            } 
            for (int a =i ;a<size-1;a++) 
            { 
             arr5[a-i] = array[a+1]; 
             arr3[a] = arr5[a-i]; 

            } 


       System.out.println(Arrays.toString(arr3)); 

         } 
       else System.out.println("************");  


     } 

} 
+0

Nie zmienia to rozmiaru tablicy zgodnie z wymaganiami. –

Powiązane problemy