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

使用二进制搜索使用Javascript查找排序数组中出现的所有数字,javascript,binary-search,Javascript,Binary Search,我最近开始用JavaScript学习算法。当我遇到这个问题时,我正在试验二进制搜索,我一直在尝试实现它,但我一直遇到困难该函数接受两个参数(一个排序数组和一个数字),并返回一个对象,其中包含数字的出现次数和计数。我得到的出现次数不是该数字的正确出现次数,计数是常量 这就是我到目前为止所做的: function binarySearchOccurrence(array, element) { //declare the start index on the left side to zer

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

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

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(数组、元素){
//将左侧的开始索引声明为零
设startIndex=0;
//将右侧的结束索引声明为数组长度减1
让endIndex=array.length-1;
//将初始计数设置为零
让计数=0;
设发生率=0;
//声明一个空对象以保存搜索和计数的结果
常量结果={}
//应用二进制搜索,在开始不需要结束时迭代
while(startIndex元素){
endIndex=中间-1;
}否则{
startIndex=中间+1;
}
}
结果发生率=发生率;
result.count=计数;
返回结果;
} 

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

您的代码会重复每次事件的计数。

假设我们得到一个数组[5,5,5,5],5。以0,3作为开始,以0,3作为结束。 Mid=1 因此,事件将变为1(第一个if) 然后在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
pos=bs(arr、val、开始、结束)
a=位置1
ppos_a=a
一会儿=-1和a-1>=0:
ppos_a=a
a=bs(arr,val,0,a-1)
b=位置+1
ppos_b=b

而b=-1和b+1尝试使用此选项,但复杂度不会是O(n)。在这种情况下,允许右或左子节点等于根节点的BST将需要额外的计算步骤来完成允许重复节点的搜索

函数binarySearchOccurrence(数组、元素){
//将左侧的开始索引声明为零
设startIndex=0;
//将右侧的结束索引声明为数组长度减1
让endIndex=array.length-1;
//将初始计数设置为零
让计数=0;
设发生率=0;
//声明一个空对象以保存搜索和计数的结果
常量结果={}
//应用二进制搜索,在开始不需要结束时迭代
while(startIndex元素){
endIndex=中间-1;
发生率++;
}else if(猜测元素<元素){
startIndex=中间+1;
发生率++;
}else if(猜测元素===元素){
发生率++;
计数++;
设searchleft=middle;//searchleft==middile索引
设searchright=middle;//searchright==middile索引
//循环,而我们不在左边精细整数<元素,在右边精细整数>元素;
而(数组[searchright]==guessElement&&array[searchleft]==guessElement){
if(array[searchright]==element){//if integar right仍然等于element
searchright=searchright-1;
计数++;
发生率++;
}else if(数组[searchleft]==element){//if integar left仍然等于element
searchleft=searchleft+1;
计数++;
发生率++;
}
}
}
结果发生率=发生率;
result.count=计数;
返回结果;
}}

log(BinarySearchOccess([1,2,3,4,4,4,5,5,6,7,8,9,5])当我在研究其他问题时,这个问题在侧边栏中作为建议出现,所以我想尝试一下

我不是一个优秀的核心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));

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

你所说的
count
occurrence
是什么意思?对于您的示例,正确的
出现次数和
计数是什么样子的?我不明白为什么这么复杂。似乎你从中间开始,搜索物体的两侧。为什么不从对象(0)的开头开始搜索,直到到达结尾(array.length-1)?@Lowerer我已经修改了它。@Sablefoste我使用的是时间复杂度为O(logn)的二进制搜索方法。因此,
出现次数
是它找到的次数。那么什么是
count
?我希望你能用代码来表达你的想法,也许我能理解得更多。我会在答案中对我的方法进行适当的解释,我希望你届时能够为它编写代码,但我认为它不符合你对log n的要求。可能是x log n,但不确定确切的复杂性。OKayy@kartikay您的代码运行,但出现的
错误。它应该返回2英寸
{occurence: 4, count: 8}