Algorithm competition - binary conversion, can you?

Binary conversion

I found many blogs about hexadecimal conversion on the Internet and found that the implementation of conversion codes between different hexadecimals is too complex and redundant. The base conversion is the basic knowledge point often tested in the algorithm competition. A clear code implementation is very necessary! Today, I will make a detailed and clear summary of common binary conversion, hoping to be of some help to your study or competition!

1, Basic introduction to binary system

What is hexadecimal?

It is the carry system, which is a carry method stipulated by people. For any kind of base system - x base system, it means that the number at a certain position is carried into one digit every X.
Binary is every two into one, octal is every eight into one, decimal is every decimal one, hexadecimal is every sixteen into one.

  • Binary numbers can only consist of numbers from 0 to 1
  • Octal numbers can only consist of numbers from 0 to 7
  • Hexadecimal numbers can only be composed of numbers (characters) from 0 to 9 A to F

How to count in n-ary?

Decimal: 0 one two three four five six seven eight nine ten 11........

Binary: 0 one ten eleven one hundred one hundred and one one hundred and ten one hundred and eleven one thousand 1001 ......

Octal: 0 one two three four five six seven ten eleven twelve thirteen fourteen fifteen sixteen seventeen twenty 21.......

Hex: 0 one two three four five six seven eight nine A B C D E F ten .... eighteen nineteen 1A 1B 1C 1D.....

2, Conversion between decimal and R base

Decimal to R-ary

Decimal to r-ary integer: divide R and take remainder, and the result is taken upside down

Note: when converting decimal to hexadecimal, if the remainder of division is 10 ~ 15

10 -> A

11 -> B

12 -> C

13 -> D

14 -> E

15 -> F

R-ary to 10-ary

Integer converted from R-ary to 10-ary: expanded by weight

0 ~ 15 to binary oral arithmetic skills: 8421 codes

It is converted to 4-bit binary representation, and the 4-bit binary number is up to 15

8: 2^3 4: 2^2 2: 2^1 1: 2^0

(1) Conversion between decimal and binary

1. Decimal to binary

Idea: divide 2 by short division to find the remainder, and store the result in reverse order. string (you can also use array to store in reverse order (stack). string actually has the function of array)

[reference code]

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>


using namespace std;
typedef long long LL;
const int N = 1e5 + 10;
LL n, x;
char c;
string s; // Binary result

int main()
{   
    cin >> n;
    while(n != 0)
    {
        x = n % 2;// Get results
        c = x + '0';// Convert numbers to characters
        s = c + s; // Store the results in the string in reverse order
        n /= 2; // Continue short division
    }
    
    // Here, n == 0 cannot be used to judge the special situation, because while introduces that n must be 0 in the end 
    if(s == "") cout << 0;
    else cout << s;
    
    return 0;
}

2. Binary to decimal

Title Description

Please convert a positive binary integer within 25 bits to hexadecimal!

input

A positive binary integer within 25 bits

output

The number corresponds to the decimal system

Sample

input

111111111111111111111111

output

16777215

Idea:

Start from the lowest point (size()-1), calculate inversely, and expand by weight.

Convert character to integer: s[i] - '0'

Prepare the variable t, representing the nth power of 2, t = 1, once per cycle, t = t * 2

[reference code]

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;
typedef long long LL;
const int N = 1e5 + 10;
LL t = 1, r; // t represents weight; r record the result of two to ten
string s; // Store binary

int main()
{   
    cin >> s;
    
    for(int i = s.size() - 1; i >= 0; i --)
    {
        r = r + (s[i] - '0') * t;
        t = t * 2;
    }
    cout << r;
    return 0;
}

(2) Conversion between decimal and hexadecimal

1. Decimal to hexadecimal

Title Description

Please read a non negative integer n (n is a positive integer no more than 18 bits) from the keyboard and convert n to hexadecimal!

Note: hexadecimal is every 16 into 1, and each bit can be 16 numbers of different sizes from small to large: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E and F, that is, every 16 into 1, in which the six letters A, B, C, D, E and F are used to represent 10, 11, 12, 13, 14 and 15 respectively.

For example, the hex of 60 is 3C. (please use capital letters)

input

A nonnegative integer n with no more than 18 bits

output

The hexadecimal value of the number

Sample

input

100000000000

output

174876E800

Idea:

The short division takes 16 remainder, and the results are stored in reverse order. When storing strings in reverse order, pay attention to:

