I'm trying to solve a problem, for the basic scenario it's working, nevertheless, I know that it is not optimal and has several faults.
Problem:
You are given a number n. Find the decimal value of the number formed by the concatenation of the binary representation of the first n positive integers. Print the answer 10^9 + 7.
Output format:
Print the answer modulo 10^9 + 7
Constraint:
1 <= n <= 10^9
Sample input: 3
Sample Output: 27
The binary representation of 1: 1
The binary representation of 2: 10
The binary representation of 3: 11
Concatenated string: 11011 -> Decimal representation is 27.
The first doubt that I have is: "modulo 10^9 + 7", I understand is the limit for the number of chars, but I don't know how to interpret it.
The second part of the question is with the solution:
Input: 20
Binary representation of 2 : 10.
Binary representation of 3 : 11
Binary representation of 4 : 100.
Binary representation of 5 : 101
Binary representation of 6 : 110
Binary representation of 7 : 111
Binary representation of 8 : 1000
Binary representation of 9 : 1001
Binary representation of 10 : 1010
Binary representation of 11 : 1011
Binary representation of 12 : 1100
Binary representation of 13 : 1101
Binary representation of 14 : 1110
Binary representation of 15 : 1111
Binary representation of 16 : 10000
Binary representation of 17 : 10001
Binary representation of 18 : 10010
Binary representation of 19 : 10011
The binary representation of 20: 10100
Concatenated string: 11011100101110111100010011010101111001101111011111000010001100101001110100
How would you recommend to tackle this kind of problem?
This is my current code:
public long FindBigNum(long n) {
System.out.println("");
System.out.println("Input: " + n);
StringBuilder binaryRepresentation = new StringBuilder();
for(Long i = 1l; i <= n; i++){
System.out.println("Binary representation of " + i + " : " + Long.toBinaryString(i));
binaryRepresentation.append(Long.toBinaryString(i));
}
System.out.println("Concatenated string: " + binaryRepresentation.toString());
//System.out.println("Binary representation: " + binaryRepresentation.toString());
long longRepresentation = parseLong(binaryRepresentation.toString(), 2);
//System.out.println("longRepresentation: " + l);
return longRepresentation;
}
public long parseLong(String s, int base){
return new BigInteger(s, base).longValue();
}
public class TestClass {
static long FindBigNum(long n) {
long result = 0;
StringBuilder binary = new StringBuilder();
long binarySumLong;
long moduloFactor = (long) (Math.pow(10, 9) + 7);
for (int number = 1; number < n; number++) {
System.out.println("Number is : " + number);
String binaryRepresentation = Long.toBinaryString(number);
System.out.println("Binary representation of " + number + " is " + binaryRepresentation);
binary.append(binaryRepresentation);
System.out.println("Value of StringBuffer binary is " + binary);
binarySumLong = binaryToInteger(binary.toString());
System.out.println("binarySumLong is : " + binarySumLong);
if (binarySumLong > (moduloFactor)) {
binarySumLong = binarySumLong % (moduloFactor);
binary = new StringBuilder(Long.toBinaryString(binarySumLong));
System.out.println(" *** binary after modification is : " + binary);
System.out.println(" *** and integer value of binary is : " + binaryToInteger(binary.toString()));
}
}
result = binaryToInteger(binary.toString());
return result;
}
public static int binaryToInteger(String binary) {
char[] numbers = binary.toCharArray();
int result = 0;
for (int i = numbers.length - 1; i >= 0; i--)
if (numbers[i] == '1')
result += Math.pow(2, (numbers.length - i - 1));
return result;
}
public static void main(String[] args) {
long output = FindBigNum((long) Math.pow(10, 4));
System.out.println("output is : " + output);
}
}
The first doubt that I have is: "modulo 10^9 + 7", I understand is the limit for the number of chars, but I don't know how to interpret it.
That means to get the remainder when dividing by that value. It is the value 1000000007 (I am assuming the caret is exponentiation).
Here is how I would approach this.
Generate your concatenated strings as you have been.
Use BigInteger to convert from binary to decimal and then take the mod with the BigInteger mod method.
That will ultimately be very slow and not efficient. However, it serves as a control to allow you to investigate optimal ways of doing it. Perhaps employing StringBuilder and pre-allocating storage for it. Writing your own int to binary conversion routine, etc.
It may even require more of a math solution (e.g. number theory) than a programming solution.
But you can compare your results to the BigInteger solution to verify if it is working.
Related
Java. I want to make an array of binary numbers available in negative form but I want the original positive binary numbers to remain there as well so I can use both positive and negative numbers in my program, but I can't find out a way to convert all the binary numbers I have in my array to negative binary numbers.
class Logicgates {
public static void main (String args[]) {
String binary[] = {
"0000","0001","0010","0011","0100","0101","0110","0111","1000","1001","1010","1011","1100","1101","1110","1111"
};
int a = 3;
int b = 5;
int c = a | b; // 0010|0100 = 0110
int d = a & b; // 0010&0100 = 0000
int ff= a ^ b;
int f = ~((~a&b) ^ (~b | a));
int g = ~f | 0x0f;
System.out.println("a = " + binary[a]);
System.out.println("b = " + binary[b]);
System.out.println("c = " + binary[c]);
System.out.println("d = " + binary[d]);
System.out.println("ff = " + binary[ff]);
System.out.println("f = " + binary[f]);
System.out.println("g = " + binary[g]);
}
}
here the value of g is -1 but since my array only contains positive 1 I can't print it.
If you want to use your original array I completely understand, as it may be a requirement to your assignment / project / learning experience.
If not, Java actually has a built in function in the java.lang library that will convert a decimal number to a binary number. The output may not be exactly what you are looking for, so you may have to make a few changes.
import java.lang.*;
public static void main(String[] args) {
int positive = 14;
System.out.println("Positive Number = " + positive);
int negative = -14;
System.out.println("Negative Number = " + negative);
//to binary
System.out.println("Positive Binary is " + Integer.toBinaryString(positive));
System.out.println("Negative Binary is " + Integer.toBinaryString(negative));
}
The output for this snippet will be
Positive Number = 14
Negative Number = -14
Positive Binary is 1110
Negative Binary is 11111111111111111111111111110010
As you can see, the negative number outputs the entire 32-bit string, but it should be simple enough for you to trim it down to the size you are looking for (e.g. 4-bit or 5-bit).
With this approach you won't be required to have your array of binary strings. You can simply pass the number to the toBinaryString() function and it will convert it for you.
After that you just need to add your logic for the gates you are trying to simulate.
Hopefully this points you in the right direction. Good luck!
I have a main function that calls another function and passes the given number as a parameter. In the other function, I want to break up the given number into sums of power. How can this be done?
My code looks like:
public static void main()
{
String hello=raisetopower(in.nextInt());
}
public String raisetopower(int n)
{
// do the logic
}
Explanation :
say if the number is 25: the function should return 5^2 + 0^2
and if it is 26: 5^2+1^2
I agree with Richard's comment that this more Mathematics than Java
The question needs more information to be able to provide code to assist, such as whether or not you consider a maximum base like 10 and whether or not all bases should be in the output even if they are to the power of 0 as your example is confusing:
"say if the number is 25: the function should return 5^2 + 0^2 and if
it is 26: 5^2+1^2"
However with that in mind, hopefully this example will be able to assist
Assuming you do have a maximum base being considered, you could start from the highest base to the lowest and use logs
If the result of the log is greater than or equal to 1, then this value should be in the output, so subtract that value and continue on to the next base
Keep continuing until you hit a value of exactly 1 and that should be your end condition
E.g assuming a maximum base of 5 for this example with an input of 27
log5 27 = 2.04781858346
so we will have 5^2 in the output and subtract this from the input, you could use floor to extract the '2'
log4 2 = 0.5
less than one so not an integer power
log3 2 = 0.630929753571
less than one so not an integer power
log2 2 = 1
add to output as greater than or equal to 1 and terminate as it is exactly 1
If you're only displaying bases with powers greater than or equal to one (this was unclear), your output at this point would be:
27 = 25^2 + 2^1
You could use a StringBuilder or an ordered collection of custom objects holding your bases and powers to make it easier to generate the output
Here's an SSCCE for my above algorithm:
import java.util.Scanner;
public class NumberToPowerConversion {
public static void main(String[] args) {
int maxBaseToConsider = 5;
System.out.println("Input number to convert: ");
Scanner input = new Scanner(System.in);
int number = input.nextInt();
StringBuilder output = new StringBuilder("Represented as powers: " + number + " = ");
for(int base = maxBaseToConsider; base >= 1; base--){
//Prevent division by 0 (log 1)
double logResult = base > 1 ? Math.log(number) / Math.log(base) : 1;
int floorResult = (int)Math.floor(logResult);
if(number == 1 || logResult == 1.0){
output.append(base + "^" + floorResult);
number -= Math.pow(base, floorResult);
if(number != 0){
//If the number couldn't be broken down completely, add the remainder to the output
output.append(" + " + number + "^1"); //To keep format consistent
}
break; //end condition reached
}
else if(floorResult >= 1){
output.append(base + "^" + floorResult);
number -= Math.pow(base, floorResult);
if(number == 0){ break; }
else{ output.append(" + "); }
}
}
System.out.println(output.toString());
}
}
Example output:
Represented as powers: 27 = 5^2 + 2^1
Represented as powers: 77 = 5^2 + 4^2 + 3^3 + 2^3 + 1^1
Represented as powers: 234 = 5^3 + 4^3 + 3^3 + 2^4 + 1^1 + 1^1
Represented as powers: 99 = 5^2 + 4^3 + 3^2 + 2^0
Represented as powers: 1 = 5^0
I have actually found the solution of this problem over here : https://github.com/Widea/Interview-Questions/blob/master/Hard/Random/PowerNumbers.java
/* Algorithm :
i <- square root of n
while n<1
n <- n-square of i
r <- r concatenate with i^2
if n=0 r concatenate with i^0
if n=1 r concatenate with i^1
i <- square root of n
return r
*/
public static String raisetopower(int n){
String raised="";
int i=(int)Math.sqrt(n);
while(n>1){
n=n-(int)Math.pow(i,2);
raised+=String.valueOf(i)+"^2+";
if(n==0)
raised+="0^2";
if(n==1)
raised+="1^2";
i=(int)Math.sqrt(n);
}
return raised;
}
I was working on a homework and thought I had finished but the teacher told me that it wasn't what he was looking for so I need to know how I can convert a binary number that is stored as a String to a decimal string without using any built-in function outside of length(), charAt(), power function, and floor/ceiling in Java.
This is what I had on the beginning.
import java.util.Scanner;
public class inclass2Fall15Second {
public static void convertBinaryToDecimalString() {
Scanner myscnr = new Scanner(System.in);
int decimal = 0;
String binary;
System.out.println("Please enter a binary number: ");
binary = myscnr.nextLine();
decimal = Integer.parseInt(binary, 2);
System.out.println("The decimal number that corresponds to " + binary + " is " + decimal);
}
public static void main (String[] args) {
convertBinaryToDecimalString();
}
}
To convert a base 2 (binary) representation to base 10 (decimal), multiply the value of each bit with 2^(bit position) and sum the values.
e.g. 1011 -> (1 * 2^0) + (1 * 2^1) + (0 * 2^2) + (1 * 2^3) = 1 + 2 + 0 + 8 = 11
Since binary is read from right-to-left (i.e. LSB (least significant bit) is on the rightmost bit and MSB (most-significant-bit) is the leftmost bit), we traverse the string in reverse order.
To get the bit value, subtract '0' from the char. This will subtract the ascii value of the character with the ascii value of '0', giving you the integer value of the bit.
To calculate 2^(bit position), we can keep a count of the bit position, and increment the count on each iteration. Then we can just do 1 << count to obtain the value for 2 ^ (bit position). Alternatively, you could do Math.pow(2, count) as well, but the former is more efficient, since its just a shift-left instruction.
Here's the code that implements the above:
public static int convertBinStrToInt(String binStr) {
int dec = 0, count = 0;
for (int i = binStr.length()-1; i >=0; i--) {
dec += (binStr.charAt(i) - '0') * (1 << count++);
}
return dec;
}
For instance, How would I be able to convert 2^60 or 12345678901234567890123456789012345678901234567890 to binary?
Basically, numbers that are too large to represent in Java.
Edit: I will be making a class that will be able to represent number that are too large. I'm just having a hard time figuring our how to convert decimal to binary.
Edit2: And also, I am not allowed to use BigDecimal, BigInteger, or any other library, sorry for not specifying earlier.
Here is a quik&dirty (very very very dirty) code:
public class BigDec2Bin {
public static int[] string2arrayReversed( String s )
{
char a[] = s.toCharArray();
int b[] = new int[ s.length() ];
for( int i = 0; i < a.length; i++ )
{
b[a.length-1-i] = a[i] - 48;
}
return b;
}
// adds two binary numbers represented as strings
public static String add( String s1, String s2 )
{
String result = "", stmp;
int[] a1, a2;
int ctmp, mark = 0;
// a1 should be the longer one
a1 = string2arrayReversed( ( s1.length() > s2.length() ? s1 : s2 ) );
a2 = string2arrayReversed( ( s1.length() < s2.length() ? s1 : s2 ) );
for( int i = 0; i < a1.length; i++ )
{
ctmp = a1[i] + ( i < a2.length ? a2[i] : 0 ) + mark;
switch( ctmp )
{
default:
case 0:
stmp = "0";
mark = 0;
break;
case 1:
stmp = "1";
mark = 0;
break;
case 2:
stmp = "0";
mark = 1;
break;
case 3:
stmp = "1";
mark = 1;
break;
}
result = stmp + result;
}
if( mark > 0 ) { result = "1" + result; }
return result;
}
public static String dec2bin( String s )
{
String result = "";
for( int i = 0; i < s.length() ; i++ )
{
result = add( result + "0", result + "000" );
result = add( result, Integer.toBinaryString( s.charAt(i) - 48 ) );
}
return result;
}
public static void main( String[] args )
{
String dec = "12345"; // should be 11000000111001
System.out.println( "dec2bin( " + dec + " ) = " + dec2bin( dec ) );
dec = "12345678901234567890123456789012345678901234567890";
System.out.println( "dec2bin( " + dec + " ) = " + dec2bin( dec ) );
}
}
Output:
dec2bin( 12345 ) = 011000000111001
dec2bin(
12345678901234567890123456789012345678901234567890
) =
10000111001001111111011000110110100110101010111110000011110010100001010100000010011001110100011110101111100011000111111100011001011011001110001111110000101011010010
My main idea is to use always strings.
add -method adds two binary numbers which are represented as strings
dec2bin -method is where the magic happens.
Allow me to explain:
result = add( result + "0", result + "000" );
is a calculation to multiply any given number by 10.
Multiplying a binary number by 10 is the same as adding the number with shifts:
x*10 <=> x<<1 + x<<3
result = add( result, Integer.toBinaryString( s.charAt(i) - 48 ) );
just adds a the next digit (from left to right) on the result string
Basicly what I'm doing is for example with 1234:
0*10 + 1 = 1
1*10 + 2 = 12
12*10 + 3 = 123
123*10 + 4 = 1234
but only in binary (represented as strings).
I hope i could help and sorry for my bad english.
Try this:
new BigDecimal("12345678901234567890123456789012345678901234567890").toString(2);
Edit:
For making a big-number class, you may want to have a look at my post about this a week ago. Ah, the question was by you, never mind.
The conversion between different number systems in principle is a repeated "division, remainder, multiply, add" operation. Let's look at an example:
We want to convert 123 from decimal to a base 3 number. What do we do?
Take the remainder modulo 3 - prepend this digit to the result.
Divide by 3.
If the number is bigger than 0, continue with this number at step 1
So it looks like this:
123 % 3 == 0. ==> The last digit is 0.
123 / 3 == 41.
41 % 3 == 2 ==> The second last digit is 2.
41 / 3 == 13
13 % 3 == 1 ==> The third digit is 1.
13 / 3 == 4
4 % 3 == 1 ==> The fourth digit is 1 again.
4 / 3 == 1
1 % 3 == 1 ==> The fifth digit is 1.
So, we have 11120 as the result.
The problem is that for this you need to have already some kind of division by 3 in decimal format, which is usually not the case if you don't implement your number in a decimal-based format (like I did in the answer to your last question linked above).
But it works for converting from your internal number format to any external format.
So, let's look at how we would do the inverse calculation, from 11120 (base 3) to its decimal equivalent. (Base 3 is here the placeholder for an arbitrary radix, Base 10 the placeholder for your internal radix.) In principle, this number can be written as this:
1 * 3^4 + 1 * 3^3 + 1*3^2 + 2*3^1 + 0*3^0
A better way (faster to calculate) is this:
((((1 * 3) + 1 )*3 + 1 )*3 + 2)*3 + 0
1
3
4
12
13
39
41
123
123
(This is known as Horner scheme, normally used for calculating values of polynomials.)
You can implement this in the number scheme you are implementing, if you know how to represent the input radix (and the digits) in your target system.
(I just added such a calculation to my DecimalBigInt class, but you may want to do the calculations directly in your internal data structure instead of creating a new object (or even two) of your BigNumber class for every decimal digit to be input.)
What about this approach:
result = 0;
for each digit in the decimal number, from left to right
result = result * 10 + digit;
return result;
So we need a way to represent an arbitrarily large binary number, and implement multiplication by 10 and addition of small numbers.
The most straightforward way to represent an arbitrarily large binary number is an array of its binary digits. You can then apply the algorithms for addition and multiplication your learned in elementary school, except that digits will "overflow" when they exceed 1 rather than 9. For example:
1010 * 1100111
----------------
11001110
+ 1100111000
----------------
10000000110
Pew: thanks, that works for some numbers. The number 6123456789012 however doesn't work, but here is the fix:
// a1 should be the longer one
a1 = string2arrayReversed( ( s1.length() >= s2.length() ? s1 : s2 ) ); //GREATER EQUAL
If you only work with integers, use BigInteger.toByteArray.
If not, unfortunately BigDecimal doesn't have that method. But I suppose you can always (in both cases) just ASCII encode the string representation of the number, if the binary form is just meant for transfer and not calculation anywhere.
there is a fast program to get the binary representation of a huge decimal.
This programm is indeed fast, it takes only 20ms to deal with a decimal with 3000digits, eg:string(3000,'2')+'12345'. because of the pursuit of efficiency, it is not very readable. you can modify it yourself to make it easier to understand.
inline string remove_pre_zero(const string& a)
{
auto t = a.find_first_not_of('\0', 0);
if (t == a.npos)
return string("0");
else
return a.substr(t);
}
string convert_to_bin(const string& _s)
{
const static string str[] = { "0", "1" };
string s(_s.size(), '0');
string binary;
binary.reserve(_s.size()*3);
int i = 0;
for (const auto& c : _s)
s[i++] = (c - '0');
while (s!="0")//simulate divide by 2
{
int t = 0, old_t = 0;
for (auto& ch : s)
{
t = ((old_t * 10 + ch) & 1);
ch = (ch + old_t * 10) >>1;
old_t = t;
}
binary += str[t];
if (s[0] == 0)
s = remove_pre_zero(s);
}
return string(binary.rbegin(), binary.rend());
}
On paper, binary arithmetic is simple, but as a beginning programmer, I'm finding it a little difficult to come up with algorithms for the addition, subtraction, multiplication and division of binary numbers.
I have two binary numbers stored as strings, assume that any leading zeroes have been dropped. How would I go about performing these operations on the two numbers?
Edit: I need to avoid converting them to an int or long.
Binary string to int:
int i = Integer.parseInt("10101011", 2);
int j = Integer.parseInt("00010", 2);
Then you can do anything you please with the two ints, eg:
i = i + j;
i = i - j;
And to get them back to a binary string:
String s = Integer.toBinaryString(i);
The algorithms, from wikipedia:
Addition:
The simplest arithmetic operation in
binary is addition. Adding two
single-digit binary numbers is
relatively simple, using a form of
carrying:
0 + 0 → 0
0 + 1 → 1
1 + 0 → 1
1 + 1 → 0, carry 1 (since 1 + 1 = 0 + 1 × 10 in binary)
Adding two "1" digits produces a digit
"0", while 1 will have to be added to
the next column.
Subtraction:
Subtraction works in much the same
way:
0 − 0 → 0
0 − 1 → 1, borrow 1
1 − 0 → 1
1 − 1 → 0
Subtracting a "1" digit from a "0"
digit produces the digit "1", while 1
will have to be subtracted from the
next column. This is known as
borrowing. The principle is the same
as for carrying. When the result of a
subtraction is less than 0, the least
possible value of a digit, the
procedure is to "borrow" the deficit
divided by the radix (that is, 10/10)
from the left, subtracting it from the
next positional value.
Multiplication:
Multiplication in binary is similar to
its decimal counterpart. Two numbers A
and B can be multiplied by partial
products: for each digit in B, the
product of that digit in A is
calculated and written on a new line,
shifted leftward so that its rightmost
digit lines up with the digit in B
that was used. The sum of all these
partial products gives the final
result.
Since there are only two digits in
binary, there are only two possible
outcomes of each partial
multiplication:
* If the digit in B is 0, the partial product is also 0
* If the digit in B is 1, the partial product is equal to A
For example, the binary numbers 1011
and 1010 are multiplied as follows:
1 0 1 1 (A)
× 1 0 1 0 (B)
---------
0 0 0 0 ← Corresponds to a zero in B
+ 1 0 1 1 ← Corresponds to a one in B
+ 0 0 0 0
+ 1 0 1 1
---------------
= 1 1 0 1 1 1 0
The following code implements binary addition without actually doing any arithmetic, binary or otherwise. The actual "addition" is done by lookupTable, and everything else is straight-up string manipulation. I wrote it with the intention of making it as instructive as possible, emphasizing the process instead of efficiency. Hope it helps.
public class BinaryArithmetic {
static String[] lookupTable = {
"0+0+0=00",
"0+0+1=01",
"0+1+0=01",
"0+1+1=10",
"1+0+0=01",
"1+0+1=10",
"1+1+0=10",
"1+1+1=11",
};
static String lookup(char b1, char b2, char c) {
String formula = String.format("%c+%c+%c=", b1, b2, c);
for (String s : lookupTable) {
if (s.startsWith(formula)) {
return s.substring(s.indexOf("=") + 1);
}
}
throw new IllegalArgumentException();
}
static String zeroPad(String s, int length) {
while (s.length() < length) {
s = "0" + s;
}
return s;
}
static String add(String s1, String s2) {
int length = Math.max(s1.length(), s2.length());
s1 = zeroPad(s1, length);
s2 = zeroPad(s2, length);
String result = "";
char carry = '0';
for (int i = length - 1; i >= 0; i--) {
String columnResult = lookup(s1.charAt(i), s2.charAt(i), carry);
result = columnResult.charAt(1) + result;
carry = columnResult.charAt(0);
}
if (carry == '1') {
result = carry + result;
}
return result;
}
public static void main(String args[]) {
System.out.println(add("11101", "1001"));
}
}
While we're at it, I might as well do multiply too.
static String multiply(String s1, String s2) {
String result = "";
String zeroSuffix = "";
for (int i = s2.length() - 1; i >= 0; i--) {
if (s2.charAt(i) == '1') {
result = add(result, s1 + zeroSuffix);
}
zeroSuffix += "0";
}
return result;
}
Working with binary arithmetic is really no different than the more familiar base 10. Let's take addition for example
(1) (1)
182 182 182 182 182
845 845 845 845 845
--- + --- + --- + --- + --- +
7 27 027 1027
So what did you do? You right-align the numbers to add, and you proceed right-to-left, adding one digit at a time, carrying over +1 to the left as necessary.
In binary, the process is exactly the same. In fact, it's even simpler because you only have 2 "digits" now, 0 and 1!
(1) (1) (1)
11101 11101 11101 11101 11101 11101 11101
1001 1001 1001 1001 1001 1001 1001
----- + ----- + ----- + ----- + ----- + ----- + ----- +
0 10 110 0110 00110 100110
The rest of the operations work similarly too: the same process that you use for base 10, works for base 2. And again, it's actually simpler because there are only 2 "digits", 0 and 1. This simplicity is why hardware likes the binary system.
Convert the binary strings to Integers and then operate on the Integers, e.g.
String add(String s1, String s2) {
int i1 = Integer.parseInt(s1);
int i2 = Integer.parseInt(s2);
return Integer.toBinaryString(i1 + i2);
}
The built-in BitSet class is very straight-forward to use for bit-level operations.