📌  相关文章
📜  查询以找到包含给定模式的范围内的整数计数

📅  最后修改于: 2021-05-25 08:26:37             🧑  作者: Mango

给定一个二进制模式pattQ查询,其中每个查询都包含一个范围[L,R] ,对于每个查询,任务是从给定范围中查找整数计数,以使它们在其二进制表示形式中包含给定模式。
例子:

方法:

  • 创建一个数组res [] ,其中res [i]将存储范围为[0,i]的有效整数的数量。
  • 0开始,找到所有整数的二进制表示形式,并检查给定的模式是否出现在其中。
  • 根据上一步中找到的值更新res []数组。
  • 现在,每个查询都可以在O(1)中以res [R] – res [L – 1]的形式回答。

下面是上述方法的实现:

C++
#include
using namespace std;
 
// Function to return the
// pre-calculate array such
// that arr[i] stores the count of
// valid numbers in the range [0, i]
string DecimalToBinaryString(int a)
{
  string binary = "";
  int mask = 1;
  for (int i = 0; i < 31; i++)
  {
    if(mask&a)
      binary = "1" + binary;
    else
      binary = "0" + binary;
    mask <<= 1;
  }
 
  return binary;
}
 
vector preCalculate(int max,
                         string pattern)
{
  vector arr(max + 1, 0);
 
  // If 0 is a valid number
  if (pattern == "0")
    arr[0] = 1;
  else
    arr[0] = 0;
 
  // For every element i
  for (int i = 1; i <= max; i++)
  {
    // If i is avalid number
    if (DecimalToBinaryString(i).find(pattern) !=
        std::string :: npos)
    {
      arr[i] = 1 + arr[i - 1];
    }
    else
    {
      arr[i] = arr[i - 1];
    }
  }
  return arr;
}
 
// Function to perform the queries
void performQueries(vector > queries,
                    int q, string pattern)
{
  // Maximum value for the
  // end of any range
  int ma = INT_MIN;
   
  for (int i = 0; i < q; i++)
    ma = max(ma, queries[i][1]);
 
  // res[i] stores the count of valid
  // integers from the range [0, i]
  vector res = preCalculate(ma,
                                 pattern);
 
  for (int i = 0; i < q; i++)
  {
    int l = queries[i][0];
    int r = queries[i][1];
 
    if (l == 0)
      cout << (res[r]) << endl;
    else
      cout << (res[r] -
               res[l - 1]) << endl;
  }
}
 
// Driver code
int main()
{
  vector> queries = {{2, 10},
                                 {8, 120}};
  int q = queries.size();
  string pattern = "101";
  performQueries(queries, q, pattern);
}
 
// This code is contributed by grand_master


Java
// Java implementation of the approach
import java.util.*;
class GFG {
 
    // Function to return the pre-calculate array
    // such that arr[i] stores the count of
    // valid numbers in the range [0, i]
    static int[] preCalculate(int max, String pattern)
    {
        int arr[] = new int[max + 1];
 
        // If 0 is a valid number
        if (pattern == "0")
            arr[0] = 1;
        else
            arr[0] = 0;
 
        // For every element i
        for (int i = 1; i <= max; i++) {
 
            // If i is avalid number
            if (Integer.toBinaryString(i).contains(pattern)) {
                arr[i] = 1 + arr[i - 1];
            }
            else {
                arr[i] = arr[i - 1];
            }
        }
        return arr;
    }
 
    // Function to perform the queries
    static void performQueries(int queries[][],
                               int q, String pattern)
    {
 
        // Maximum value for the end of any range
        int max = Integer.MIN_VALUE;
        for (int i = 0; i < q; i++)
            max = Math.max(max, queries[i][1]);
 
        // res[i] stores the count of valid
        // integers from the range [0, i]
        int res[] = preCalculate(max, pattern);
 
        for (int i = 0; i < q; i++) {
            int l = queries[i][0];
            int r = queries[i][1];
 
            if (l == 0)
                System.out.println(res[r]);
            else
                System.out.println(res[r] - res[l - 1]);
        }
    }
 
