# Binary string with given frequencies of sums of consecutive pairs of characters

A binary string is a series of 0s and 1s in computer science and mathematics. The sum of two adjacent characters is indicated by sums of subsequent pairs of characters. For example to understand the below topic, the total number or digits of the succeeding pairs in the string "11010" is 1+1=2, 1+0=1, and 0+1=1. The goal is to locate a binary string that satisfies the specified frequencies using the frequencies of these sums as a guide. Applications of this issue can be found in fields like information theory and coding theory.

## Methods

To find a binary string with given frequencies of sums of consecutive pairs of characters, we can use the following methods −

Method 1: Brute Force

Method 2: Backtracking

Method 3: Dynamic Programming

## Method 1: Brute Force

A set of algorithms known as brute force approaches solve problems by thoroughly examining every potential solution, usually without the use of optimisations or heuristics. A brute force strategy entails creating every conceivable binary string and then determining if the frequencies of sums of consecutive pairs of characters match the specified frequencies in order to obtain a binary string with the required frequencies of sums of consecutive pairs of characters.

### Syntax

Here's a syntax of a brute force method to find a binary string with given frequencies of sums of consecutive pairs of characters

// Initialize variables
int n = length of binary string
int freq[] = array of frequencies of sums
string result = ""

// Loop through all possible binary strings of length n
for (int i = 0; i < pow(2, n); i++) {
string binary = binary representation of i with padding of zeros to length n

// Check if the binary string satisfies the frequency constraints
int sumFreq[] = array of frequencies of sums for binary
bool valid = true
for (int j = 0; j < n - 1; j++) {
if (sumFreq[j] != freq[j]) {
valid = false
break
}
}

// If the binary string satisfies the frequency constraints, save it as result
if (valid) {
result = binary
break
}
}

// Print the result
print result


### Algorithm

Step 1 − Produce every binary string of length n that is conceivable.

Step 2 − Determine the sums of every binary string's adjacent character pairs.

Step 3 − Verify that these sums' frequencies match the specified frequencies.

Step 4 − If a match is discovered, provide the binary string back.

Step 5 − Return "No binary string found" if no match is discovered.

### Example 1

Here's an example C++ code that implements a brute force method to find all binary strings of length n with a given frequency of sums of consecutive pairs of characters −

These implementations generate_binary_strings function takes as inputs a vector to hold the results (results), the required frequency of summing of successive pairs (freq), and the length of the binary strings (n). It uses a nested loop over the integers from 0 to 2n-1 to construct all conceivable binary strings of length n. After that, it examines each string to see if it adheres to the specified frequency and the restriction that no two consecutive characters cannot be 1. A string is included in the results vector if it meets these requirements. A binary string is constructed in the function known as the main function and is then written or shown on the screen.

#include <iostream>
#include <vector>
using namespace std;

void generate_binary_strings(int n, int freq, vector<string>& results) {
for (int i = 0; i < (1 << n); i++) {
string s(n, '0');
int count = 0;
for (int j = 0; j < n-1; j++) {
if (i & (1 << j)) {
s[j] = '1';
count++;
}
}
if (count == freq) {
bool valid = true;
for (int j = 0; j < n-1; j++) {
if (s[j] == '1' && s[j+1] == '1') {
valid = false;
break;
}
}
if (valid) {
results.push_back(s);
}
}
}
}

int main() {
int n = 4; // length of binary strings
int freq = 2; // desired frequency of sums of consecutive pairs
vector<string> results;
generate_binary_strings(n, freq, results);
cout << "Binary strings of length " << n << " with frequency " << freq << ":" << endl;
for (const auto& s : results) {
cout << s << endl;
}
return 0;
}


### Output

Binary strings of length 4 with frequency 2:
1010
1010


## Method 2: Backtracking

To solve combinatorial issues, backtracking is a powerful algorithmic technique that is frequently employed. Finding a binary string with a certain frequency of sums of successive pairs of letters is one of these problems. In this problem, the two integers n and k, which represent the length of the binary string and the frequency of the sums of successive pairs of characters, respectively, are provided.

### Syntax

backtrack(string s, int freq[], int n, int index)
if index == n
return true  // base case: solution found

for i = 0 to 1
s[index] = i
if satisfies_constraints(s, freq, index)
if backtrack(s, freq, n, index+1)
return true  // solution found

return false  // backtrack

satisfies_constraints(string s, int freq[], int index)
// check if s[0:index] satisfies the given constraints


### Algorithm

Step 1 − Begin with an n-length empty string.

Step 2 − Produce all feasible sums of a binary string of length n that contains consecutive character pairs.

Step 3 − Using backtracking, create every binary string that might possibly be made up of 0s and 1s while making sure that each sum's frequency corresponds to the specified frequency.

Step 4 − Return a valid binary string if one is discovered.

Step 5 − Return "No binary string found" if no suitable binary string could be located.

This method's temporal complexity can, in the worst case, be O(2n), depending on how many valid binary strings need to be verified.

### Example 2

The backtrack function takes as input a vector freq of length n that represents desired frequencies of sums of consecutive pairs of characters reference to binary string of length n that will contain binary string being constructed, an integer pos that represents the current position in the binary string being constructed, and integer sum that represents sum of previous two characters (o).

In main function of the example, we build frequency vector called freq and use it to call findBinaryStringWithFrequencies. A valid binary string is reported to the console if one is discovered. If not, a failure notice is displayed.

#include <iostream>
#include <vector>
using namespace std;

