How to convert a Decimal number to Binary number using divide and conquer technique? - divide-and-conquer

I am stuck with a question which says to apply divide and conquer to convert a decimal number to binary.
I have written this simple code for conversion but don't know how can I apply divide and conquer here.
def d2b(n):
b = []
while n > 0:
r = n%2
n //= 2
b.insert(0,r)
return b
Any idea or hint would be a great help. I want to construct a function which uses a divide and conquer method.

Try it.
C# program to convert a decimal
number to binary number
using System;
public class Dese
{
// function to convert decimal
// to binary
static void decToBinary(int n)
{
// array to store binary number
int[] binaryNum = new int[1000];
// counter for binary array
int i = 0;
while (n > 0)
{
// storing remainder in
// binary array
binaryNum[i] = n % 2;
n = n / 2;
i++;
}
// printing binary array
// in reverse order
for (int j = i - 1; j >= 0; j--)
Console.Write(binaryNum[j]);
}
// Driver Code
public static void Main ()
{
int n = 17;
decToBinary(n);
}
}

Related

Generate n-digit prime numbers given their first m digits

Digressing a bit on the site I came across this question, It is clear to me that generating prime numbers is complicated and some of the solutions given in that question to make the problem easier are good and ingenious, It occurs to me that perhaps giving the program some leading digits for large primes will make the search easier, is this correct? For example, perhaps finding 10-digit primes starting with 111 is easier than generating all 10-digit primes (even the more leading digits provided this makes it less complex).
Searching on the net (I must clarify that I am not a mathematician and I am not a computer scientist) I found the following code to generate primes of n digits
#include <bits/stdc++.h>
using namespace std;
const int sz = 1e5;
bool isPrime[sz + 1];
// Function for Sieve of Eratosthenes
void sieve() {
memset(isPrime, true, sizeof(isPrime));
isPrime[0] = isPrime[1] = false;
for (int i = 2; i * i <= sz; i++) {
if (isPrime[i]) {
for (int j = i * i; j < sz; j += i) {
isPrime[j] = false;
}
}
}
}
// Function to print all the prime
// numbers with d digits
void findPrimesD(int d) {
// Range to check integers
int left = pow(10, d - 1);
int right = pow(10, d) - 1;
// For every integer in the range
for (int i = left; i <= right; i++) {
// If the current integer is prime
if (isPrime[i]) {
cout << i << " ";
}
}
}
// Driver code
int main() {
// Generate primes
sieve();
int d = 1;
findPrimesD(d);
return 0;
}
My question is, how to take advantage of this code to give it the first m digits and thus make the search easier and smaller?

How do I convert a number into an 8-bit binary rather than 4-bit

void decimaltobin()
{
binaryNum = 0;
m = 1;
while (num != 0)
{
rem = num % 2;
num /= 2;
binaryNum += rem * m;
m *= 10;
}
}
Just wondering if there was an easy fix to get this function to print an 8-bit binary number instead of a 4-bit number, e.g. 0000 0101 instead of 0101.
As mentioned in the comments, your code does not print anything yet and the data type of binaryNum is not clear. Here is a working solution.
#include <iostream>
using namespace std;
void decToBinary(int n)
{
// array to store binary number
int binaryNum[32];
// counter for binary array
int i = 0;
while (n > 0) {
// storing remainder in binary array
binaryNum[i] = n % 2;
n = n / 2;
i++;
}
// printing the required number of zeros
int zeros = 8 - i;
for(int m = 0; m < zeros; m++){
cout<<0;
}
// printing binary array in reverse order
for (int j = i - 1; j >= 0; j--)
cout << binaryNum[j];
}
// Driver program to test above function
int main()
{
int n = 17;
decToBinary(n);
return 0;
}
The code implements the following:
Store the remainder when the number is divided by 2 in an array.
Divide the number by 2
Repeat the above two steps until the number is greater than zero.
Print the required number of zeros. That is 8 - length of the binary number. Note that this code will work for numbers that can be expressed in 8 bits only.
Print the array in reverse order now
Ref
Maybe I am missing your reason but why do you want to code from scratch instead of using a standard library?
You may use standard c++ without having to code a conversion from scratch using for instance std::bitset<NB_OF_BITS>.
Here is a simple example:
#include <iostream>
#include <bitset>
std::bitset<8> decimalToBin(int numberToConvert)
{
return std::bitset<8>(numberToConvert);
}
int main() {
int a = 4, b=8, c=12;
std::cout << decimalToBin(a)<< std::endl;
std::cout << decimalToBin(b)<< std::endl;
std::cout << decimalToBin(c)<< std::endl;
}
It outputs:
00000100
00001000
00001100

Converting from Decimal to BCD

