2016-11-17 3 views
1

Целью этого алгоритма является возврат организованного массива (с валютой) изменения.Бесконечная петля, хотя я поставил перерыв;

Я построил вложенный цикл while, пока «изменение» не равно 0, тогда каждый цикл в функции while while «change» больше 0 (i.e: not -ve).

Что я пропустил?

// 
function checkCashRegister(price, cash, cid) { 
    var change = cash-price; 
    var chArr = [["PENNY", 0], 
["NICKEL", 0], 
["DIME", 0], 
["QUARTER", 0], 
["ONE", 0], 
["FIVE", 0], 
["TEN", 0], 
["TWENTY", 0], 
["ONE HUNDRED", 0]]; 

    while (change !== 0) { 
    while (change - 100 > 0) { 
     chArr[8][1] += 100; 
     change -=100; 
     if (change <= 0) {break;} 
    } 
    while (change - 20 > 0) { 
     chArr[7][1] += 20; 
     change -=20; 
     if (change <= 0) {break;} 
    } 
    while (change - 10 > 0) { 
     chArr[6][1] += 10; 
     change -=10; 
     if (change <= 0) {break;} 
    } 
    while (change - 5 > 0) { 
     chArr[5][1] += 5; 
     change -=5; 
     if (change <= 0) {break;} 
    } 
    while (change - 1 > 0) { 
     chArr[4][1] += 1; 
     change -=1; 
     if (change <= 0) {break;} 
    } 
    while (change - 0.25 > 0) { 
     chArr[3][1] += 0.25; 
     change -=0.25; 
     if (change <= 0) {break;} 
    } 
    while (change - 0.1 > 0) { 
     chArr[2][1] += 0.1; 
     change -=0.1; 
     if (change <= 0) {break;} 
    } 
    while (change - 0.05 > 0) { 
     chArr[1][1] += 0.05; 
     change -=0.05; 
     if (change <= 0) {break;} 
    } 
    while (change - 0.01 > 0) { 
     chArr[0][1] += 0.01; 
     change -=0.01; 
     if (change <= 0) {break;} 
    } 
    if (change <= 0) {break;} 

    } 
    // Here is your change, ma'am. 
    return chArr; 
} 

checkCashRegister(17.46, 20.00, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.10], ["QUARTER", 4.25], ["ONE", 90.00], ["FIVE", 55.00], ["TEN", 20.00], ["TWENTY", 60.00], ["ONE HUNDRED", 100.00]]); 
+0

Вы нарушаете только внутреннюю петлю? –

+1

Похоже, что этот код слишком сложный ... – Amessihel

+0

@Thomas В наружном цикле тоже есть перерыв. Но да, это слишком сложно – Hespen

ответ

3

Вам нужно просто проверить отдельные наличные части и использовать там только чек, если все остальное больше, то изменение. Не требуется условие нарушения во внутреннем цикле.

Не хватает, чтобы проверить, достаточно ли изменений.

function checkCashRegister(price, cash, cid) { 
 
    var change = cash-price; 
 
    var chArr = [["PENNY", 0], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]]; 
 

 
    while (change >= 100 && cid[8][1] >= 100) { 
 
     chArr[8][1] += 100; 
 
     cid[8][1] -= 100; 
 
     change -=100; 
 
    } 
 
    while (change >= 20 && cid[7][1] >= 20) { 
 
     chArr[7][1] += 20; 
 
     cid[7][1] -= 20; 
 
     change -=20; 
 
    } 
 
    while (change >= 10 && cid[6][1] >= 10) { 
 
     chArr[6][1] += 10; 
 
     cid[6][1] -= 10; 
 
     change -=10; 
 
    } 
 
    while (change >= 5 && cid[5][1] >= 5) { 
 
     chArr[5][1] += 5; 
 
     cid[5][1] -= 5; 
 
     change -=5; 
 
    } 
 
    while (change >= 1 && cid[4][1] >= 1) { 
 
     chArr[4][1] += 1; 
 
     cid[4][1] -= 1; 
 
     change -=1; 
 
    } 
 
    while (change >= 0.25 && cid[3][1] >= 0.25) { 
 
     chArr[3][1] += 0.25; 
 
     cid[3][1] -= 0.25; 
 
     change -=0.25; 
 
    } 
 
    while (change >= 0.1 && cid[2][1] >= 0.1) { 
 
     chArr[2][1] += 0.1; 
 
     cid[2][1] -= 0.1; 
 
     change -=0.1; 
 
    } 
 
    while (change >= 0.05 && cid[1][1] >= 0.05) { 
 
     chArr[1][1] += 0.05; 
 
     cid[1][1] -= 0.05; 
 
     change -=0.05; 
 
    } 
 
    while (change > 0 && cid[0][1] >= 0.01) { 
 
     chArr[0][1] += 0.01; 
 
     cid[0][1] -= 0.01; 
 
     change -=0.01; 
 
    } 
 
    
 
    // Here is your change, ma'am. 
 
    return chArr; 
 
} 
 

 
var register1 = [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.10], ["QUARTER", 4.25], ["ONE", 90.00], ["FIVE", 55.00], ["TEN", 20.00], ["TWENTY", 60.00], ["ONE HUNDRED", 100.00]], 
 
    register2 = [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.10], ["QUARTER", 4.25], ["ONE", 90.00], ["FIVE", 55.00], ["TEN", 20.00], ["TWENTY", 60.00], ["ONE HUNDRED", 100.00]]; 
 

 
