模式匹配在javascript中搜索

时间:2017-03-10 07:38:05

标签: javascript algorithm search binary-search

我正在尝试使用模式匹配的javascript二进制搜索。但问题是它在很多情况下失败了。

我试过这段代码。

function binarySearch(ar, el, compare_fn) {
    var m = 0;
    var n = ar.length - 1;
    while (m <= n) {
        var k = parseInt((n + m) / 2);
        var cmp = compare_fn(el, ar[k]);
        if (cmp > 0) {
            m = k + 1;
            console.log(cmp,m,ar[m],k)
        } else if(cmp < 0) {
            n = k - 1;
             console.log(cmp,n,ar[n],k)
        } else {
            return k;
        }
    }
    return -m - 1;
}

function compare_number(a, b) {
  var regExp = new RegExp(a, 'gi');
  var match= (regExp.test(b)?0:1);
  if(match){
     match=a.localeCompare(b);
  }
  return(match);
}

new function test() {
  var ar = ["job0000ya","job0002","job003","hello","myui",]; 
  var n = binarySearch(ar, "ya", compare_number);
     console.log([n]);
}();

但是这个特殊情况似乎失败了。建议我能做到这一点。

1 个答案:

答案 0 :(得分:0)

&#13;
&#13;
//The binary search algorithm
var binarySearch = (function() {
  /**
   * compare_complex
   *
   * @param {(number | string)} a
   * @param {(number | string)} b
   * @returns {number}
   */
  function compare_complex(a, b) {
    return a.toString().localeCompare(b.toString());
  }
  /**
   * compare_number
   *
   * @param {number} a
   * @param {number} b
   * @returns {number}
   */
  function compare_number(a, b) {
    return a - b;
  }
  /**
   * binarySearch
   *
   * @param {IBinarySearch} [args={ list: [], target: '' }]
   * @returns {number}
   */
  function binarySearch(args) {
    if (args === void 0) {
      args = {
        list: [],
        target: ''
      };
    }
    var params = {
      list: [],
      target: '',
      searchThreshold: 10,
      complex: false
    };
    for (var key in args) {
      if (args.hasOwnProperty(key) && params.hasOwnProperty(key)) {
        params[key] = args[key];
      }
    }
    var max = params.list.length - 1;
    var min = 0;
    if (params.list[min] == params.target) {
      return min;
    }
    if (params.list[max] == params.target) {
      return max;
    }
    var compare = (params.complex === true ? compare_complex : compare_number);
    while (max - min >= params.searchThreshold) {
      var diff = max - Math.floor((max - min) / 2);
      var cmp = compare(params.list[diff], params.target);
      if (cmp == 0) {
        return diff;
      } else if (cmp < 0) {
        min = diff;
      } else {
        max = diff;
      }
    }
    return params.list.slice(min, max).indexOf(params.target) + min;
  }
  return binarySearch;
})();
//------------SIMULATION------------//
//Global compare function for sorting
function compare_complex(a, b) {
  return a.toString().localeCompare(b.toString());
}
//Test array
var arr = [];
//Minimum test array length
var arrLength = 1000000;
//Populate
while (arr.length < arrLength) {
  arr = arr.concat(arr, ["job0000ya", "job0002", "job003", "hello", "myui"]);
}
//Target to find in haystack
var target = "job033";
//Add target to list
arr.push(target);
//Sort list (must be done before search)
arr = arr.sort(compare_complex);
//Actual test
setTimeout(function() {
  console.log("Looking for:", target, "among", arr.length, "rows");
  var t = Date.now();
  console.log("Result at index:", binarySearch({
    list: arr,
    target: target,
    complex: true
  }));
  console.log("Time(ms):", Date.now() - t);
  var index = binarySearch({
    list: arr,
    target: target,
    complex: true
  });
  console.log("5 nearest elements:", arr.slice(index - 2, index + 3));
}, 1000);
&#13;
&#13;
&#13;