bool backtrack(vector<int>& freq, string& binary, int pos, int sum) {
if (pos == binary.length()) {
return true;
}

for (int i = 0; i <= 1; i++) {
int new_sum = sum + (i * (pos > 0 ? binary[pos-1] - '0' : 0));
if (freq[new_sum] > 0) {
freq[new_sum]--;
binary[pos] = '0' + i;
if (backtrack(freq, binary, pos+1, new_sum)) {
return true;
}
freq[new_sum]++;
}
}

return false;
}

string findBinaryStringWithFrequencies(vector<int> freq) {
int n = freq.size();
string binary(n, '0');
if (backtrack(freq, binary, 0, 0)) {
return binary;
} else {
return "";
}
}

int main() {
vector<int> freq = {1, 2, 1, 0, 0, 1};
string binary = findBinaryStringWithFrequencies(freq);
if (binary.empty()) {
cout << "No binary string found." << endl;
} else {
cout << "Binary string: " << binary << endl;
}
return 0;
}


### Output

No binary string found.


## Method 3: Dynamic Programming

Dynamic programming is a well-known method in computer science for resolving optimisation issues by splitting them into smaller issues and then constructing a solution to the main issue from the solutions to those smaller issues. The creation of binary strings with predetermined sums of consecutive character pair frequencies is one use for dynamic programming.

### Syntax

The pseudocode for the above dynamic programming approach is given below −

Function finds binary string(frequencies):
N = length of binary string
k = maximum sum of consecutive pairs of characters that need to be achieved
YT[N+1] [k+1] = 0
YT  = 1
for L in interval (1, N+1):
for P in interval(k+1):
for prep in {0, 1}:
if j - prep >= 0:
YT[L][P] += YT[L-1] [P-prep]
for P in interval(k+1):
if frequency[P]!= -1:


In the above pseudocode, the frequencies parameter is a list of size k+1, where the i-th element represents the frequency of the sum of consecutive pairs of characters equal to i. If the frequency of a particular sum is not given, the corresponding frequency value will be -1. The function returns the number of binary strings that satisfy the given frequency constraints.

### Algorithm

Step 1 − Create a dp array with n+1 elements and initialise it to 0.

Step 2 − Increment the matching entry in the dp array for each possible sum of the characters in successive pairings.

Step 3 − Find every binary string that could possibly include a mixture of 0s and 1s using dynamic programming, making sure that each sum's frequency corresponds to the specified frequency.

Step 4 − Return a valid binary string if one is discovered.

Step 5 − Return "No binary string found" if no suitable binary string could be located.

The time complexity of this method depends on the quantity of valid binary strings that must be verified, however in some circumstances it may be quicker than the earlier techniques.

### Example 3

An illustration of how to handle the problem of finding a binary string with specified frequencies of sums of successive pairs of characters using dynamic programming.

In this version, the number of binary strings of length i that include j pairs of consecutive 1s and k pairs of successive 0s are stored in a 3-dimensional DP array called dp[i][j][k]. Starting with the basic cases for i = 1, we use recurrence relation to compute the DP array for i = 2 to n. According to this relationship, the total number of binary strings of length i that contain j consecutive pairs of 1s and k consecutive pairs of 0s equals the sum of the strings that contained j consecutive pairs of 1s and k consecutive pairs in the step before it (dp[i-1][j][k]).

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

// Function to find the binary string
string binaryStringWithFrequencies(int n, int freq0, int freq1, int freq2) {
string ans = "";

// DP array to store the number of strings
// with a given frequency of sums
vector<vector<vector<int>>>dp(n + 1, vector<vector<int>>(freq1 + 1, vector<int>(freq2 + 1)));

// Initialize DP array for base cases
dp = 1;
if(freq1 > 0) dp = 1;
if(freq2 > 0) dp = 1;

// Compute DP array for remaining cases
for(int i = 2; i <= n; i++) {
for(int j = 0; j <= freq1; j++) {
for(int k = 0; k <= freq2; k++) {
if(j + k > i) break;  // No possible string with sum of consecutive pairs > i
dp[i][j][k] = dp[i-1][j][k];
if(j > 0) dp[i][j][k] += dp[i-1][j-1][k];
if(k > 0) dp[i][j][k] += dp[i-1][j][k-1];
}
}
}

// Trace back the DP array to find the binary string
int j = freq1, k = freq2;
for(int i = n; i >= 1; i--) {
if(j > 0 && dp[i-1][j-1][k] > 0) {
ans += '1';
j--;
}
else {
ans += '0';
k--;
}
}

// Reverse the string to get the correct order
reverse(ans.begin(), ans.end());

// Return the binary string
return ans;
}

// Driver code
int main() {
int n = 5;
int freq0 = 2, freq1 = 1, freq2 = 1;
string ans = binaryStringWithFrequencies(n, freq0, freq1, freq2);
cout << ans << endl;  // Output: 00110
return 0;
}


### Output

00001


## Conclusion

Finally, it should be noted that finding a binary string with specific frequencies of the sums of consecutive character pairs is a difficult challenge that calls for considerable thought. It is feasible to effectively address this problem and produce an appropriate binary string by using mathematical methods and algorithms like linear programming. The difficulty of the issue, however, rises as the amount of the input, and it may take a lot of processing power to discover the best answer. However, this issue may be properly dealt with and the needed binary string can be obtained by using the appropriate methods and tools.

Updated on: 31-Jul-2023

60 Views 