When the remainder is:

​ Integer 0 ~ 9, converted to characters' 0 '~'9': x +'0 '

​ Integer 10 ~ 15, converted to characters' A'~'F': x +'a '- 10

Note:

​ int Up to 2 ^ 31 - 1, 10 bit integer;

​ long long Up to 2 ^ 63 - 1, 19 bit integer

When the value exceeds the int range, turn on long long

[reference code]

Solution 1:

Judge whether the result of n%16 is in the range of 0 ~ 9 and 10 ~ 15, and convert it into corresponding characters respectively!

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>


using namespace std;
typedef long long LL;
const int N = 1e5 + 10;
LL n, x;
string s; // Store binary
char c;

int main()
{   
    cin >> n;
    while(n != 0)
    {
        x = n % 16;
        //Convert x to character and store it in the string s in reverse order
        // If the remainder is less than 10: '0' ~'9 '
        // If the remainder is 10 ~ 15: 'A'~'F '
        
        if(x < 10) c = x + '0';
        else c = x + 'A' - 10;
        
        s = c + s; // Store string in reverse order
        
        n /= 16;
    }
    if(s == "") cout << 0;
    else cout << s;
    
    return 0;
}

Solution 2:

List the character results of 0 ~ 15, and directly get the corresponding characters according to the remainder: string t = "0123456789ABCDEF"// skill!

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;
typedef long long LL;
const int N = 1e5 + 10;

LL n, x;
string s; // Store binary
string t = "0123456789ABCDEF"; // skill!

int main()
{   
    cin >> n;
    while(n != 0)
    {
        x = n % 16;
        
        //Convert x to character and store it in the string s in reverse order
        s = t[x] + s; // Store string in reverse order
        
        n /= 16;
    }
    if(s == "") cout << 0;
    else cout << s;
    
    return 0;
}

2. Hexadecimal to decimal

Title Description

Please convert a positive hexadecimal integer with no more than 10 digits to a decimal integer!

input

Hexadecimal positive integer within 10 bits

output

The number corresponds to a decimal integer

Sample

Input copy

2ECF

output

11983

Idea: calculate in reverse order and expand by weight! Get each character s[i] from s and convert it to an actual integer:

​ s[i]: '0'~'9' -> s[i] - '0'

​ s[i]: 'A~'F' -> s[i] - 'A' + 10

[reference code]

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>


using namespace std;
typedef long long LL;
const int N = 1e5 + 10;
LL n, r, t = 1;
string s; // Store binary



int main()
{   
    cin >> s;
    for(int i = s.size() - 1; i >= 0; i --)
    {
        // If s[i] is a character number
        if(s[i] >= '0' && s[i] <= '9') // Function judgment can also be isdigit(s[i]): judge whether it is a character or a number
            r = r + (s[i] - '0') * t;
        else
            r = r + (s[i] - 'A' + 10) * t;
        
        t = t * 16;
        
    }
    cout << r;
    return 0;
}

3, Binary to octal / hexadecimal conversion

We know that binary to eight / hexadecimal, you can first convert binary to decimal, and then use short division to find eight / hexadecimal, but this is more troublesome. Add the amount of code! We can convert directly, which is equivalent to a template!

Principle: each octal number is equivalent to a 3-bit binary number (07), and each hexadecimal number is equivalent to a '4-bit' binary number (015). During conversion, the middle 0 cannot be omitted. If the beginning is not enough, it can be filled with zero.

Binary to 8 / hexadecimal:

8 / hex to binary:

1. Binary to hexadecimal

Title Description

Please convert a binary number with no more than 100 bits to hexadecimal number!

input

A binary integer with no more than 100 bits

output

The hexadecimal number corresponding to this number!

Sample

input

11001001111011111000001000010011

output

C9EF8213

Idea:

Step 1: judge whether the length of the string is a multiple of 4. If not, supplement 0.

s: Character array

s. Size()% 4 = = 1, make up 3 zeros

s. Size()% 4 = = 2, make up 2 zeros

s. Size()% 4 = = 3, make up 1 0

Step 2: every four digit binary number is converted into a one digit hexadecimal number (with the help of hexadecimal in turn) for output.

"1101" is converted to the corresponding decimal integer -- > 13. Note that if the conversion result is 0 ~ 9, it is converted to '0' ~'9 ', and if the conversion result is 10 ~ 15, it is converted to' A'~'F'