    // Driver code
    public static void main(String args[])
    {
        int queries[][] = { { 2, 10 }, { 8, 120 } };
        int q = queries.length;
        String pattern = "101";
 
        performQueries(queries, q, pattern);
    }
}


Python3
# Python3 implementation of the approach
import sys
 
# Function to return the pre-calculate array
# such that arr[i] stores the count of
# valid numbers in the range [0, i]
def preCalculate(maX, pattern) :
    arr = [0] * (maX + 1);
     
    # If 0 is a valid number
    if (pattern == "0") :
        arr[0] = 1;
         
    else :
        arr[0] = 0;
         
    # For every element i
    for i in range(1, maX + 1) :
         
        # If i is avalid number
        if (pattern in bin(i)) :
            arr[i] = 1 + arr[i - 1];
             
        else :
            arr[i] = arr[i - 1];
             
    return arr;
 
# Function to perform the queries
def performQueries(queries,q, pattern) :
     
    # Maximum value for the end of any range
    maX = -(sys.maxsize + 1);
     
    for i in range(q) :
         
        maX = max(maX, queries[i][1]);
         
    # res[i] stores the count of valid
    # integers from the range [0, i]
    res = preCalculate(maX, pattern);
 
    for i in range(q) :
        l = queries[i][0];
        r = queries[i][1];
         
        if (l == 0) :
            print(res[r]);
        else :
            print(res[r] - res[l - 1]);
 
# Driver code
if __name__ == "__main__" :
     
    queries = [ [ 2, 10 ], [ 8, 120 ] ];
    q = len(queries);
    pattern = "101";
    performQueries(queries, q, pattern);
 
# This code is contributed by kanugargng


C#
// C# implementation of the approach
using System;
using System.Numerics;
 
class GFG
{
 
    //integer to binary string
    public static string toBinaryString(int x)
    {
        char[] bits = new char[32];
        int i = 0;
     
        while (x != 0)
        {
            bits[i++] = (x & 1) == 1 ? '1' : '0';
            x >>= 1;
        }
     
        Array.Reverse(bits, 0, i);
        return new string(bits);
    }
     
    // Function to return the pre-calculate array
    // such that arr[i] stores the count of
    // valid numbers in the range [0, i]
    static int[] preCalculate(int max, string pattern)
    {
        int []arr = new int[max + 1];
 
        // If 0 is a valid number
        if (pattern == "0")
            arr[0] = 1;
        else
            arr[0] = 0;
 
        // For every element i
        for (int i = 1; i <= max; i++)
        {
            // If i is avalid number
            if (toBinaryString(i).Contains(pattern))
            {
                arr[i] = 1 + arr[i - 1];
            }
            else
            {
                arr[i] = arr[i - 1];
            }
        }
        return arr;
    }
 
    // Function to perform the queries
    static void performQueries(int [,]queries,
                               int q, string pattern)
    {
 
        // Maximum value for the end of any range
        int max = int.MinValue;
        for (int i = 0; i < q; i++)
            max = Math.Max(max, queries[i, 1]);
 
        // res[i] stores the count of valid
        // integers from the range [0, i]
        int []res = preCalculate(max, pattern);
 
        for (int i = 0; i < q; i++)
        {
            int l = queries[i, 0];
            int r = queries[i, 1];
 
            if (l == 0)
                Console.WriteLine(res[r]);
            else
                Console.WriteLine(res[r] - res[l - 1]);
        }
    }
 
    // Driver code
    public static void Main(string []args)
    {
        int [,]queries = { { 2, 10 }, { 8, 120 } };
        int q = queries.GetLength(0) ;
        string pattern = "101";
 
        performQueries(queries, q, pattern);
    }
}
 
// This code is contributed by Arnab Kundu


输出:
2
59