簡體   English   中英

如何從兩個創建一個新數組並根據原始數組中的值初始化新數組

[英]How to create a new array from two and initialize the new one based on values in original arrays

我是 Java 新手,我不確定如何提出正確的問題,所以請耐心等待。 我總共有 6 種不同類型的 40 個項目要放入一個新數組中; 每種物品類型都有不同的成本。 第一個項目(數量=1)花費 3 美元,第二個項目(數量=2)每個花費 5 美元,第三個項目(數量=4)花費 9 美元,依此類推。 每個項目類型的數量在numTypeIndArray ,每個類型的成本在costCSDriverArray 總項目的累積計數在numTypeCumulArray

因此,新數組indItemCostArray應該是一維的並且有 40 個元素。 它看起來像{3,5,5,9,9,9,9,...,13,13,13} ,但最后 15 個元素的成本為 13 美元。 如何使用 40 個元素訪問這個數組? 我開始嘗試使用嵌套的 for 循環填充數組,但我還沒有到達那里。 下面的代碼是完全錯誤的。

int[] costArray = new int[]{3,5,9,10,11,13};
int[] numTypeIndArray = new int[]{1,2,4,7,11,15};
int[] numTypeCumulArray = new int[]{1,3,7,14,25,40};

int[] indItemCostArray = new int[numTypeCumulArray[6]];

for (int i = 0; i < indItemCostArray.length; i++) {
    for (int j = 0; j < numTypeIndArray[i]; j++) {
        indItemCostArray[i+j] = costArray[j];
    }
}

首先,您將在以下位置獲得ArrayOutOfBoundException

int[] indItemCostArray = new int[numTypeCumulArray[6]];

數組numTypeCumulArray的大小為 6,數組索引為 0。 因此,最后一個索引號是 5,而不是 6,因為索引從 0 開始。

您可以執行以下操作來訪問數組的最后一個元素:

int[] indItemCostArray = new int[numTypeCumulArray[numTypeCumulArray.length - 1]];

其次,您運行外循環40次,每次迭代時,內循環嘗試迭代numTypeIndArray[i]次,其中i是外循環的迭代器變量。 因此,肯定在第六次迭代之后,當i值為6 ,您的程序將再次拋出ArrayOutOfBoundException因為您正在從numTypeIndArray的最后一個索引為 5 訪問內循環的終止符條件中的值。

同樣,在內部循環中,您在索引位置i+j處分配indItemCostArray ,這實際上與您的目的相去甚遠。

要實現您的期望,您可以執行以下操作:

int currentIndex =0;

for (int costIndex = 0; costIndex < costArray.length; costIndex++) {
    for(int index = currentIndex;  index < currentIndex + numTypeIndArray[costIndex]; index++) {
        indItemCostArray[index] = costArray[costIndex];
    }
    currentIndex = numTypeCumulArray[costIndex];
}

在這里,我所做的是,在外循環中,我迭代了與costArray的長度相同的時間,您也可以采用numTypeIndArray的長度,沒問題。 我定義了一個名為currentIndex的變量來跟蹤數組indItemCostArray的當前可分配索引。 在內部循環中,我嘗試從currentIndex開始並循環到與該類型所需的項目數相同的時間,在numTypeIndArray[costIndex] ,並且對於每次迭代,設置indItemCostArray的相應索引的成本為costIndex中的costArray 最后,我用來自numTypeCumulArray的相應累積總項目更新 currentIndex 。

希望你一切都清楚。

三個陣列的整個設置有點奇怪。 最奇怪的是第三個數組。 仔細想想,你真的需要它嗎? 您已經擁有第二個數組中的所有信息。 第三個數組會引入很多不必要的錯誤。

但是,假設您出於某種原因確實需要這些數組,並且制作這些數組沒有錯誤。 您可以獲得所需的第四個數組,如下所示,

int[] costArray = new int[]{3,5,9,10,11,13};
int[] numTypeIndArray = new int[]{1,2,4,7,11,15};
int[] numTypeCumulArray = new int[]{1,3,7,14,25,40};

