对给定二进制字符串的任意两个子字符串进行最大按位或运算
在这个问题中,我们需要找出给定字符串中任意两个子字符串的最大或值。
第一种方法是找出给定二进制字符串的所有子字符串,对每个字符串取或值,并打印最大或值。
另一种方法是将原始字符串作为一个子字符串,并从最左边的零开始取另一个子字符串,以最大化或值。
问题描述- 我们给出了一个二进制字符串 alpha。我们需要找出给定二进制字符串中任意两个子字符串的"或"值之和的最大值。
示例
输入
alpha = "1000010"
输出
1100011
说明- 第一个子字符串为"1000010",另一个子字符串为"000010"。当我们对两者取或值时,我们得到"1100011"。
输入
alpha = "1111";
输出
1111
说明- 该字符串已经是最大值。因此,我们可以取原始字符串和任何其他子字符串来获得最大值。
输入
alpha = "1100";
输出
1111
解释- 我们可以取 1100 个子字符串和 11 个子字符串来获得最大值。
方法 1
在此方法中,我们将给定二进制字符串的所有子字符串存储在列表中。然后,我们将对每个子字符串进行"或"运算并跟踪最大值。此外,我们将创建一个函数来比较两个子字符串并进行"或"运算。
算法
步骤 1 - 使用空字符串初始化"maxOR"字符串变量,以存储任意两个字符串的"或"运算的最大值。此外,定义 subStr 列表来存储所有子字符串。
步骤 2 - 遍历给定的二进制字符串,使用 substr() 方法获取所有可能的子字符串,并将其推送到 subStr 列表。 substr() 方法将起始索引作为第一个参数,将子字符串长度作为第二个参数。
步骤 3 - 开始遍历子字符串列表。同时,使用嵌套循环遍历所有其他子字符串,对当前子字符串与其他子字符串进行"或"运算。
步骤 4 - 执行 takeOR() 函数对两个字符串进行"或"运算。
步骤 4.1 - 如果 temp1 字符串较小,则在 temp1 字符串后附加初始零。否则,在 temp2 字符串后附加初始零。
步骤 4.2 - 使用空字符串初始化"res"字符串,以存储结果"或"值。
步骤 4.3 - 遍历 temp1 和 temp2 两个字符串。如果当前索引处有任何字符串包含"1",则将"1"附加到"res"字符串。否则,将"0"附加到"res"字符串。
步骤 4.4 - 返回"res"字符串。
步骤 5 - 获取 OR 值后,通过执行 getmax() 函数检查 OR 值是否大于 maxOR 字符串的值。
步骤 5.1 - 如果 temp1 的大小大于 temp2,则返回 temp1。同样,如果 temp2 的大小大于 temp1,则返回 temp1。
步骤 5.2 - 开始遍历字符串。
步骤 5.3 - 如果 temp1 中第 p 个索引处的字符大于 temp1,则返回 temp1。类似地,如果 temp2 中第 p 个索引处的字符大于 temp2,则返回 temp2。
步骤 5.4 - 最后,返回"temp1"字符串。
步骤 6 - 将 getMax() 函数的返回值存储在"maxOR"变量中。
步骤 7 - 返回"maxOR"变量的值。
示例
#include <bits/stdc++.h> using namespace std; string takeOR(string &temp1, string &temp2) { // 如果字符串长度不相等,则在较小字符串的开头添加 0 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 = ""; // 对两个字符串进行"或"运算 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) { // 如果大小不相等,则返回大字符串 if (temp1.size() > temp2.size()) { return temp1; } else if (temp1.size() < temp2.size()) { return temp2; } // 比较两个字符串并返回最大字符串 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; // 获取给定字符串的所有子字符串 for (int p = 0; p < alpha.length(); p++) { for (int q = 1; q <= alpha.length() - p; q++) { subStr.push_back(alpha.substr(p, q)); } } // 获取两个子字符串的最大或值 for (int p = 0; p < subStr.size(); p++) { for (int q = p + 1; q < subStr.size(); q++) { // 对两个字符串进行或运算 string OR_res = takeOR(subStr[p], subStr[q]); // 获取最大字符串 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; }
输出
给定字符串的任意两个子字符串的最大或值为 1100011
时间复杂度 - O(N*N*N),其中 O(N*N) 表示遍历所有子字符串,O(N) 表示查找最大值并对两个字符串进行或运算。
空间复杂度 - O(N*N) 表示存储所有子字符串。
方法 2
在此方法中,我们将从最左边的 0 开始取子字符串,并将其与原始字符串进行或运算,这将始终得出最大值。
算法
步骤 1 - 使用空字符串初始化"temp1"和"temp2"字符串以存储临时字符串。
步骤 2 - 接下来,我们需要从原始字符串中删除前导零。开始遍历字符串,当找到第一个"1"时,从该索引处获取子字符串,并将其存储在"temp1"中。
步骤 3 - 如果 p 等于字符串长度,则返回"0",因为字符串全为零。
步骤 4 - 开始遍历字符串,并将当前字符附加到"temp2"字符串。如果当前字符为"0",则将索引值存储在"x"中并跳出循环,因为我们需要从最左边的零开始取子字符串。
步骤 5 - 如果 x 等于"temp1"字符串的长度,则返回 temp2 字符串,因为它包含所有 1。
步骤 6 - 再次遍历字符串,对原始字符串和从最左边的零开始的子字符串进行"或"运算。
步骤 7 - 如果 temp1[p] 或 temp1[x] 等于"1",则将"1"附加到 temp2。否则,将"0"附加到 temp2。
步骤 8 - 最后,返回"temp2"字符串。
示例
#include <bits/stdc++.h> using namespace std; string maxORVal(string alpha) { int p, q, len = alpha.length(); string temp1 = "", temp2 = ""; // 从字符串中删除前导零 for (p = 0; p < len; p++) { if (alpha[p] == '1') { // 获取从 p 到 len 的子字符串 temp1 = alpha.substr(p, len); break; } } // 对于全包含零的字符串,答案是"0"。 if (p == len) { return "0"; } int x, temp1_len = temp1.size(); // 获取从开始到第一个零的子字符串 for (x = 0; x < temp1_len; x++) { if (temp1[x] == '0') { break; } temp2 += temp1[x]; } // 如果字符串全为 1,则答案为"1"。 if (x == temp1_len) return temp2; // 获取最大 OR 值 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 the answer 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; }
输出
给定字符串的任意两个子字符串的最大或值为 1100011
时间复杂度 - 遍历字符串一次,复杂度为 O(N)。
空间复杂度 - 存储子字符串,复杂度为 O(N)。
第二种方法是第一种方法的优化版本。在第二种方法中,我们将从最左边的零开始的子字符串作为另一个子字符串,因为无论何时将其与原始字符串进行"或"运算,它总是会得出最大值。