제로베이스 JavaScript 05)기본문제풀이 - 무한뺄셈.js 알고리즘을 풀다가 이 에러가 나타났다.
처음 보는 에러여서 구글링을 했고 나와 같은 오류를 발생한 stackoverflow 사용자를 찾았다.
아직 내 오류를 해결하지 못했지만, 이 사람의 게시글을 번역하며 이 에러에 대해 이해해보려고 한다.
질문 :
The code consists of making an array from a range of numbers and / as well having a third argument / in which it indicates the steps from the numbers, / if it has a step of 2 well for example it goes from [1,3,5] the code works fine / except when I pass step with a negative number as an argument e.g. NumberRange(10,5,-2); / That's when the error appears, in the code it shows the logic I used for a negative step.
코드는 다양한 숫자의 배열을 만드는 것으로 구성되어 있고, 숫자들의 step을 나타내는 세번째 인수를 가지고 있습니다. 만약 이것이 step: 2 라면 [1, 3, 5]으로 코드가 잘 작동합니다. 제가 음수를 인수로써 패스하는 경우를 제외하고 e.g. NumberRange(10,5,-2);. 그러면 오류가 나타나는데, 코드에서 제가 음수 step을 사용한 논리를 보여줍니다.
function NumberRange(start, end, step){
var numberList = [];
if(typeof(step) == 'undefined'){
if(start < end){
for(;start <= end; start++){
numberList.push(start);
}
console.log(numberList);
}
else if(start > end){
for(;start >= end;){
numberList.push(start);
start -= 1;
}
console.log(numberList);
}
}
else if(start > end && (Math.sign(step) == -1)){ // This is the logic I created when a negative step is given as an argument.
for(;start >= end; start - step){
numberList.push(start);
}
console.log(numberList);
}
else if(start < end && (Math.sign(step) == -1)){
console.log("Negative step cant work since the value of the beginning of the list is less than the end of it")
}
else{
for(;start <= end;){
numberList.push(start);
start += step;
}
console.log(numberList);
}
//return numberList;
};
NumberRange(10,5,-2);
답변 :
for(;condition;) is just an ugly way of writing while(condition), don't do it.
Why it doesn't work is the for(;start >= end; start - step) part, / which doesn't update start, just subtracts step from it and throws the result away. / Why it wouldn't work with - is that step is negative in that branch, / so it should be start += step in order to count downwards.
Generally you don't need the 4 branches, / instead you could set step to +/-1 if it's undefined, and if you really wanted to, you could still validate the sign of step after setting it but before using it:
for( ; 조건 ; ) 은 그저 while( 조건 )을 예쁘지 않게 쓰는 방법입니다. 하지 마세요.
작동하지 않은 이유는 for(;start >= end; start - step) 부분입니다(start가 갱신되지 않고 step만 빼고 결과를 버리는).
- (마이너스)를 사용해서 안되는 이유는 그 지점에서 그 step이 음수 이기 때문입니다, 따라서 아래쪽으로 카운트하려면 start += step을 사용해야 합니다.
일반적으로 4개의 분기는 필요하지 않습니다, 대신 그것이 undefined일 때 당신은 step을 +/-1로 설정할 수 있습니다, 그리고 당신이 정말 원한다면, 당신은 설정 후 사용 전에 단계 부호의 유효성을 확인할 수 있습니다.
function NumberRange(start, end, step) {
if (typeof(step) == 'undefined') {
step = Math.sign(end - start);
}
if (Math.sign(step) != Math.sign(end - start)) {
console.log(`Can't count from ${start} to ${end} using ${step} as stepsize.`);
} else {
var numberList = [];
if (start > end) {
while (start > end) {
numberList.push(start);
start += step;
}
} else {
while (start < end) {
numberList.push(start);
start += step;
}
}
console.log(numberList.join());
return numberList;
}
}
NumberRange(10, 5, -2);
NumberRange(1, 2);
NumberRange(2, 1);
NumberRange(1, 3, 2);
NumberRange(1, 3, -2);
NumberRange(3, 1, -2);
NumberRange(3, 1, 2);
Then someone may get annoyed with having two loops with identical bodies, and after all, with a bit more complicated condition they can be collapsed into one:
그러면 누군가가 동일한 몸체를 가진 두 개의 loops를 가진 것에 대해 기분이 나쁠 수 있고, 결국, 조금 더 복잡한 조건이라면 그것들은 하나로 붕괴될 수(합칠 수) 있다.
function NumberRange(start, end, step) {
if (typeof(step) == 'undefined') {
step = Math.sign(end - start);
}
if (Math.sign(step) != Math.sign(end - start)) {
console.log(`Can't count from ${start} to ${end} using ${step} as stepsize.`);
} else {
var numberList = [];
while ((step > 0 && start < end) || (step < 0 && start > end)) {
numberList.push(start);
start += step;
}
console.log(numberList.join());
return numberList;
}
}
NumberRange(10, 5, -2);
NumberRange(1, 2);
NumberRange(2, 1);
NumberRange(1, 3, 2);
NumberRange(1, 3, -2);
NumberRange(3, 1, -2);
NumberRange(3, 1, 2);
마지막으로 오류가 나는 내 코드를 작성하겠다.
/* user code */
function answer(s, e) {
let squence = [];
squence.push(s);
squence.push(e);
// 코드 구현 시작 영역
while (s - e >= 0) {
squence.push(s - e);
s = squence[squence.indexOf(s) + 1];
e = squence[squence.indexOf(e) + 1];
}
// 코드 구현 종료 영역
return squence;
}
/* main code */
let input = [
// TC : 1
[9, 3],
// TC : 2
[6, 3],
// TC : 3
[13, 7],
];
for (let i = 0; i < input.length; i++) {
process.stdout.write(`#${i + 1}`);
console.log(answer(input[i][0], input[i][1]));
}
디버깅을 통해 왜 Error가 났는지 찾았다.
TC : 1은 잘 수행 된다.
// output: [9, 3, 6] 3 - 6 == -3 이기 때문에 break; 된다.
TC : 2에서 문제가 발생한다.[6, 3, 3, 0] 까지는 잘 수행된다.
하지만 2번째 while문에서 e = squence[squence.indexOf(e) + 1] 이 수행되지 않아
s = 3, e = 0 으로 3번째 while문이 수행되어야 할 것이
s = 3, e = 3으로 수행된다.
그래서 3번째 while문의 결과값도 0이 된다.
s와 e의 index가 바뀌지 않고 계속 3으로 고정되어 while 문이 수행되기 때문에 overflow 문제가 발생한 것이다.
// output: [6, 3, 3, 0, 0, 0, 0, ... ] error
< squence[squence.indexOf(e) + 1] 가 수행되지 않은 이유 >
[6, 3, 3] 에서 s = e = 3 이 된다.
indexOf(e) 은 그 배열의 첫번째 요소만 가져오기 때문에,
indexOf(e), indexOf(s) 의 값으로 항상 1이 나온다.
그러므로 squence[1] - squence[1] 을 하게 되므로 계속 0이 나오는 것이었다.
한 배열 안에 같은 값이 2개 이상 존재할 때 indexOf()를 사용하는 것은 좋지 않다.
해결 코드 (코딩 메이트 코드)
function answer(s, e) {
let squence = [];
let idx = 0; // 기준 값
squence.push(s);
squence.push(e);
// 코드 구현 시작 영역
while (true) {
if(s-e < 0 ) break;
else squence.push(s - e);
s = squence[++idx];
e = squence[idx+1];
}
// 코드 구현 종료 영역
return squence;
}
/* main code */
let input = [
// TC : 1
[9, 3],
// TC : 2
[6, 3],
// TC : 3
[13, 7],
];
for (let i = 0; i < input.length; i++) {
process.stdout.write(`#${i + 1}`);
console.log(answer(input[i][0], input[i][1]));
}
index 변수를 따로 선언해어 (idx)while문이 돌아갈 때마다 값이 증가하는 방식으로 코드를 짰다.
강사님 코드
/* user code */
function answer(s, e) {
let squence = [];
squence.push(s);
squence.push(e);
let sum;
while (1) {
sum = s - e;
s = e;
e = sum;
if (sum < 0) break;
squence.push(e);
}
return squence;
}
/* main code */
let input = [
// TC : 1
[9, 3],
// TC : 2
[6, 3],
// TC : 3
[13, 7],
];
for (let i = 0; i < input.length; i++) {
process.stdout.write(`#${i + 1}`);
console.log(answer(input[i][0], input[i][1]));
}
Why its giving me this error # Fatal error in , line 0 # Fatal JavaScript invalid size error 169220804?
The code consists of making an array from a range of numbers and as well having a third argument in which it indicates the steps from the numbers, if it has a step of 2 well for example it goes fro...
stackoverflow.com
Comment