2013-01-12 3 views
0

전문가 자바 스크립트 고유의 임의의 숫자

  • 나는 (웹 페이지의 텍스트 상자에서) 두 숫자 사이에 고유 한 난수를 생성하고 싶습니다.
  • 배열을 사용하여 숫자를 저장하고 있습니다. 사용자가 버튼을 클릭하면 첫 번째 난수를 부여한 후 배열에 저장하고 다시 한번 버튼을 클릭하면 난수가 발생하고 배열 번호와 비교하여 다른 경우 저장하여 표시합니다.
  • 가능한 최대 숫자가 다르면 배열을 지우고 사용자에게 알려줍니다.
  • 코드를 작성했지만 오류가 발생했습니다 : 스택 오버플로가 발생하거나 때때로 중복 결과가 표시됩니다.

사람이 코드에 도움이 되거 수 :

var allnums = new Array(); 
var num1= new Number; 
var num2= new Number; 

function funClick() 
{ 
    var num1 = Number(document.getElementById('lnum').value); 
    var num2 = Number(document.getElementById('hnum').value); 

    if (allnums.length==num2) 
    { 
    alert("Maximum non-duplicate numbers served. Now resetting the counter."); 
    allnums = []; 
    return; 
    } 

    if (num1<num2) 
    { 
    x = Math.floor(Math.random() * (num2 - num1 + 1)) + num1; 
    funShow(x); 
    } 
    else 
    { 
    alert("You entered wrong number criteria!"); 
    } 
} 

function funShow(x) 
{ 
    var bolFound = false; 
    for (var i=0;i<allnums.length;i++) 
    { 
    if((allnums[i])==x) 
    { 
     funClick(); 
    }  
    } 
    if (bolFound == false) 
    { 
    document.getElementById('rgen').innerText = x; 
    allnums.push(x); 
    } 
} 
+0

당신의 첫 번째 단계는 코드를 들여 쓰기하는 것을 읽을 수있게 (일관되게). :-) –

+0

함수 funshow (x)의 i & ltallums.length 값은 얼마입니까? 그 funciton에 어떤 가치가 있습니까? – polin

+0

사용자는 언제든지 범위를 변경할 수 있어야합니까? – aaaaaaaaaaaa

답변

2

