繁体   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