Convert four bit binary to one bit hexadecimal:

char num(string s)
{
	...
}

[reference code]

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>


using namespace std;
typedef long long LL;
const int N = 1e5 + 10;

// Convert 4-bit binary into hexadecimal integer and change it into hexadecimal symbol: 0 ~ 9 - > '0' ~'9 '; 10~15 -> 'A'~'F' 
char num(string s)
{
    LL r = 0, t = 1; // r = 0, t = 1; Don't forget
    // Expand by weight from the lowest bit and convert to hexadecimal
    // Hexadecimal to hexadecimal in
    for(int i = s.size() - 1; i >= 0; i --)
    {
        r = r + (s[i] - '0') * t;
        t = t * 2;
    }
    
    //Hexadecimal to hexadecimal: 0 ~ 9 - > '0' ~'9 '; 10~15 -> 'A'~'F'
    char c; // Storage results
    if(r < 10) c = r + '0';
    else c = r + 'A' - 10;
    
    return c;
}


int main()
{   
    string s, t; // Store binary
    cin >> s; 
    
    // See if you need to fill in zero
    if(s.size() % 2 == 1) s = "000" + s;
    else if(s.size() % 2 == 2) s = "00" + s;
    else if(s.size() % 2 == 3) s = "0" + s;
    
    // 4-bit binary number intercepted every time: substr(i, 4) intercepts string, i += 4
    for(int i = 0; i < s.size(); i += 4)
    {
        t = s.substr(i, 4);
        // Convert 4-bit binary to hexadecimal and output
        cout << num(t);
    }

    return 0;
}

2. Hexadecimal to binary

Idea: convert the hexadecimal number of each bit to 4-bit binary number!

Step 1: convert each hexadecimal to 4-bit binary and connect it to the string!

Step 2: clear the leading 0, that is, output from the first non-0. Note: when hexadecimal is 0000, it is also 0 after being converted to binary. At this time, you can't clear all 0000, but keep a 0!

[reference code]

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>


using namespace std;
typedef long long LL;
const int N = 1e5 + 10;
// skill:
string t[16] = {"0000","0001","0010","0011","0100","0101","0110","0111","1000","1001","1010","1011","1100","1101","1110","1111"};


//Find: convert each hexadecimal to the corresponding 4 to binary
//1. Convert s[i] into an integer corresponding to 0 ~ 15, and then find the corresponding 4-bit binary (skill: obtain the corresponding binary through the array subscript)
//2. Finally clear the leading 0 of binary string
int main()
{   
    string s, r; // s stores hexadecimal; r store binary
    cin >> s; 
    
    for(int i = 0; i < s.size(); i ++)
    {
        //1. Convert s[i] to an integer corresponding to 0 ~ 15
        int x;
        if(s[i] >= '0' && s[i] <= '9') x = s[i] - '0'; // If 0 ~ 9
        else x = s[i] - 'A' + 10;
        
        //1. Concatenate the binary represented by hexadecimal with string
        r += t[x];
    }
    
    //2. Finally clear the leading 0
    while(r[0] == '0' && r.size() > 1)
    {
        r.erase(0,1);
    }
    
    cout << r;

    return 0;
}

The function of the: erase() function in C++ STL is used to delete elements in the container

erase(first,last);------> Left closed right open: [first, last)

3. Binary to octal

Title Description

Please convert a binary integer within 100 bits to an octal integer!

input

Binary integer within 100 bits

output

The octal integer corresponding to the number

Sample

input

111100001111000011110000

output

74170360

Idea: the same as the above binary to hexadecimal

Step 1: judge whether the length of the string is a multiple of 3. If not, supplement 0.

s: Character array

s. Size()% 3 = = 1, fill in 2 zeros

s. Size()% 4 = = 2, make up 1 0

Step 2: convert every 3-digit binary number into 1-digit octal number (07) for output. (the binary number of every 3 bits is: 08, 9 is 1001 four digits!), that is, convert it into the corresponding hexadecimal number

[reference code]

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;
typedef long long LL;
const int N = 1e5 + 10;

// Convert the 3-bit binary (must be 0 ~ 7) into a decimal integer, and the corresponding octal must be 0 ~ 7
LL num(string s)
{

    LL t = 1, r = 0;
    // Expand by weight from the lowest bit and convert to hexadecimal
    for(int i = s.size() - 1; i >= 0; i --)
    {
        r = r + (s[i] - '0') * t;
        t = t * 2;
    }
    
    return r;
}

