# Maximum bitwise OR on of any two Substrings of given Binary String

In this problem, we need to find the maximum OR value of any two substrings of the given strings.

The first approach is to find all substrings of the given binary string, take OR value of each string, and print the maximum OR value.

The other approach is to take the original string as one substring and take another substring starting from left most zero to maximize the OR value.

Problem statement - We have given a binary string alpha. We need to find the maximum OR value of any two substrings of the given binary string.

### Sample examples

Input

alpha = "1000010"


Output

1100011

Explanation - The first substring is '1000010', and another substring is '000010'. When we take OR value of both, we get '1100011'.

Input

alpha = "1111";


Output

1111

Explanation - The string is already maximum. So, we can take an original string and any other substring to get the maximum result.

Input

alpha = "1100";


Output

1111

Explanation - We can take 1100 and 11 substrings to get the maximum result.

## Approach 1

In this approach, we will store all substrings of the given binary string in the list. After that, we will take the OR of each substring and track the maximum value. Also, we will create a function to compare two substrings and take the OR of two substrings.

### Algorithm

Step 1 - Initialize the 'maxOR' string variable with an empty string to store the maximum OR value of any two strings. Also, define the subStr list to store all substrings.

Step 2 - Traverse the given binary string, take all possible substrings using the substr() method, and push to the subStr list. The substr() method takes the starting index as the first parameter and the substring length as a second parameter.

Step 3 - Start traversing the list of substrings. Also, use the nested loop to traverse all other substrings to take OR of the current substring with other substrings.

Step 4 - Execute the takeOR() function to take the OR of two strings.

Step 4.1 - If the size of the temp1 string is smaller, append initial zeros to the temp1 string. Otherwise, append initial zeros to the temp2 string.

Step 4.2 - Initialize the 'res' string with an empty string to store the resultant OR value.

Step 4.3 - Traverse temp1 and temp2 both strings. If any string contains '1' at the current index, append '1' to the 'res' string. Otherwise, append '0' to the 'res' string.

Step 4.4 - Return the 'res' string.

Step 5 - After getting the OR value, check whether the OR value is greater than the maxOR string's value by executing the getmax() function.

Step 5.1 - If the size of the temp1 is greater than temp2, return temp1. Similarly, if the size of the temp2 is greater than the temp1, return the temp1.

Step 5.2 - Start traversing the string.

Step 5.3 - If the character at the pth index is greater in temp1, return temp1. Similarly, if the character at the pth index in the temp2 is greater, return temp2.

Step 5.4 - At last, return the 'temp1' string.

Step 6 - Store the returned value from the getMax() function in the 'maxOR' variable.

Step 7 - Return the 'maxOR' variable's value.

### Example

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

string takeOR(string &temp1, string &temp2) {
// If the string length is not equal, then add 0's at the start of smaller string
if (temp1.size() < temp2.size()) {
int diff = temp2.size() - temp1.size();
for (int p = 0; p < diff; p++) {
temp1 = '0' + temp1;
}
} else if (temp1.size() > temp2.size()) {
int diff = temp1.size() - temp2.size();
for (int p = 0; p < diff; p++) {
temp2 = '0' + temp2;
}
}

string res = "";
// Take OR of both strings
for (int p = 0; p < temp1.length(); p++) {
if (temp1[p] == '1' || temp2[p] == '1') {
res += '1';
} else {
res += '0';
}
}
return res;
}

string getMax(string temp1, string temp2) {
// Return large string if the size is not equal
if (temp1.size() > temp2.size()) {
return temp1;
} else if (temp1.size() < temp2.size()) {
return temp2;
}

// Compare two strings and return the maximum string
for (int p = 0; p < temp1.size(); p++) {
if (temp1[p] > temp2[p]) {
return temp1;
} else if (temp1[p] < temp2[p]) {
return temp2;
}
}
return temp1;
}

string maxORVal(string alpha) {
string maxOR = "";
vector<string> subStr;
// get all substrings of the given string
for (int p = 0; p < alpha.length(); p++) {
for (int q = 1; q <= alpha.length() - p; q++) {
subStr.push_back(alpha.substr(p, q));
}
}

// Get the maximum OR value of two substrings
for (int p = 0; p < subStr.size(); p++) {
for (int q = p + 1; q < subStr.size(); q++) {
// Take OR of two strings
string OR_res = takeOR(subStr[p], subStr[q]);
// Get maximum string
maxOR = getMax(maxOR, OR_res);
}
}
return maxOR;
}

int main() {
string alpha = "1000010";
cout << "The maximum OR value of any two substrings of the given string  is " << maxORVal(alpha);
return 0;
}


### Output

The maximum OR value of any two substrings of the given string is 1100011


Time complexity - O(N*N*N), where O(N*N) is to traverse all substrings, and O(N) is to find the maximum and take OR of two strings.

Space complexity - O(N*N) to store all substrings.

## Approach 2

In this approach, we will take the substring starting from the leftmost 0 and take its OR with the original string, which will always give the maximum value.

### Algorithm

Step 1 - Initialize the 'temp1' and 'temp2' strings with empty strings to store the temporary strings.

Step 2 - Next, we need to remove the leading zeros from the original string. Start traversing the string, and when we find the first '1', take the substring from that index, and store the substring in the 'temp1'.

Step 3 - If p is equal to string length, return '0' as the string contains all zeros.

Step 4 - Start traversing the string, and append the current character to the 'temp2' string. If the current character is '0', store the index value in the 'x' and break the loop, as we need to take substring starting from the leftmost zero.

Step 5 - If x equals the 'temp1' string's length, return the temp2 string as it contains all 1's.

Step 6 - Again, traverse the string to take OR of the original string and substring starting from leftmost zero.

Step 7 - If temp1[p] or temp1[x] is equal to '1', append '1' to temp2. Otherwise, append '0' to temp2.

Step 8 - At last, return the 'temp2' string.

### Example

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

string maxORVal(string alpha) {
int p, q, len = alpha.length();
string temp1 = "", temp2 = "";
// Removing leading zeros from the string
for (p = 0; p < len; p++) {
if (alpha[p] == '1') {
// Get substring from p to len
temp1 = alpha.substr(p, len);
break;
}
}
// For a string containing all zeros, the answer is '0'.
if (p == len) {
return "0";
}
int x, temp1_len = temp1.size();
// Get substring from start to first zero
for (x = 0; x < temp1_len; x++) {
if (temp1[x] == '0') {
break;
}
temp2 += temp1[x];
}
// If the string contains all ones, the answer is '1'.
if (x == temp1_len)
return temp2;
// Get maximum OR value
for (p = 0; p < temp1_len and x < temp1_len; p++, x++) {
if (temp1[p] == '1' or temp1[x] == '1')
temp2 += '1';
else
temp2 += '0';
}
return temp2;
}
int main() {
string alpha = "1000010";
cout << "The maximum OR value of any two substrings of the given string  is " << maxORVal(alpha);
return 0;
}


### Output

The maximum OR value of any two substrings of the given string is 1100011


Time complexity - O(N) for traversing the string once.

Space complexity - O(N) to store the substrings.

The second approach is the optimized version of the first approach. In the second approach, we have taken the substring starting from the leftmost zero as another substring because it always gives the maximum value whenever we take its OR with the original string.

Updated on: 29-Aug-2023

33 Views 