【问题标题】:How to decrease the size of an array after removing some elements from it从数组中删除一些元素后如何减小数组的大小
【发布时间】:2018-02-03 00:53:31
【问题描述】:

我正在做一个项目,这是其中一项任务: 创建一个名为“remove()”的方法,它可以从数组中删除一个元素。 去掉后,如果元素个数小于数组的1/4,数组的大小需要减半。

例如: 我有一个大小为 100 的数组,其中包含 25 个元素。删除一个元素后,我将有 24 个元素,我的数组大小为 50。

这是我的代码:

    //First create a method decrese
    private decrease() {
        if (numElement < (1 / 4) * (Array.length)) {
        Array[] newarray = new Array[(Array.length) / 2];
        for (int i = 0; i < numElement; i++)
            newarray[i] = Array[i];
        Array = newarray;   
    }

    //Then create my Remove method
    public void remove(ToRemove){
    if (numElement > 0) {                //First check if my array is empty
        for (int i = 0; i < numElement; i++) {
            if (Array[i].equals(ToRemove)) {
                Array[i] = Array[numElement - 1];
                Array[numElement - 1] = null;
                numElement--;
                decrease();
            }
        } 
     //if the Array is empty, also decrease the size 
     decrease();
     }

经过一些测试运行,我的删除工作正常,无论我放入什么大小,数组长度都不会减少。

谁能帮帮我。 谢谢

【问题讨论】:

  • Java 数组具有固定长度。您需要创建一个新的(较小的)数组。
  • Tom 的进一步评论:您期望 (1/4=.25),但 1 和 4 是 int 类型,所以 1/4 实际上是 0。由于您对值进行硬编码,只需使用0.25 代替。如果你使用变量,你会强制转换为 double。
  • @IanMc 谢谢大家,我不敢相信我被困了 3 个小时

标签: java arrays


【解决方案1】:

另外,你应该只使用 if (numLength

此外,您应该能够只使用一些 Arrays.copyOfRange 和 System.arraycopy 来满足您的复制需求。

https://docs.oracle.com/javase/7/docs/api/java/lang/System.html https://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html

这是一个简单的代码 sn-p,它基本上实现了从数组中删除元素。

import java.lang.reflect.Array;
import java.util.Arrays;

public class MySpecialArray<T> {

T[] buf;

int size;

Class<T> type;

public MySpecialArray(Class<T> type, int initialBufSize) {
    this.size = 0;
    this.type = type;

    buf = (T[]) Array.newInstance(type, initialBufSize);
}

    /**
 * Like arraylist add, it will basically add freely until it reaches the max length of the buffer.
 * Then it has to expand the buffer. It uses buf.length * 2 + 1 to account for when an initialBufSize of 0 is
 * supplied.
 * @param elem
 */
public void add(T elem) {
    if (this.size == this.buf.length) {
        int newSize = this.buf.length * 2 + 1;
        buf = Arrays.copyOf(buf, newSize);
    }
    this.buf[this.size] = elem;
    this.size += 1;
}

public void add(T...elements) {
    for(T elem : elements) {
        this.add(elem);
    }
}

/**
 * Remove all occurrences of an element. Also reduce the max buf_size of the array if my utilized size is less than a fourth of my max buf size.
 * @param removeMe element to remove all occurrences of
 * @return
 */
public void remove(T removeMe) {
    boolean found = false;
    for(int i = 0; i < this.size; i++) {
        if (buf[i].equals(removeMe)) {
            System.arraycopy(buf, i+1, buf, i, this.size - i);
            this.size -= 1;
            if (this.size < this.buf.length / 4) {
                this.buf = Arrays.copyOf(buf, this.buf.length / 2);
            }
        }
    }
}

/**
 * Remove the last element
 * @return
 */
public T remove() {
    if (this.size == 0) {
        throw new RuntimeException("Cannot remove from empty buffer");
    }
    T removed = this.buf[this.size -1];
    this.size -= 1;
    if (this.size <= this.buf.length / 4) {
        int newSize = this.buf.length / 2;
        this.buf = Arrays.copyOf(this.buf, newSize);
    }

    return removed;
}

@Override
public String toString() {
    StringBuilder sb = new StringBuilder();
    for(int i = 0; i < this.size; i++) {
        sb.append(this.buf[i].toString()).append(",");
    }
    return sb.toString();
}

public static void main(String...args) {
    MySpecialArray<Integer> arr = new MySpecialArray(Integer.class, 50);
    arr.add(10, 2, 4, 3, 5, 11, 9, 3, 8, 16);

    System.out.println("===Pre removed===");
    System.out.println(arr.buf.length);
    System.out.println(arr.size);
    System.out.println(arr);
    arr.remove(3);

    System.out.println("===After removing 3===");
    System.out.println(arr.buf.length);
    System.out.println(arr.size);
    System.out.println(arr);
 }
}

这个示例在运行时会打印出来

===Pre removed===
50
10
10,2,4,3,5,11,9,3,8,16,
===After removing 3===
25
8
10,2,4,5,11,9,8,16,

【讨论】:

    【解决方案2】:

    简单的答案是“你不能”

    Java Array 数据结构的大小是固定的,“一旦创建”,您就无法更改 Same Array Object 的大小。

    如果您需要更改大小,您要么需要将其内容复制到一个新的 Array 对象,要么使用不同的数据结构,如 ArrayList,它在内部执行此操作。

    【讨论】:

    • “您要么需要将其内容复制到新的数组对象” - OP 已经这样做了...
    • 新数组的大小/长度将是OP给出的不是吗?
    猜你喜欢
    • 2019-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多