最有效的方法来检查数字范围内的数字而不重复

时间:2015-12-28 03:33:37

标签: javascript algorithm numbers

给定一个数字n,最小数量min,最大数量max,确定最有效的方法是什么

  1. 号码n是否包含在范围内,包括min - max

  2. 号码n包含或不包含重复的数字

  3. 效率意味着方法或方法集需要最少量的计算资源,并在最短的时间内返回truefalse

  4. 上下文:if循环内的for条件,可能需要数千到数十万次迭代才能返回结果;返回truefalse以及Number检查所需的毫秒数可能会影响效果

  5. Profiles小组DevTools小组对71,3307个项目进行了迭代,下面的RegExp被列为使用27.2ms1097.3ms完成循环。在836,7628以下RegExp个项目的集合中使用了193.5ms,总共11285.3ms。{/ p>

    要求:在最短的时间内返回给定上述参数的Boolean truefalse的最有效方法。

    注意:解决方案不必限于RegExp;下面用作模式返回预期结果。

    当前js使用RegExp reRegExp.protype.test()

    
    
    var min = 2
    , max = 7
    , re = new RegExp("[" + min + "-" + max + "](.)(?!=\1)", "g")
    , arr = [81, 35, 22, 45, 49];
    
    for (var i = 0; i < arr.length; i++) {
      console.log(re.test(arr[i]), i, arr[i])
        /*
          false 0 81 
          true 1 35
          false 2 22
          true 3 45
          false 4 49 
        */
    }
    &#13;
    &#13;
    &#13;

2 个答案:

答案 0 :(得分:2)

关联数组方法:

这具有易于理解的优点。

"2015-12-28T04:04:07.626Z"

function checkDigits(min, max, n) {
    var digits = Array(10);                   // Declare the length of the array (the 10 digits) to avoid any further memory allocation
    while (n) {
        d = (n % 10);                         // Get last digit
        n = n / 10 >>0;                       // Remove it from our number (the >>0 bit is equivalent to compose(Math.floor, Math.abs))
        if (d < min || d > max || digits[d])  // Test if "d" is outside the range or if it has been checked in the "digits" array
            return false;
        else
            digits[d] = true;                 // Mark the digit as existing
    }
}

二元掩码方法:

这将使用一个实际上用作位数组的整数替换Array。它应该更快。

var min = 2
, max = 7
, arr = [81, 35, 22, 45, 49];

function checkDigits(min, max, n) {
    var digits = Array(10);                   // Declare the length of the array (the 10 digits) to avoid any further memory allocation
    while (n) {
        d = (n % 10);                         // Get last digit
        n = n / 10 >>0;                       // Remove it from our number (the >>0 bit is equivalent to compose(Math.floor, Math.abs))
        if (d < min || d > max || digits[d])  // Test if "d" is outside the range or if it has been checked in the "digits" array
            return false;
        else
            digits[d] = true;                 // Mark the digit as existing
    }
    return true;
}

for (var i = 0; i < arr.length; i++) {
  console.log(checkDigits(min, max, arr[i]), i, arr[i])
}

function checkDigits(min, max, n) {
    var digits = 0;                   
    while (n) {
        d = (n % 10);                         
        n = n / 10 >>0;
        if (d < min || d > max || (digits & (1 << d)))
            return false;
        else
            digits |= 1 << d;
    }
    return true;
}

二进制掩码方法的说明:

function checkDigits(min, max, n) { var digits = 0; while (n) { d = (n % 10); n = n / 10 >>0; if (d < min || d > max || (digits & (1 << d))) return false; else digits |= 1 << d; } return true; }创建一个位掩码,一个设置为1 << d位且所有其他位设置为0的整数。 d在整数digits |= 1 << d上设置由位掩码标记的位 digits将我们的位掩码标记的位与digits & (1 << d)(先前标记的位的集合)进行比较 如果您想详细了解这一点,请参阅fseek()上的文档。

所以,如果我们检查626,我们的数字会是这样的:

digits

答案 1 :(得分:0)

解决方案1 ​​

使用正则表达式进行测试

var min = 2;
var max = 7;
res = "";
arr = [81, 35, 22, 45, 49]
arr.push("");
regex=new RegExp("[" + min + "-" + max + "](.)(?!=\1)", "g")
var result = arr.reduce(function(a, b) {
  if (regex.test(a)) {
    res = res + a + " is true\n"
  } else {
    res = res + a + " is false\n"
  };
  return b
});
console.log(res)

reduce方法在某种意义上是不同的,就像python中的生成器函数一样(在运行中产生输出)

它使用回调函数简单地循环遍历数组中的每个元素。我不能说减少功能有多高效。

然而考虑数组中的两个元素

81                             35          
^
take this value            take the result
and do something           from the previous 
                           element and add it
                           to the result computed
                           for this element  

更多信息https://msdn.microsoft.com/en-us/library/ff679975%28v=vs.94%29.aspx

SOlution 2

使用list存储值及其布尔值

var min = 2;
var max = 7;
res = [""];
arr = [81, 35, 22, 45, 49]
arr.push("");
regex=new RegExp("[" + min + "-" + max + "](.)(?!=\1)", "g")
var result = arr.reduce(function(a, b) {
  if (regex.test(a)) {
    res.push([a,true])
  } else {
    res.push([a,false])
  };
  return b
});
console.log(res)