C++ 计算二进制字符串中满足条件的三元组数量

C++ 计算二进制字符串中满足条件的三元组数量

二进制字符串是一种只包含二进制字符(’0’和’1’)的字符串。给定一个二进制字符串,我们需要找到满足以下条件的三元组:前两个字符的按位“与”等于后两个字符的按位“与”。

数学上的表达式为:

对于 0 <= i < j < k < length (给定的字符串):(s[i] & s[j]) (s[j] & s[k])

按位”与”操作在两位都为真时返回真,否则对于任何一位为假或两位都为假时返回假。

示例

输入

“01010”

输出

8

解释

对于索引为0的位置上的0,我们可以有以下三元组:(0, 1, 0),(0, 1, 0),(0, 0, 1),(0, 1, 0),(0, 0, 0)。

对于下一个位置上的1,我们可以有以下三元组:(1, 0, 1),(1, 0, 0)。

对于下一个位置上的0,我们可以有以下三元组:(0, 1, 0)。

方法1

在这个程序中,我们将使用暴力法的方法来获取所有的三元组,然后我们将检查它们是否符合给定的条件。

  • 首先,我们将创建一个函数,该函数将接受一个参数,即给定的字符串,并返回所需的结果。

  • 在函数中,我们将获取字符串的大小,然后使用嵌套的for循环来遍历字符串并获取所有的三元组。

  • 我们将维护一个变量来存储计数,如果任何一个三元组满足给定条件,则将增加计数。

  • 在主函数中,我们将调用该函数并打印结果。

例子

#include <bits/stdc++.h>
using namespace std; 

// function to get the required solution 
int countTriplets(string str){
   int len = str.size(); // getting the size of string 
   int ans = 0; // variable to store the count 
   // use nested three for loops to get all the triplets 
   for (int i = 0; i < len; i++){
      int a = str[i] -'0'; // current bit 
      for (int j = i + 1; j < len; j++){
         int b = str[j] - '0'; // current bit
         for (int k = j + 1; k < len; k++){
            int c = str[k] - '0'; // current bit

            if((a & b) == (b & c)){
               ans++; // increasing the count 
            }
         }
      }
   }
   return ans; // return the final count
}
int main(){
   string str = "01010"; // given string 
   cout<<"The number of triplets in the given string is: " << countTriplets(str) << endl;
   return 0;
}

输出

The number of triplets in the given string is: 8

时间和空间复杂度

上述代码的时间复杂度是O(N^3),其中N是给定字符串的长度。在这里,我们使用嵌套的for循环对字符串进行了三次遍历,使得时间复杂度较高。

我们这里没有使用额外的空间,这使得上述代码的空间复杂度为O(1)或常数。

方法2

在这种方法中,我们将使用前缀和后缀数组来存储零的计数,以减少时间复杂度。

我们将维护这些数组,并遍历给定的字符串以获得结果。

在遍历过程中,如果字符串的当前索引是’0’,那么我们将简单地将当前索引乘以剩余索引的个数减一加到结果中。

如果当前索引值为’1’,那么我们将使用前缀*后缀和索引减去前缀乘以剩余元素减去后缀,这将给我们最终的答案。

示例

#include <bits/stdc++.h>
using namespace std; 

// function to ge the required solution 
int countTriplets(string str){
   int len = str.size(); // getting size of string 
   int ans = 0; // variable to store the count 
   int prefix[len], suffix[len];
   // traversing over the string to get the prefix array 
   prefix[0] = str[0] == '0';
   for (int i = 1; i < len; ++i) {
      prefix[i] = prefix[i-1] + (str[i] == '0');
   }
   // traversing over the string to get the suffix array 
   suffix[len-1] = str[len-1] == '0';
   for (int i = len - 2; i >= 0; --i) {
      suffix[i] = suffix[i+1] + (str[i] == '0');
   }
   // iterating over the string to get the final answer 
   for (int i = 1; i < len - 1; i++) {
      if (str[i] == '0') {
         ans += i * (len - i - 1);
      }
      else {
         ans += prefix[i - 1] * suffix[i + 1];
         ans += (i - prefix[i - 1]) * (len - i - 1 - suffix[i + 1]);
      }
   }
   return ans; // return the final count
}
int main(){
   string str = "01010"; // given string 
   cout<<"The number of triplets in the given string is: "<<countTriplets(str)<<endl;
   return 0;
}

输出

The number of triplets in the given string is: 8

时间和空间复杂度

以上代码的时间复杂度为O(N),其中N是给定字符串的长度。

在以上代码中,我们使用额外的数组来存储前缀和后缀的零的个数,使得空间复杂度为线性的O(N)。

结论

在本教程中,我们实现了一个程序,用于找出给定二进制字符串中满足以下条件的三元组的数量:对于0 <= i < j < k < length(给定字符串):(s[i] & s[j]) (s[j] & s[k])。我们实现了两个程序,一个是通过嵌套的for循环暴力查找所有三元组,另一个是通过维护前缀和后缀和并通过数学方式找到结果。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程