简体   繁体   中英

Can someone explain why this does not work?

I'm going through the interview cake algorithms. This is basically self-assigned homework. I've given it a few goes, and my solution is fairly ugly, but I don't understand why it's not giving me the correct output. Only one loop executes in the algorithm, and I've tried switching the order, as well as other versions along this line.

I'm a little stuck here, and have two questions relating to this algorithm, which I'm trying to complete in straight-up Javascript.

Here's the problem:

You have an array of integers, and for each index you want to find the product of every integer except the integer at that index. Write a function get_products_of_all_ints_except_at_index() that takes an array of integers and returns an array of the products. Do not use division.

The array [1, 7, 3, 4]

Would return:

[84, 12, 28, 21]

By calculating:

[7*3*4, 1*3*4, 1*7*4, 1*7*3]

My overwrought attempt is below:

var l = [84, 12, 28, 21],
    products_before_curr_index = 1,
    products_after_curr_index = 1,
    backwards_index=1,
    forwards_index,
    product_array = []; 
for(var factor=0; factor<l.length; factor++){
    forwards_index=factor+1;
    while(forwards_index<l.length){
    products_after_curr_index*=l[forwards_index]; 
    forwards_index+=1; 
    }
    if(factor>0){
    products_before_curr_index *= l[factor-backwards_index];
    backwards_index+=1; 
    }
  product_array.push(products_after_curr_index*products_before_curr_index);
  backwards_index=1; 
  products_after_curr_index = 1;
  products_before_curr_index=1;
}

This returns [84, 12, 28, 3]

My questions:

  1. Why doesn't this work? Where am I going wrong?
  2. There must be a more elegant way to do this using slice or map. I'm stumped. Can someone give me a hint here?

This one uses map and reduce methods of Array object.

function get_products_of_all_ints_except_at_index(inList) {

    var product = function (x, y) { return x * y; };

    var lists = inList.map(function (v, i, a) {
        return a.slice(0, i).concat(a.slice(i + 1, a.length));
    });

    return lists.map(function (v, i, a) { return v.reduce(product); });

}

// test case
console.log(get_products_of_all_ints_except_at_index([1, 7, 3, 4]));

Yeah it looks like you have overcomplicated it a bit. The problem description gives you a bit of a hint on how to solve the problem. For each integer in the array, you want to find the product of all the other integers. In other words, you can loop over each item in the array, then loop over each item in the array again (aka, a nested loop) and add up all the products except for the current index of the first array.

For example:

var a = [1, 7, 3, 4];
var b = [];

a.forEach(function( value_1 ) {
    var product = 1;

    a.forEach(function( value_2 ) {
        if ( value_1 != value_2 )
            product *= value_2;
    });

    b.push( product );
});

console.log( b ); // [84, 12, 28, 21]

Your original solution doesn't work because you only ever go back once. You use a while loop to go forward through the entire array to calculate the product of all the elements after, but you only use one single calculation to go backwards:

products_before_curr_index *= l[factor-backwards_index];

So you're only ever getting the product of the value immediately before the current index. You never go back further. If you're wondering, you only happen to get the third value ( 28 ) right because the first number is 1 (aka, multiplying by 1 wouldn't have done anything anyway). Try changing that first number to anything that isn't 1 and you'll see that the third calculation also fails.

I didn't particularly liked the solution given by Interview Cake, I felt it was complicated. I may not have the most optimized solution, and I used Numpy which is not clear if we can (but it doesn't say we can't, so...)

It worked for all test cases and I feel it's way more simple/easy to grasp:

` import numpy as np

def get_products_of_all_ints_except_at_index(int_list):

    if len(int_list) < 2:
        raise IndexError("you need two numbers at least")

    products = []
    for i in range(len(int_list)):
        temp_list = int_list.copy()
        del temp_list[i]
        prod = np.prod(temp_list)
        products.append(prod)

    return products

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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