// C++ program to convert a decimal
// number to binary number
#include <iostream>
using namespace std;
// function to convert decimal to binary
void decToBinary(int n)
{
// array to store binary number
int binaryNum[1000];
// counter for binary array
int i = 0;
while (n > 0) {
// storing remainder in binary array
binaryNum[i] = n % 2;
n = n / 2;
i++;
}
// printing binary array in reverse order
for (int j = i - 1; j >= 0; j--)
cout << binaryNum[j];
}
// Driver program to test above function
int main()
{
int n = 17;
decToBinary(n);
return 0;
}
So this is a program to convert Decimal numbers to Binary. Now I'm trying to convert Decimal Numbers to BCD. I get the concept, if I have a number like 215 for example, I separate each number [2,1,5] and then convert each number into binary so it would be 0010,0001,0101. I am just confused about implementing it.
First of all, your algorithm simply displays the binary representation of some number n, instead of dividing it into single digits and returning some set of their binary representation.
To make out lives easier, we will be using standard containers and standard algorithms:
[...] if i have a number like 215 for example, i seperate each number [2,1,5] and then covert each number into binary so it would be 0010,0001,0101
Great, it means that we need some sort of a container to hold those three representations, don't we? My choice would be std::vector, since it is incredibly simple and efficient! You can read more about it here.
The mentioned vector will eventually store the binary representations, but here we encounter another problem - we actually need to somehow represent them!
Fortunately enough, the standard gives us a great tool - std::bitset, which is explained here. It is primarily used to make binary operations easier, but one of its great features is that it's also extremely good at simply being a binary representation.
The final function could look like this:
auto dec_to_bin(int n)
{
std::vector<std::bitset<4>> repr;
while(n > 0){
repr.push_back(std::bitset<4>(n % 10));
n /= 10;
}
std::reverse(repr.begin(), repr.end());
return repr;
}
What is happening here?
We firstly create a vector of fixed size bitsets (of the size 4, since every decimal digit can be represented as four binary digits), then as long as our n is greater than zero (you already know why - you are using the same logic in your code), we add (using push_back) a new bitset, that will be treated as binary representation of modulo of your number (i.e. the last digit).
Keep in mind though, that by doing this, we created the vector in the reversed order. The last two things we have to do is simply reverse and return it!
Finally, we can use our function in main as such:
int main()
{
for(auto b : dec_to_bin(215)){
std::cout << b << ' ';
}
}
This will print 0010 0001 0101, which was your desired output for the number 215
Can't you just replace the % 2 and / 2 with % 10 and / 10? The variables will be named wrong but that's the algorithmic change.
You simply have to divide your integer by digits and call your function for each digit:
void decToBCD(int n) {
// array to store digits
int digits[10];
// counter for digits
int i = 0;
while (n > 0) {
// storing remainder in digit array
digits[i] = n % 10;
n = n / 10;
i++;
}
// printing binary representation of digits
for (int j = i - 1; j >= 0; j--) {
decToBinary(digits[j]);
cout << " ";
}
}
I would update what you have to return a string from decToBinary rather than printing to cout, you can then write decToBCD which uses modulo 10 to work out the integer for each digit of the number (in the same way you used modulo 2 and divide by 2 to get each bit in decToBinary), and call decToBinary for each integer digit and concatenates the strings of binary digits to give the full result.

lcm of all numbers in an array in c++

I came across this piece of code to compute least common factor of all numbers in an array but could not understand the algorithm used. What is the use of __builtin_popcount here which is used to count the number of set bits?
pair<long long, int> pre[200000];
long long a[25], N;
long long trunc_mul(long long a, long long b)
{
return a <= INF / b ? a * b : INF;
}
void compute()
{
int limit = 1 << N;
limit--;
for (int i = 1; i <= limit; i++)
{
long long lcm = 1;
pre[i].second = __builtin_popcount(i);
int k = 1;
for (int j = N - 1; j >= 0; j--)
{
if (k&i)
{
lcm = trunc_mul(lcm / __gcd(lcm, a[j]), a[j]);
}
k = k << 1;
}
pre[i].first = lcm;
}
return;
}
The code snipped you provided is given up to 25 numbers. For each subset of numbers it computes their LCM into pre[i].first and number of them in that subset into pre[i].second. The subset itself is represented as a bitmask, therefore to compute number of elements in the subset the snippet uses __builtin_popcount. It has nothing to do with the computation of the LCM.
LCM is computed using a rather standard approach: LCM of any set of numbers is equal to their product divided by their GCD. This is exactly what this snipped does, using builtin GCD function __gcd.
The k&i and k = k<<1 part is to figure out what numbers belong to a set represented by a bitmask. If you don't fully understand it, try to see what happens if i = 0b11010, by running this loop on a piece of paper or in the debugger. You will notice that k&i condition will be true on the second, fourth and fifth iteration, precisely the positions at which i has ones in its binary representation.