int main()
{   
    string s, t; // s store binary
    cin >> s;
    
    // See if you need to make up 0
    if(s.size() % 3 == 1) s = "00" + s;
    else if(s.size() % 3 == 2) s = "0" + s;
    
    // Intercept 3-bit binary, convert to corresponding octal, output
    for(int i = 0; i < s.size(); i += 3)
    {
        t = s.substr(i, 3);
        
        // Convert every 3 bits of binary to octal and output
        cout << num(t);
    }

    return 0;
}

4. Octal to binary

Title Description

Please convert an octal integer within 100 bits to a binary integer!

input

Octal integer within 100 bits

output

The number corresponds to a binary integer

Sample

input

12376532347173217361

output

1010011111110101011010011100111001111011010001111011110001

Idea: the same as hexadecimal to binary: convert the 8-digit number of each bit into a 3-digit binary number!

Step 1: convert each octal (0 ~ 7) to 3-bit binary and connect it to the string!

Step 2: clear the leading 0, that is, output from the first non-0. Note: when octal is 000, it is also 0 after binary conversion. At this time, you can't clear all 000, but keep a 0!

[reference code]

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>


using namespace std;
typedef long long LL;
const int N = 1e5 + 10;

// Store 3-bit binary corresponding to 0 ~ 7 octal
string t[8] = {"000","001","010","011","100","101","110","111"};


int main()
{   
    string s, r; // s stores octal and r stores binary
    
    cin >> s;
    
    // Octal - > binary: convert each bit of octal to 3-bit binary (directly obtained through the number corresponding array!), and then splice
    for(int i = 0; i < s.size(); i ++)
    {
        int x = s[i] - '0'; // Find the binary representation corresponding to each bit of octal
        r += t[x]; // Splicing
    }
    
    // Clear leading 0
    while(r[0] == '0' && r.size() > 1)
    {
        r.erase(0, 1);
    }
    
    cout << r;
    
    return 0;
}

Binary conversion application example: Xiao Li finds half a palindrome number

Find that this number is not a palindrome number in decimal system, but it is a palindrome number in binary or hexadecimal system, then this number is half a palindrome number!

Idea:

With a simple idea, judge whether the decimal number is a palindrome number. If not, convert it to binary number and hexadecimal number, and then judge whether it is a palindrome number!

We found a very similar operation, that is, whether this number is a palindrome in the d-ary representation. We know that the short division is used to convert the 10-ary number to other bases! We don't need to judge whether it is a palindrome by the final result of the binary representation. We can save each bit remainder in an array to judge whether its remainder is a palindrome! - therefore, We can write a judgment function to make a unified judgment!

[reference code]

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>


using namespace std;
typedef long long LL;
const int N = 1e5 + 10;
LL n, x;
int a[N]; // Store the remainder corresponding to each bit from n to d, which is used to judge whether it is a palindrome number

// Convert decimal number n to d-ary number and judge whether it is a palindrome!
bool huiwen(int n, int d)
{ 
    int k = 0;
    while(n != 0)
    {
        x = n % d;
        a[k ++] = x; // Store remainder
        n /= d;
    }
    // Judge palindromes: whether the symmetrical bits are equal. If they are unequal, it is not the number of palindromes
    for(int i = 0; i < k / 2; i ++)
    {
        //0 --> k - 1
        //1 --> k - 2
        //2 --> k - 3... i --> k - i - 1
        if(a[i] != a[k - i -1])
        {
            return false;
            break;
        }
    }
    
    return true;
}

int main()
{   
    cin >> n;
    while(n --)
    {
        int x;
        cin >> x;
        if(huiwen(x, 10) == false && (huiwen(x, 2) == true || huiwen(x, 16) == true))
        {
            cout << x << endl;
        }
    }
    
    return 0;
}

4, Summary

Hexadecimal conversion can be converted by analogy with 10 hexadecimal computer system, and the principle formula of conversion can be clear. When converting from 8 / 16 to 2, a string array is used to record the 3 / 4-bit binary representation of each bit of 8 / 16, which can be used directly during conversion to speed up efficiency!

Note: if there are any mistakes or deficiencies in the article, please point out them and leave your valuable suggestions! If this article is of some help to you, I hope you can praise and recommend it. Thank you very much

Posted on Sun, 05 Dec 2021 20:18:40 -0500 by 99naa