使用二进制搜索使用Javascript在排序数组中查找数字的所有出现

时间:2019-02-21 11:17:28

标签: javascript binary-search

我最近开始学习JavaScript的算法。当我遇到这个问题时,我正在尝试二进制搜索,并且一直在尝试实现它,但是我仍然遇到困难。 该函数接受两个参数(排序后的数组和一个数字),并返回一个object,其中包含数字的出现和计数。我得到的occurrence不是数字的正确出现,而count是常数。

这是我到目前为止所做的:

function binarySearchOccurrence(array, element) {
    //declare the start index on the left side to zero
      let startIndex = 0;

      //declare the end index on the right side to the length of array minus 1
      let endIndex = array.length - 1;

      //set initial count to zero
      let count = 0;
      let occurrence = 0;

      //declare an empty object to hold the result of search and count 
      const result = {}

      //Applying binary search, iterate while start does not meed end
     while(startIndex <= endIndex){
          //find the middile index
          let middle = Math.floor((startIndex + endIndex)/2); 
              let guessElement = array[middle];
              count++;
              //if element is present in the middle, increment occurence
          if(guessElement === element){
                  occurrence++;

            while(startIndex <= endIndex){

                if(guessElement > element){
                    endIndex = middle - 1;
                    occurrence++;
                    break;

                } else {
                    startIndex = middle + 1;
                    occurrence++;
                    break;
                } 
            } 

              //Else look in the left or right side accordingly
          } else if (guessElement > element) {
                  endIndex = middle - 1;

          } else {
                  startIndex = middle + 1;
          }
      }
          result.occurrence = occurrence;
          result.count = count;
          return result;
  } 

当我使用这样的数组进行测试时:binarySearchOccurrence([1, 2, 3, 4, 4, 4, 5, 5, 5, 6, 7, 8, 9], 5)它返回{ occurrence: 6, count: 4 }而不是{ occurrence: 3, count: 2 };

3 个答案:

答案 0 :(得分:0)

您的代码会为每次出现重复计数。

说我们得到了一个数组[5,5,5,5],5。从0,3开始作为开始,结束。 中= 1 因此出现次数将变为1(如果出现则为第一个) 然后在while循环中 否则将计算出else部分,因此出现次数变为2。 现在您以2,3开始,因此mid为2,这又由第一个if语句计算。

替代方法:

  • 使用二进制搜索功能返回元素的位置。跑 直到发现中间说x为止都是第一次。
  • 再次运行它以使0到x-1,x + 1结束
  • 执行此操作,直到上半年搜索没有结果 和搜索的后一半
  • 搜索的最新已知结果可以 减去以计算出现的次数。

我的方法示例。

[1、2、3、4、4、4、4、4、4、5、6、7、8]

binarysearch = bs(arr,val,start,end)=返回val在else -1数组中的位置

pos=bs(arr,val,start,end)
a=pos-1
ppos_a=a
while a!=-1 and a-1>=0:
    ppos_a=a
    a=bs(arr,val,0,a-1)

b=pos+1
ppos_b=b
while b!=-1 and b+1<=len-1:
    ppos_b=b
    b=bs(arr,val,b+1,len-1)

result = ppos_b-ppos_a

这应该使您计数。我对复杂性有点怀疑,但似乎是c log n其中c << n

答案 1 :(得分:0)

尝试使用此方法,但是在这种情况下,复杂度将不会是O(n),BST允许右或左子级中的一个等于根节点,将需要额外的计算步骤才能完成对重复节点的搜索被允许。 Are duplicate keys allowed in the definition of binary search trees?

function binarySearchOccurrence(array, element) {

      //declare the start index on the left side to zero
      let startIndex = 0;

      //declare the end index on the right side to the length of array minus 1
      let endIndex = array.length - 1;

      //set initial count to zero
      let count = 0;
      let occurrence = 0;

      //declare an empty object to hold the result of search and count 
      const result = {}

      //Applying binary search, iterate while start does not meed end
      while (startIndex <= endIndex) {

        //find the middile index
        let middle = Math.floor((startIndex + endIndex) / 2);
        let guessElement = array[middle];
        count++;

        //if element is present in the middle, increment occurence
        if (guessElement > element) {
          endIndex = middle - 1;
          occurrence++;
        } else if (guessElement < element) {
          startIndex = middle + 1;
          occurrence++;
        } else if (guessElement === element) {
         occurrence++;
         count++;

         let searchleft = middle; // searchleft == middile index

         let searchright = middle;// searchright == middile index


//loop while we donot fine integar < element on left and integar > element on rigth;
          while (array[searchright] == guessElement && array[searchleft] == guessElement ) { 


            if (array[searchright] == element) { //if integar right still equal to element 
              searchright = searchright - 1;
              count++;
              occurrence++;
            } else if(array[searchleft] == element) { //if integar left still equal to element 
            searchleft = searchleft + 1;
              count++;
              occurrence++;
            }
          }
        }
        result.occurrence = occurrence;
        result.count = count;
        return result;
      }}

      console.log(binarySearchOccurrence([1, 2, 3, 4, 4, 4, 5, 5, 5, 6, 7, 8, 9], 5));

答案 2 :(得分:0)

这个问题是侧边栏的建议,而我在寻找其他问题时,请考虑尝试一下。

我不是一个优秀的JavaScript核心程序员,但是稍微修改了您的代码,我认为下面的代码可以为您提供正确的结果

function binarySearchOccurrence(array, element, flag) {
            //declare the start
            //index on the left side to zero 
            let startIndex = 0; //declare the end index on
            // the right side to the length of array minus 1 
            let endIndex = array.length - 1;
            //set initial count to zero 
            let count = 0;
            let occurence = -1;
            const result = {}
            //Applying binary search, iterate while start does not meed end 
            while (startIndex <= endIndex) { //find the middle index 
                let middle = Math.floor((startIndex + endIndex) / 2);
                count++; //if element is
                //   present in the middle, increment occurence 
                if (array[middle] == element) {
                    occurence = middle;
                    if (flag == "last") {
                        startIndex = middle + 1;
                    } else {
                        endIndex = middle - 1;
                    }
                } else {
                    if (arr[middle] > element) {
                        endIndex = middle - 1;
                    } else {
                        startIndex = middle + 1;
                    }
                }
            }
            result.occurence = occurence;
            result.count = count;
            return result;
        }

        function countOccurence(arr, key) {
            let count = binarySearchOccurrence(arr, key, "last").count + binarySearchOccurrence(arr, key, "first").count;
            let occurence = (binarySearchOccurrence(arr, key, "last").occurence - binarySearchOccurrence(arr, key,
                "first").occurence) + 1;
            let result = {};
            result.occurence = occurence;
            result.count = count;
            return result;
        }
        let arr = [0, 1, 2, 3, 4, 4, 4, 4, 5, 6, 7, 8, 9];
        console.log(countOccurence(arr, 4));

我的控制台中的输出

{occurence: 4, count: 8}

任何优秀的JS程序员都可以编辑和改进此代码,我将不胜感激。