简体   繁体   English

如何从两个创建一个新数组并根据原始数组中的值初始化新数组

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

I'm new to Java, and I'm not sure how to ask the right question, so please bear with me.我是 Java 新手,我不确定如何提出正确的问题,所以请耐心等待。 I have 40 total items of 6 different types to put into a new array;我总共有 6 种不同类型的 40 个项目要放入一个新数组中; each item type has a different cost.每种物品类型都有不同的成本。 The first item (quantity=1) costs $3, the second item (qty=2) costs $5 each, the third item (qty=4) costs $9 each, and so on.第一个项目(数量=1)花费 3 美元,第二个项目(数量=2)每个花费 5 美元,第三个项目(数量=4)花费 9 美元,依此类推。 The quantity of each item type is in numTypeIndArray and the cost for each type is in costCSDriverArray .每个项目类型的数量在numTypeIndArray ,每个类型的成本在costCSDriverArray A cumulative count of the total items is in numTypeCumulArray .总项目的累积计数在numTypeCumulArray

So, the new array, indItemCostArray , should be single dimensional and have 40 elements.因此,新数组indItemCostArray应该是一维的并且有 40 个元素。 It would look something like {3,5,5,9,9,9,9,...,13,13,13} , but the last fifteen elements are a cost of $13.它看起来像{3,5,5,9,9,9,9,...,13,13,13} ,但最后 15 个元素的成本为 13 美元。 How do I get to this array with 40 elements?如何使用 40 个元素访问这个数组? I started with trying to fill the array using a nested for loop but I haven't gotten there yet.我开始尝试使用嵌套的 for 循环填充数组,但我还没有到达那里。 The code below is plain wrong.下面的代码是完全错误的。

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];
    }
}

First of all, you'll get a ArrayOutOfBoundException at:首先,您将在以下位置获得ArrayOutOfBoundException

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

The size of the array numTypeCumulArray is 6, and arrays are 0 indexed.数组numTypeCumulArray的大小为 6,数组索引为 0。 So, The last index number is 5, not 6, as indexing started from 0.因此,最后一个索引号是 5,而不是 6,因为索引从 0 开始。

You can do as follows for accessing the last element of the array:您可以执行以下操作来访问数组的最后一个元素:

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

Secondly, you're running your outer loop for 40 times and for each iteration your inner loop is trying to iterate for numTypeIndArray[i] times, where i is the iterator variable of outer loop.其次,您运行外循环40次,每次迭代时,内循环尝试迭代numTypeIndArray[i]次,其中i是外循环的迭代器变量。 So, surely after sixth iteration, when value of i will be 6 , your program will again throw the ArrayOutOfBoundException as you're accessing a value in the terminator condition of the inner loop from numTypeIndArray whose last index is 5.因此,肯定在第六次迭代之后,当i值为6 ,您的程序将再次抛出ArrayOutOfBoundException因为您正在从numTypeIndArray的最后一个索引为 5 访问内循环的终止符条件中的值。

Again, inside the inner loop, you're assigning indItemCostArray at index position i+j , which will actually far from your purpose.同样,在内部循环中,您在索引位置i+j处分配indItemCostArray ,这实际上与您的目的相去甚远。

To achieve what you are exactly expecting, you can do as follows:要实现您的期望,您可以执行以下操作:

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];
}

Here, what I did is, in the outer loop I iterated the same amount of time the length of costArray , you can take the length of numTypeIndArray instead too, no issue.在这里,我所做的是,在外循环中,我迭代了与costArray的长度相同的时间,您也可以采用numTypeIndArray的长度,没问题。 I've defined a variable named currentIndex to keep track of the current assignable index for array indItemCostArray .我定义了一个名为currentIndex的变量来跟踪数组indItemCostArray的当前可分配索引。 In the inner loop, I tried to begin with the currentIndex and loop upto the time same as the number of items needed for that type, given in numTypeIndArray[costIndex] , and for each iteration, set the corresponding index of indItemCostArray with the cost of costIndex in the costArray .在内部循环中,我尝试从currentIndex开始并循环到与该类型所需的项目数相同的时间,在numTypeIndArray[costIndex] ,并且对于每次迭代,设置indItemCostArray的相应索引的成本为costIndex中的costArray Finally, I update the currentIndex with the corresponding cumulative total items from numTypeCumulArray .最后,我用来自numTypeCumulArray的相应累积总项目更新 currentIndex 。

Hope you got everything clear.希望你一切都清楚。

The whole setup of three arrays is kind of weird.三个阵列的整个设置有点奇怪。 The weiredest is the third array.最奇怪的是第三个数组。 Think carefully, do you actually need it?仔细想想,你真的需要它吗? You already have all the information in your second array.您已经拥有第二个数组中的所有信息。 The third array can introduce a lot of unnacessary mistakes.第三个数组会引入很多不必要的错误。

But, assuming that you actually need these arrays for some reason and there are no mistakes in making these arrays.但是,假设您出于某种原因确实需要这些数组,并且制作这些数组没有错误。 You can get your required fourth array as follows,您可以获得所需的第四个数组,如下所示,

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));

First, you don't need int[] numTypeCumulArray = new int[]{1,3,7,14,25,40};首先,你不需要int[] numTypeCumulArray = new int[]{1,3,7,14,25,40};

It just shows the cumulative values of the numTypeIndArray .它只显示numTypeIndArray的累积值。 The last value, 40 is just the sum of numTypeIndArray and that would be the size of the resulting array from your requirement.最后一个值40只是numTypeIndArray的总和,这将是您要求的结果数组的大小。

It can be summed in a simple for loop or you can do it like this and then create the target array.它可以在一个简单的 for 循环中求和,或者您可以这样做,然后创建目标数组。

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

Then you could proceed to populate the array with the values as has been shown.然后,您可以继续使用已显示的值填充数组。 Here is another way using streams which you will undoubtedly learn about.这是使用流的另一种方法,您无疑会了解它。 The quick explanation is that it creates multiple streams of the proper quantities of cost.简单的解释是它创建了多个适当数量的成本流。

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

Then it flattens them in a single stream of those values and returns an array.然后它在这些值的单个流中将它们展平并返回一个数组。

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

But using a class to hold the information would be better.但是使用一个类来保存信息会更好。 Here is one example.这是一个例子。

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();
    }
}

And it can be used like so.它可以像这样使用。

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);

Prints印刷

[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]

And once again it can be streamed to create your results exactly as before only using the class getters to get the values.再一次,它可以像以前一样流式传输以创建您的结果,只需使用类getters来获取值。

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

The two arrays result and result2 are identical.这两个数组resultresult2是相同的。 But you may find that using classes may eliminate the requirement for creating such an array.但是您可能会发现使用类可以消除创建这样一个数组的需要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM