簡體   English   中英

如何刪除數組中的項目並保持順序不變?

[英]How to delete an item in the array and keeping the order the same?

我正在從事這個項目,它允許我在數組中添加和刪除元素。 當我刪除數組中的元素時,該空間中會有一個零,代碼應該在刪除的值之后移動值以取代它的位置。 例如:在數組 {1, 2, 3, 4, 5} 中。 我選擇刪除3,我的output應該是{1, 2, 4, 5}。 相反,我的 output 是 {1, 2, 5, 4}。 有人可以幫我弄清楚為什么會那樣做嗎? 以及如何糾正?

import java.util.Scanner;
import java.util.Arrays;

public class IntBag2 {
    private static final int INITIAL_SIZE = 20;
    private static int[] bag;
    private int capacity;

    public IntBag2() {
        bag = new int[INITIAL_SIZE];
    }

    public IntBag2(int capacity) {
        bag = new int[capacity];
    }

    public boolean add(int item) {
        if (capacity == bag.length)
            return false;

        bag[capacity++] = item;

        return true;
    }

    public boolean delete(int item) {
        for (int i = 0; i < capacity; i++) {
            if (bag[i] == item) {
                bag[i] = bag[--capacity];
                return true;
            }
        }

        return false;
    }

    @Override
    public String toString() {
        String result = "Bag: ";
        for (int i = 0; i < capacity; i++)
            result += bag[i] + " ";
        return result;
    }

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        IntBag2 intBag = new IntBag2();
        boolean done = false;

        while (!done) {
            System.out.println("1. Add an Item to the Array");
            System.out.println("2. Delete an item in the Array");
            System.out.println("3. toString");
            switch (input.nextInt()) {
            case 1:
                System.out.println("Add an Item to the Array");
                System.out.println(intBag.add(input.nextInt()));
                break;
            case 2:
                System.out.println("Delete Item of Array");
                System.out.println(intBag.delete(input.nextInt()));
                break;
            case 3:
                System.out.println("toString");
                System.out.println(intBag.toString());
                break;
            }
        }
        input.close();
    }

}

隨着線bag[i] = bag[--capacity]; 您基本上是在獲取數組中的最后一項並將其放置在已刪除項的位置。

鑒於您使用的是int[] (而不是Integer[] ),我們無法將數組的索引分配為null 我們能做的最好的事情就是給它賦值-1或創建一個新數組。

我決定從頭開始創建一個新數組。 下面將做的伎倆。

public class IntBag2 {
    private static final int INITIAL_SIZE = 20;
    private static int[] bag;
    private int capacity;

    public IntBag2() {
        bag = new int[INITIAL_SIZE];
    }

    public IntBag2(int capacity) {
        bag = new int[capacity];
    }

    public boolean add(int item) {
        if (capacity == bag.length)
            return false;

        bag[capacity++] = item;

        return true;
    }

    public boolean delete(int item) {
        int[] newBag = new int[capacity];
        int newCapacity = capacity;
        boolean deleted = false;
        for (int i = 0, j = 0; i < capacity; i++) {
            if (bag[i] == item && !deleted) {
                deleted = true;
                newCapacity = capacity - 1;
            } else {
                newBag[j++] = bag[i];
            }
        }

        bag = newBag;
        capacity = newCapacity;
        return deleted;
    }

    @Override
    public String toString() {
        String result = "Bag: ";
        for (int i = 0; i < capacity; i++)
            result += bag[i] + " ";
        return result;
    }
}

一個更簡單的delete實現是可能的,允許“刪除”數組中等於給定item所有條目,並將剩余的條目高效地移到前面:

public boolean delete(int item) {
    System.out.println("deleting " + item); // for debug purposes
    int oldCapacity = capacity;
    for (int i = 0, j = 0; i < oldCapacity; i++) {
        if (bag[i] != item) {
            bag[j++] = bag[i];
        } else {
            capacity--;
        }
    }
    System.out.println("new capacity = " + capacity); // for debug

    // or use Arrays.fill(bag, capacity, oldCapacity, -1); instead of the loop
    for (int i = capacity; i < oldCapacity; i++) {
        bag[i] = -1; // mark free entries with -1 in the tail
    }

    return oldCapacity == capacity;
}

此外,如果在循環中使用多重連接,則toString方法應使用StringBuilder ,或者為簡潔起見,可以使用Arrays中的實用方法print以下方法:

public void print() {
    System.out.println(Arrays.toString(Arrays.copyOf(bag, capacity)));
}

測試:

IntBag ibag = new IntBag(10);
ibag.add(1);
ibag.add(3);
ibag.add(3);
ibag.add(2);
ibag.add(1);
ibag.print();
ibag.delete(2);
ibag.print();
ibag.delete(1);
ibag.print();

Output:

[1, 3, 3, 2, 1]
deleting 2
new capacity = 4
[1, 3, 3, 1]
deleting 1
new capacity = 2
[3, 3]

更新

僅“刪除”第一個條目而不創建新數組可以按如下方式實現:

  • 跳過所有元素,直到檢測到item或到達bag的末尾
  • 如果找到item ,將剩余元素移動 1,將 -1 寫入最后一個元素,返回true
  • 否則返回false
public boolean deleteFirst(int item) {
    System.out.println("deleting first " + item);
    int id = 0;
    while (id < capacity && bag[id] != item) id++;
    if (id < capacity && bag[id] == item) {
        while (++id < capacity) {
            bag[id - 1] = bag[id];
        }
        bag[--capacity] = -1;
        return true;
    }
    return false;
}

測試:

IntBag ibag = new IntBag(10);
ibag.add(1); ibag.add(3); ibag.add(1); ibag.add(2); ibag.add(1);
ibag.print();
ibag.deleteFirst(1); ibag.print();
ibag.deleteFirst(1); ibag.print();
ibag.deleteFirst(1); ibag.print();

Output:

[1, 3, 1, 2, 1]
deleting first 1
[3, 1, 2, 1]
deleting first 1
[3, 2, 1]
deleting first 1
[3, 2]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM