XOR of very large Binary Numbers in range [L, R]

• Difficulty Level : Easy
• Last Updated : 13 Jan, 2022

Given two binary strings L and R, the task is to find the xor from L to R. Length of the binary string is < = 10e6.

Examples:

Input: L = 10, R = 100
Output: 101
Explanation: L = 2 and R = 4 in decimal system.Therefore, the xor will be 2^3^4 = 5(101).

Input: L = 10, R = 10000
Output: 10001

Naive Approach: The simplest approach to solve the problem is to find all the binary strings in the range [L, R] and then perform the XOR operation on all the binary strings.

Time Complexity: (R – L +1) *(N) where N is the length of binary string R.
Auxiliary Space: O(1)

Efficient Approach: The above approach can be optimized further by observing that –

• (L ^ (L+1) ^……^(R – 1) ^ R) can be written as (1^2^3 ^…. ^(R-1)^R) ^ (1^2^3 ….. ^(L-2) ^ (L-1)) where ‘^’ denotes the bitwise xor of the elements. So the problem is reduced to find the xor from 1 to n.
• To calculate xor from 1 to n, find the remainder of n by moduling it with 4 and store it in a variable, say rem and there are four possible values of rem
• If rem =0 then xor = n.
• If rem = 1 then xor = 1.
• If rem = 2 then xor = n+1.
• If rem = 3 then xor = 0.

After observing the above points, follow the steps below to solve the problem:

• Create a function sub that subtracts 1 from a binary string S of size N by performing the steps mentioned below:
• Iterate in the range [N-1, 0] using the variable i and perform the following steps:
• If S[i] = ‘0’, then modify the value of S[i] as 1.
• If S[i] = ‘1’, then modify the value of S[i] as 0 and terminate the loop.
• Return string S as the answer.
• Create a function ad that adds 1 to a binary string S of size N by performing the steps mentioned below:
• Initialize a variable, say carry as 0.
• Iterate in the range [N-1, 0] using the variable i and perform the following steps:
• If S[i] = ‘1’, then modify the value of S[i] as 0 and modify the value of carry as 1.
• If S[i] = ‘0’, then modify the value of S[i] as 1 and modify the value of carry as 0 and terminate the loop.
• If carry =1, then modify the value of S as ‘1’ + S and return the string S.
• Create a function Xor_Finder which return the value of XOR from 1 to S by performing the steps mentioned below:
• Initialize a variable, say val and update the value as S[n] + S[n-1]*2 where n is the length of the string S.
• Now if val = 0, then return string S as the answer.
• If val = 1, then return ‘1’ as the answer.
• If val = 3, then return 0 as the answer.
• Create a function final_xor which calculate xor of two binary strings L and R by performing the steps mentioned below:
• Append character ‘0’ to the string L while L.size() != R.size().
• Initialize a string, say ans that will store the value of xor of binary strings L and R.
• Iterate in the range [0, R.size()-1] using the variable i and perform the following steps:
• If L[i] = R[i], then append the character ‘0’ at the end of string ans.
• If L[i] != R[i], then append the character ‘1’ at the end of string ans.
• Return string ans as the xor of the two strings.
• Create a function xorr to calculate xor from L to R by performing the following steps:
• Modify the value of L as sub(L).
• Modify the value of L and R by calling the function xor_finder(L) and xor_finder(R) to calculate xor from 1 to L and from 1 to R respectively.
• Initialize a variable, say ans and update the value of ans by updating the value as final_xor(L, R).
• Return string ans as the answer.

Below is the implementation of the above approach:

C++

 // C++ program for the above approach#include using namespace std; // Function to subtract one// from the binary stringstring sub(string s){    int n = s.size();    for (int i = n - 1; i >= 0; i--) {        // If the current character        // is 0 change it to 1        if (s[i] == '0') {            s[i] = '1';        }        else {            // If the character is 1            // Change is to 0 and            // terminate the loop            s[i] = '0';            break;        }    }    // Return the answer    return s;} // Function to add 1 in the// binary stringstring ad(string s){    int n = s.size();     int carry = 0;    for (int i = n - 1; i >= 0; i--) {        // If s[i]=='1' it        // will change s[i] to 0        // and carry = 1        if (s[i] == '1') {            carry = 1;            s[i] = '0';        }        else {            // If s[i]=='0' it            // will change s[i] to 1            // and carry = 0 and            // end the loop            carry = 0;            s[i] = '1';            break;        }    }    // If still carry left    // append character 1 to the    // beginning of the string    if (carry) {        s = '1' + s;    }    return s;} // Function to find xor from 1 to nstring xor_finder(string s){    int n = s.size() - 1;     // Variable val stores the    // remainder when binary string    // is divided by 4    int val = s[n] - '0';    val = val + (s[n - 1] - '0') * 2;     // If val == 0 the xor from    // 1 to n will be n itself    if (val == 0) {        return s;    }    else if (val == 1) {        // If val ==      the xor from        // 1 to n will be 1 itself        s = '1';        return s;    }    else if (val == 2) {        // If val == 2 the xor from        // 1 to n will be n+1 itself        return (ad(s));    }    else if (val == 3) {        // If val == 3 the xor from        // 1 to n will be 0 itself        s = '0';        return s;    }}// Function to find the xor of two// binary stringstring final_xor(string L, string R){    // Using loop to equalise the size    // of string L and R    while (L.size() != R.size()) {        L = '0' + L;    }    string ans = "";    for (int i = 0; i < L.size(); i++) {        // If ith bit of L is 0 and        // ith bit of R is 0        // then xor will be 0        if (L[i] == '0' && R[i] == '0') {            ans += '0';        }        else if (L[i] == '0' && R[i] == '1'                 || L[i] == '1' && R[i] == '0') {            // If ith bit of L is 0 and            // ith bit of R is 1 or            // vice versa then xor will be 1            ans += '1';        }        else {            // If ith bit of L is 1 and            // ith bit of R is 1            // then xor will be 0            ans += '0';        }    }    return ans;} // Function to find xor from L to Rstring xorr(string L, string R){    // changing L to L - 1    L = sub(L);     // Finding xor from 1 to L - 1    L = xor_finder(L);     // Finding xor from 1 to R    R = xor_finder(R);     // Xor of 1, 2, ..., L-1 and 1, 2, ...., R    string ans = final_xor(L, R);     return ans;} // Driver Codeint main(){    // Given Input    string L = "10", R = "10000";     // Function Call    cout << xorr(L, R) << endl;    return 0;}

Java

 // Java program for above approachclass GFG{     // Function to subtract one// from the binary stringpublic static String sub(String s){    StringBuilder new_s = new StringBuilder(s);    int n = s.length();    for(int i = n - 1; i >= 0; i--)    {                 // If the current character        // is 0 change it to 1        if (s.charAt(i) == '0')        {            new_s.setCharAt(i, '1');        }        else        {                         // If the character is 1            // Change is to 0 and            // terminate the loop            new_s.setCharAt(i, '0');            break;        }    }         // Return the answer    return new_s.toString();} // Function to add 1 in the// binary stringpublic static String ad(String s){    int n = s.length();    StringBuilder new_s = new StringBuilder(s);    int carry = 0;    for(int i = n - 1; i >= 0; i--)    {                 // If s[i]=='1' it        // will change s[i] to 0        // and carry = 1        if (s.charAt(i) == '1')        {            carry = 1;            new_s.setCharAt(i, '0');        }        else        {                         // If s[i]=='0' it            // will change s[i] to 1            // and carry = 0 and            // end the loop            carry = 0;            new_s.setCharAt(i, '1');            break;        }    }         // If still carry left    // append character 1 to the    // beginning of the string    if (carry != 0)    {        s = '1' + new_s.toString();    }    return s;} // Function to find xor from 1 to npublic static String xor_finder(String s){    int n = s.length() - 1;     // Variable val stores the    // remainder when binary string    // is divided by 4    int val = s.charAt(n) - '0';    val = val + (s.charAt(n - 1) - '0') * 2;     // If val == 0 the xor from    // 1 to n will be n itself    if (val == 0)    {        return s;    }    else if (val == 1)    {                 // If val == 1 the xor from        // 1 to n will be 1 itself        s = "1";        return s;    }    else if (val == 2)    {                 // If val == 2 the xor from        // 1 to n will be n+1 itself        return (ad(s));    }    else    {                 // If val == 3 the xor from        // 1 to n will be 0 itself        s = "0";        return s;    }} // Function to find the xor of two// binary stringpublic static String final_xor(String L, String R){         // Using loop to equalise the size    // of string L and R    while (L.length() != R.length())    {        L = '0' + L;    }    String ans = "";    for(int i = 0; i < L.length(); i++)    {                 // If ith bit of L is 0 and        // ith bit of R is 0        // then xor will be 0        if (L.charAt(i) == '0' && R.charAt(i) == '0')        {            ans += '0';        }        else if (L.charAt(i) == '0' && R.charAt(i) == '1' ||                 L.charAt(i) == '1' && R.charAt(i) == '0')        {            // If ith bit of L is 0 and            // ith bit of R is 1 or            // vice versa then xor will be 1            ans += '1';        }        else        {                         // If ith bit of L is 1 and            // ith bit of R is 1            // then xor will be 0            ans += '0';        }    }    return ans;} // Function to find xor from L to Rpublic static String xorr(String L, String R){         // Changing L to L - 1    L = sub(L);     // Finding xor from 1 to L - 1    L = xor_finder(L);     // Finding xor from 1 to R    R = xor_finder(R);     // Xor of 1, 2, ..., L-1 and 1, 2, ...., R    String ans = final_xor(L, R);     return ans;} // Driver codepublic static void main(String[] args){         // Given Input    String L = "10", R = "10000";     // Function Call    System.out.println(xorr(L, R));}} // This code is contributed by garry133