Intitutive method to find prime numbers in a range

While trying to find prime numbers in a range (see problem description), I came across the following code:
(Code taken from here)
// For each prime in sqrt(N) we need to use it in the segmented sieve process.
for (i = 0; i < cnt; i++) {
p = myPrimes[i]; // Store the prime.
s = M / p;
s = s * p; // The closest number less than M that is composite number for this prime p.
for (int j = s; j <= N; j = j + p) {
if (j < M) continue; // Because composite numbers less than M are of no concern.
/* j - M = index in the array primesNow, this is as max index allowed in the array
is not N, it is DIFF_SIZE so we are storing the numbers offset from.
while printing we will add M and print to get the actual number. */
primesNow[j - M] = false;
}
}
// In this loop the first prime numbers for example say 2, 3 are also set to false.
for (int i = 0; i < cnt; i++) { // Hence we need to print them in case they're in range.
if (myPrimes[i] >= M && myPrimes[i] <= N) // Without this loop you will see that for a
// range (1, 30), 2 & 3 doesn't get printed.
cout << myPrimes[i] << endl;
}
// primesNow[] = false for all composite numbers, primes found by checking with true.
for (int i = 0; i < N - M + 1; ++i) {
// i + M != 1 to ensure that for i = 0 and M = 1, 1 is not considered a prime number.
if (primesNow[i] == true && (i + M) != 1)
cout << i + M << endl; // Print our prime numbers in the range.
}
However, I didn't find this code intuitive and it was not easy to understand.
Can someone explain the general idea behind the above algorithm?
What alternative algorithms are there to mark non-prime numbers in a range?
That's overly complicated. Let's start with a basic Sieve of Eratosthenes, in pseudocode, that outputs all the primes less than or equal to n:
function primes(n)
sieve := makeArray(2..n, True)
for p from 2 to n
if sieve[p]
output(p)
for i from p*p to n step p
sieve[p] := False
This function calls output on each prime p; output can print the primes, or sum the primes, or count them, or do whatever you want to do with them. The outer for loop considers each candidate prime in turn; The sieving occurs in the inner for loop where multiples of the current prime p are removed from the sieve.
Once you understand how that works, go here for a discussion of the segmented Sieve of Eratosthenes over a range.
Have you considered the sieve on a bit level, it can provide a bit larger number of primes, and with the buffer, you could modify it to find for example the primes between 2 and 2^60 using 64 bit ints, by reusing the same buffer, while preserving the offsets of the primes already discovered. The following will use an array of integers.
Declerations
#include <math.h> // sqrt(), the upper limit need to eliminate
#include <stdio.h> // for printing, could use <iostream>
Macros to manipulate bit, the following will use 32bit ints
#define BIT_SET(d, n) (d[n>>5]|=1<<(n-((n>>5)<<5)))
#define BIT_GET(d, n) (d[n>>5]&1<<(n-((n>>5)<<5)))
#define BIT_FLIP(d, n) (d[n>>5]&=~(1<<(n-((n>>5)<<5))))
unsigned int n = 0x80000; // the upper limit 1/2 mb, with 32 bits each
// will get the 1st primes upto 16 mb
int *data = new int[n]; // allocate
unsigned int r = n * 0x20; // the actual number of bits avalible
Could use zeros to save time but, on (1) for prime, is a bit more intuitive
for(int i=0;i<n;i++)
data[i] = 0xFFFFFFFF;
unsigned int seed = 2; // the seed starts at 2
unsigned int uLimit = sqrt(r); // the upper limit for checking off the sieve
BIT_FLIP(data, 1); // one is not prime
Time to discover the primes this took under a half second
// untill uLimit is reached
while(seed < uLimit) {
// don't include itself when eliminating canidates
for(int i=seed+seed;i<r;i+=seed)
BIT_FLIP(data, i);
// find the next bit still active (set to 1), don't include the current seed
for(int i=seed+1;i<r;i++) {
if (BIT_GET(data, i)) {
seed = i;
break;
}
}
}
Now for the output this will consume the most time
unsigned long bit_index = 0; // the current bit
int w = 8; // the width of a column
unsigned pc = 0; // prime, count, to assist in creating columns
for(int i=0;i<n;i++) {
unsigned long long int b = 1; // double width, so there is no overflow
// if a bit is still set, include that as a result
while(b < 0xFFFFFFFF) {
if (data[i]&b) {
printf("%8.u ", bit_index);
if(((pc++) % w) == 0)
putchar('\n'); // add a new row
}
bit_index++;
b<<=1; // multiply by 2, to check the next bit
}
}
clean up
delete [] data;