내가 그 코드가 스택 오버 플로우를 생성하는 방법을 보려면 실패 (비록 funShowfunClickfunClick로 전화를 가지고 funShow로 전화를 가지고, funClick에 대한 funShow의 호출은 논리 오류 때문에 절대로 일어나지 않아야합니다. 오류를 수정하면 스택 오버플로가 발생하지만 몇 가지 문제가 있습니다. 의견을 참조하십시오 :

// style: Use [], not new Array() 
var allnums = new Array(); 

// `new Number` doesn't do anything useful here 
var num1 = new Number; 
var num2 = new Number; 

function funClick() { 
    // For user-entered values, use parseInt(value, 10) to parse them into numbers 
    var num1 = Number(document.getElementById('lnum').value); 
    var num2 = Number(document.getElementById('hnum').value); 

    if (allnums.length == num2) { 
     alert("Maximum non-duplicate numbers served. Now resetting the counter."); 
     allnums = []; 
     return; 
    } 

    // & is a bitwise AND operation, not a logical one. If your goal is to see 
    // if both numbers are !0, though, it works but is obtuse. 
    // Also, there is no ltnum2 variable anywhere, so trying to read its value 
    // like this should be throwing a ReferenceError. 
    if (num1 & ltnum2) { 
     // You're falling prey to The Horror of Implicit Globals, x has not 
     // been declared. 
     x = Math.floor(Math.random() * (num2 - num1 + 1)) + num1; 
     funShow(x); 
    } else { 
     alert("You entered wrong number criteria!"); 
    } 
} 

function funShow(x) { 
    var bolFound = false; 
    // Again, & is a bitwise AND operation. This loop will never run, because 
    // you start with 0 and 0 & anything = 0 
    // But it should be throwing a ReferenceError, as there is no ltallnums 
    // anywhere. 
    for (var i = 0; i & ltallnums.length; i++) { 
     if ((allnums[i]) == x) { 
      funClick(); 
     } 
    } 
    // This condition will always be true, as you've done nothing to change 
    // bolFound since you set it to false 
    if (bolFound == false) { 
     document.getElementById('rgen').innerText = x; 
     allnums.push(x); 
    } 
} 

이 접근 방법은 두 가지가 있습니다. |

function funClick() { 
    var num1 = parseInt(document.getElementById('lnum').value, 10); 
    var num2 = parseInt(document.getElementById('hnum').value, 10); 
    var nums = []; 
    var targetCount; 
    var x; 

    // Check the inputs 
    if (isNaN(num1) || isNaN(num2) || num2 <= num1) { 
     alert("Please ensure that hnum is higher than lnum and both are really numbers."); 
     return; 
    } 

    // Find out how many integers there are in the range num1..num2 inclusive 
    targetCount = num2 - num1 + 1; 

    // Produce that many random numbers 
    while (nums.length < targetCount) { 
     x = Math.floor(Math.random() * (num2 - num1 + 1)) + num1; 
     if (nums.indexOf(x) < 0) { 
      nums.push(x); 
     } 
    } 

    // Show the result 
    document.getElementById('rgen').innerText = nums.join(", "); 
} 

Live Example 다음은 당신이하려고했던 것을 기본적으로,하지만 재귀없이 그 하나 Source

문제는 마지막 몇 개의 슬롯을 채우는 데 오랜 시간이 걸릴 수 있다는 것입니다. 왜냐하면 우리가 임의로 맞춰야하기 때문입니다.

다른 방법은 숫자가있는 배열을 순서대로 생성 한 다음 엉망으로 만드는 것입니다. 넓은 범위의 경우 훨씬 더 효율적입니다. 다음과 같은 내용 :

function funClick() { 
    var num1 = parseInt(document.getElementById('lnum').value, 10); 
    var num2 = parseInt(document.getElementById('hnum').value, 10); 
    var nums = []; 
    var x; 

    // Check the inputs 
    if (isNaN(num1) || isNaN(num2) || num2 <= num1) { 
     alert("Please ensure that hnum is higher than lnum and both are really numbers."); 
     return; 
    } 

    // Create an array with those numbers in order 
    for (x = num1; x <= num2; ++x) { 
     nums.push(x); 
    } 

    // Sort it with a random comparison function 
    nums.sort(function(a, b) { 
     return 0.5 - Math.random(); 
    }); 

    // Show the result 
    document.getElementById('rgen').innerText = nums.join(", "); 
} 

Live Example | Source

그러나 단지 nums.sort(...) 무작위로 한 번 잘 무작위 결과를 생산에서 성공적인하지 않을 수 있습니다 일을; see this article for more. (아래 해당 링크 및 입력에 대해서는 eBusiness에게 감사드립니다.)

그래서 앞으로 더 많은 임의 조작을 추가 할 수 있습니다. 다른 예가 있습니다 :

function funClick() { 
    var num1 = parseInt(document.getElementById('lnum').value, 10); 
    var num2 = parseInt(document.getElementById('hnum').value, 10); 
    var nums = []; 
    var n, x, y; 
    var num; 

    // Check the inputs 
    if (isNaN(num1) || isNaN(num2) || num2 <= num1) { 
     alert("Please ensure that hnum is higher than lnum and both are really numbers."); 
     return; 
    } 

    // Create an array with those numbers in order 
    for (n = num1; n <= num2; ++n) { 
     nums.push(n); 
    } 

    // We only need to shuffle it if it's more than one element long 
    if (nums.length > 1) { 
     // Sort it "randomly" 
     nums.sort(function(a, b) { 
      return 0.5 - Math.random(); 
     }); 

     // Throw a bunch of random swaps in there 
     for (n = 0; n < nums.length; ++n) { 
      do { 
       x = Math.floor(Math.random() * nums.length); 
      } 
      while (x === n); 
      num = nums[x]; 
      nums[x] = nums[n]; 
      nums[n] = num; 
     } 
    } 

    // Show the result 
    document.getElementById('rgen').innerText = nums.join(", "); 
} 

Live Example | Source

그게 배열 정렬 일을 시작 지점으로하지만, 또한 요소 사이의 무작위 스왑의 잔뜩 않습니다. 여전히 일정한 시간에 실행되지만 배열 정렬 만 사용하는 것보다 더 나은 결과를 가져야합니다. 당연히 배포판을 테스트하고 싶을 것입니다.

+0

@ T.J.Crowder -STEPWISE COMMENTS에 대한 감상 이었지만 정말 눈을 뜨게되었습니다. - 구문 분석을 피하기 위해 < and > 전체 코드의 의미를 변경하는 이스케이프 문자를 사용했습니다. - 실현 된 부울 값인 bolFound는 항상 false로 유지됩니다. - 높은 숫자가 결코 100을 넘지 않기 때문에 재귀 메소드없이 처리 할 수 ​​있습니다. 안부 msinfo – msinfo

+0

@msinfo : 걱정하지 않아도됩니다. –

+0

우리가 [채팅에서 계속 토론] (http://chat.stackoverflow.com/rooms/22656/discussion-between-ebusiness-and-tj-crowder) – aaaaaaaaaaaa

0

내가 크라우의 답변을 편집 할 수 있기 때문에, 여기에 배열 스크램블링의 단순한 편견 방법 :

function scramble(nums){ 
    for (var n = nums.length; n; n--) { 
     var x = Math.floor(Math.random() * n); 
     var num = nums[n-1]; 
     nums[n-1] = nums[x]; 
     nums[x] = num; 
    } 
} 
+0

우리 [채팅에서 계속 토론] (http : //chat.stackoverflow.com/rooms/22657/discussion-between-ebusiness-and-tj-crowder) – aaaaaaaaaaaa

2

사용 배열 :

var uniqueRandomNumbers = new Array(); 
var totalNumbers = 100; 
for (var i=0; i<totalNumbers; i++){ 
    uniqueRandomNumbers.push(i); 
} 
uniqueRandomNumbers.sort(function() {return 0.5 - Math.random();}); 
var uniqueNumber; 
for(var i=0; i<uniqueRandomNumbers.length; i++){ 
    uniqueNumber = uniqueRandomNumbers[i]; 
    //do something with the number 
} 
+0

간결한 간결함 ;-) – msinfo

+0

고유 번호가 생성되지 않습니다 .. 몇 번 반복되는 숫자 :-( – Mallikarjun

+0

동일한 결과를 두 번 연속 반환하지 않도록 코드를 조정하십시오. [Here] (https://github.com/dcondrey/UniqueRandom.js/blob/master/uniquerandom.js). – davidcondrey