Python3

 # Python program for the above approach # Function to subtract one# from the binary stringdef sub(s):       # Changing string into list to change    # the characters in O(1)    s = list(s)    n = len(s)    for i in range(n-1, -1, -1):               # If the current character        # is 0 change it to 1        if (s[i] == '0'):            s[i] = '1'        else:            # If the character is 1            # Change is to 0 and            # terminate the loop            s[i] = '0'            break    # Return the answer    # converting list to string    s = "".join(s)    return s # Function to add 1 in the# binary string  def ad(s):    n = len(s)    carry = 0    for i in range(n-1, -1, -1):        # If s[i]=='1' it        # will change s[i] to 0        # and carry = 1        if (s[i] == '1'):            carry = 1            s[i] = '0'        else:            # If s[i]=='0' it            # will change s[i] to 1            # and carry = 0 and            # end the loop            carry = 0            s[i] = '1'            break    # If still carry left    # append character 1 to the    # beginning of the string    if (carry):        s = '1' + s    return s # Function to find xor from 1 to n  def xor_finder(s):    n = len(s) - 1     # Variable val stores the    # remainder when binary string    # is divided by 4    val = ord(s[n]) - 48    val = val + (ord(s[n - 1]) - 48) * 2     # If val == 0 the xor from    # 1 to n will be n itself    if (val == 0):        return s    elif (val == 1):        # If val ==      the xor from        # 1 to n will be 1 itself        s = '1'        return s    elif (val == 2):        # If val == 2 the xor from        # 1 to n will be n+1 itself        return (ad(s))    elif (val == 3):        # If val == 3 the xor from        # 1 to n will be 0 itself        s = '0'        return s # Function to find the xor of two# binary string  def final_xor(L, R):    # Using loop to equalise the size    # of string L and R    while (len(L) != len(R)):        L = '0' + L    ans = ""    for i in range(len(L)):        # If ith bit of L is 0 and        # ith bit of R is 0        # then xor will be 0        if (L[i] == '0' and R[i] == '0'):            ans += '0'        elif (L[i] == '0' and R[i] == '1'              or L[i] == '1' and R[i] == '0'):            # If ith bit of L is 0 and            # ith bit of R is 1 or            # vice versa then xor will be 1            ans += '1'        else:            # If ith bit of L is 1 and            # ith bit of R is 1            # then xor will be 0            ans += '0'    return ans # Function to find xor from L to R  def xorr(L, R):    # changing L to L - 1    L = sub(L)     # Finding xor from 1 to L - 1    L = xor_finder(L)     # Finding xor from 1 to R    R = xor_finder(R)     # Xor of 1, 2, ..., L-1 and 1, 2, ...., R    ans = final_xor(L, R)     return ans # Driver Code # Given InputL = "10"R = "10000" # Function Callprint(xorr(L, R)) # This code is contributed by rj13to.
Output:
10001

Time Complexity: O(N) where N is the length of the string
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up