console.log(checkCashRegister(17.46, 20.00, register1)); 
 
console.log(register1); 
 

 
console.log(checkCashRegister(19.50, 20.00, register2)); 
 
console.log(register2);
.as-console-wrapper { max-height: 100% !important; top: 0; }

+0

И, конечно же, вы могли бы поместить значения монет в массив и создать цикл за один раз; но давайте не будем этого делать для него :-) – RemcoGerlich

+0

Почему бы не по модулю? – mplungjan

+1

Все '' 'должны быть'> = '. – RemcoGerlich

-1

Вот причина: окончательная монета каждого вида никогда не добавляется в массив.

Скажите, что сумма составляет 0,02, 2 цента. Тогда в окончательном цикле,

while (change - 0.01 > 0) { 
    chArr[0][1] += 0.01; 
    change -=0.01; 
    if (change <= 0) {break;} 
} 

охранник (0.02 - 0.01 > 0) истинно, поэтому цикл вводится и изменение становится 0,01.

В следующий раз 0.01 - 0.01 > 0 is false, поэтому цикл не введен.

И тогда внешний цикл запускается снова и снова, потому что изменение все равно 0,01, и оно никогда не становится ниже.

Для того, чтобы > должен был быть >=. Затем все перерывы, а также весь внешний контур могут быть удалены.

+0

спасибо большое, это работает – BahaaZidan

+0

Я действительно удивляюсь, почему это было downvoted. – RemcoGerlich

0

Я думаю, что вы должны пересмотреть свой код:

function checkCashRegister(price, cash) { 
    var change = cash - price; 

    var chObj = { 
    PENNY: 0, 
    NICKEL: 0, 
    QUARTER: 0, 
    ONE: 0, 
    FIVE: 0, 
    TEN: 0, 
    TWENTY: 0, 
    ONE_HUNDRED: 0 
    } 

    // Performs an euclidian division to get the quotient 
    // (in 750$, there are 7 times 100 ie quotient = 7)  
    chObj.ONE_HUNDRED = Math.floor(change/100); 
    // Now get the remainder (750 minus 7 times 100) 
    change = change % 100; 

    // So on... 
    chObj.TWENTY = Math.floor(change/20); 
    change = change % 20; 

    chObj.TEN = Math.floor(change/10); 
    change = change % 10; 

    chObj.FIVE = Math.floor(change/5); 
    change = change % 5; 

    chObj.ONE = Math.floor(change); 

    change = Math.floor((change - Math.floor(change)) * 100); 

    chObj.QUARTER = Math.floor(change/20)/100; 
    change = change % 25; 

    chObj.NICKEL = Math.floor(change/10)/100; 
    change = change % 10; 

    chObj.NICKEL = Math.floor(change)/100; 

    return chObj; 
} 

var chObj = checkCashRegister(245, 1000); 

for (var key in chObj) { 
    if (chObj.hasOwnProperty(key)) { 
    console.log(key + " : \t" + chObj[key]); 
    } 
} 

Результат (для просмотра через консоль):

PENNY :  0 
NICKEL : 0 
QUARTER : 0 
ONE : 0 
FIVE : 1 
TEN : 1 
TWENTY : 2 
ONE_HUNDRED : 7 

Это может быть более улучшена я думаю. См. Скрипку here.

+0

Предполагается, что в кассовом аппарате есть неограниченное количество каждого номинала – mplungjan

+0

Код Аскера считается таким же, верно? – Amessihel

+0

Да, но намерение ясное - по-прежнему полезно использовать modulo – mplungjan

0

ваша проблема в том, что вы проверяете равенство 0 и ваше фактическое значение 0,00 .. [что-то] вы можете увидеть, что это известная проблема here

изменить последнее, если заявление будет if (change.toFixed(2) <= 0) {break;}

BTW Я предлагаю вам изменить все ваши расчеты денег на центы, чтобы избежать таких проблем (вместо 1.0 $ использовать 100 центов).

Смежные вопросы