// you want to make sure that your arrays are of same lenght
assert(costArray.length == numTypeIndArray.length && costArray.length == numTypeCumulArray.length);

// length of these arrays is unique items count
int uniqueItemsCount = costArray.length;

// totalItemsCount is last element of numTypeCumulArray
int totalItemsCount = numTypeCumulArray[uniqueItemsCount - 1];

int[] indItemCostArray = new int[totalItemsCount];

// use this to keep track of index in indItemCostArray
int itemCostIndex = 0;

for (int i = 0; i < uniqueItemsCount && itemCostIndex < totalItemsCount; i++) {
    for (int j = 0; j < numTypeIndArray[i] && itemCostIndex < totalItemsCount; j++) {
        indItemCostArray[itemCostIndex] = costArray[j];
        // increase the index for next item cost
        itemCostIndex += 1;
    }
}
    int[] costArray = new int[]{3,5,9,10,11,13};
    int[] numTypeIndArray = new int[]{1,2,4,7,11,15};
    int[] numTypeCumulArray = new int[]{1,3,7,14,25,40};

    int[] indItemCostArray = new int[numTypeCumulArray[5]];

    int num = 0;
    for (int i = 0; i < numTypeIndArray.length; i++) {
        for (int j = 0; j < numTypeIndArray[i]; j++) {
            indItemCostArray[num + j] = costArray[i];
        }
        num += numTypeIndArray[i];
    }

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

首先,你不需要int[] numTypeCumulArray = new int[]{1,3,7,14,25,40};

它只顯示numTypeIndArray的累積值。 最后一個值40只是numTypeIndArray的總和,這將是您要求的結果數組的大小。

它可以在一個簡單的 for 循環中求和,或者您可以這樣做,然后創建目標數組。

int maxSize = Arrays.stream(numTypeIndArray).sum();
int[] indItemCostArray = new int[maxSize];

然后,您可以繼續使用已顯示的值填充數組。 這是使用流的另一種方法,您無疑會了解它。 簡單的解釋是它創建了多個適當數量的成本流。

e.g
stream1 -> {3}
stream2 -> {5,5};
stream3 -> {9,9,9,9} etc.

然后它在這些值的單個流中將它們展平並返回一個數組。

int[] result = IntStream.range(0, costArray.length)
        .flatMap(i -> IntStream.range(0, numTypeIndArray[i])
                .map(q -> costArray[i]))
        .toArray();

但是使用一個類來保存信息會更好。 這是一個例子。

class Product {
    private String name;
    private int cost;
    private int quantity;
    public Product(String name, int cost, int quantity) {
        this.name = name;
        this.cost = cost;
        this.quantity = quantity;
    }
    public int getCost() {
        return cost;
    }
    public int getQuantity() {
        return quantity;
    }
    public String getName() {
        return name;
    }
    
    @Override 
    public String toString() {
        return new StringJoiner(", ","[", "]").add(name).add("cost="+cost).add("quantity="+quantity).toString();
    }
}

它可以像這樣使用。

List<Product> products = new ArrayList<>();
for (int i = 0; i < costArray.length; i++) {
        products.add(new Product("Item" + (i+1), costArray[i], numTypeIndArray[i]));
}
products.forEach(System.out::println);

印刷

[Item1, cost=3, quantity=1]
[Item2, cost=5, quantity=2]
[Item3, cost=9, quantity=4]
[Item4, cost=10, quantity=7]
[Item5, cost=11, quantity=11]
[Item6, cost=13, quantity=15]

再一次,它可以像以前一樣流式傳輸以創建您的結果,只需使用類getters來獲取值。

        
int[] result2 = products.stream()
        .flatMapToInt(
                prod -> IntStream.range(0, prod.getQuantity())
                        .map(q -> prod.getCost()))
        .toArray();

這兩個數組resultresult2是相同的。 但是您可能會發現使用類可以消除創建這樣一個數組的需要。

暫無
暫無

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

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