Homework: how to write own multiplication of big numbers? - java

In my project I have to deal with multiplication of big numbers ( greater then java.long ) stared in my own BigNumber class as int[]. Basically I need to implement something like this :
157 x
121 y
----
157 result1
314 + result2
157 + result3
------
18997 finalResult
But how do I implement it?
I thought about expanding result2,3 with zeros (3140, 15700) and adding them. But first I somehow need to navigate between each digit of y and multiply it by each digit of x.

Use the diagonal approach. Make an array, and multiply each digit by each other digit and fill in the numbers in each cell.
36 x 92
3 6
+-----+-----+
| 2 / | 5 / |
9 | / | / |
| / 7 | / 4 |
+-----+-----+
| 0 / | 1 / |
2 | / | / |
| / 6 | / 2 |
+-----+-----+
Add the numbers on each diagonal. Move from the least-significant digit (at the lower right) to the most (upper left).
2 2 (least-significant)
(6 + 1 + 4) = 11 (make this 1, and carry the 1 to the next digit) 1
(5 + 7 + 0 + 1(carried)) = 13 (make this 3, and carry the 1) 3
2 + 1(carried) = 3 3 (most-significant)
The answer's 3312.
Make a two-dimensional array of your digits. Fill the array with the multiplications of the single digits together.
Write some logic to scrape the diagonals as I did above.
This should work for arbitrarily large numbers (as long as you still have memory left).

Here's the code I had written. Basically same as manual multiplication. Pass the two big numbers as strings to this function, the result is returned as a string.
public String multiply(String num1, String num2){
int product, carry=0, sum=0;
String result = new String("");
String partial = new String("");
ArrayList<String> partialList = new ArrayList<String>();
/* computing partial products using this loop. */
for(int j=num2.length()-1 ; j>=0 ; j--) {
for(int i=num1.length()-1 ; i>=0 ; i--) {
product = Integer.parseInt((new Character(num1.charAt(i))).toString()) *
Integer.parseInt((new Character(num2.charAt(j))).toString()) + carry;
carry = product/10;
partial = Integer.toString(product%10) + partial;
}
if(carry != 0)
partial = Integer.toString(carry) + partial;
partialList.add(partial);
partial = "";
carry = 0;
}
/* appending zeroes incrementally */
for(int i=0 ; i<partialList.size() ; i++)
partialList.set(i, partialList.get(i) + (Long.toString( (long)java.lang.Math.pow(10.0,(double)i))).substring(1) );
/* getting the size of the largest partial product(last) */
int largestPartial = partialList.get(partialList.size()-1).length();
/* prefixing zeroes */
int zeroes;
for(int i=0 ; i<partialList.size() ; i++) {
zeroes = largestPartial - partialList.get(i).length();
if(zeroes >= 1)
partialList.set(i, (Long.toString( (long)java.lang.Math.pow(10.0,(double)zeroes))).substring(1) + partialList.get(i) );
}
/* to compute the result */
carry = 0;
for(int i=largestPartial-1 ; i>=0 ; i--) {
sum = 0;
for(int j=0 ; j<partialList.size() ; j++)
sum = sum + Integer.parseInt(new Character(partialList.get(j).charAt(i)).toString());
sum = sum + carry;
carry = sum/10;
result = Integer.toString(sum%10) + result;
}
if(carry != 0)
result = Integer.toString(carry) + result;
return result;
}

I would avoid the headaches of writing your own and just use the java.math.BigInteger class. It should have everything you need.

Separating out the carrying and the digit multiplication:
def carries(digitlist):
digitlist.reverse()
for idx,digit in enumerate(digitlist):
if digit>9:
newdigit = digit%10
carry = (digit-newdigit)/10
digitlist[idx] = newdigit
if idx+1 > len(digitlist)-1:
digitlist.append(carry)
else:
digitlist[idx+1] += carry
digitlist.reverse()
return True
def multiply(first,second):
digits = [0 for place in range(len(first)+len(second))]
for fid,fdig in enumerate(reversed(first)):
for sid,sdig in enumerate(reversed(second)):
offset = fid+sid
mult = fdig*sdig
digits[offset] += mult
digits.reverse()
carries(digits)
return digits
def prettify(digitlist):
return ''.join(list(`i` for i in digitlist))
Then we can call it:
a = [1,2,3,4,7,6,2]
b = [9,8,7,9]
mult = multiply(a,b)
print prettify(a)+"*"+prettify(b)
print "calc:",prettify(mult)
print "real:",int(prettify(a))*int(prettify(b))
Yields:
1234762*9879
calc: 12198213798
real: 12198213798
Of course the 10s in the carries function and the implicit decimal representation in prettify are the only thing requiring this to be base 10. Adding an argument could make this base n, so you could switch to base 1000 in order to reduce the numbers of blocks and speed up the calculation.

I have implemented this in C++. refer to this for logic...
#include <iostream>
#include <deque>
using namespace std;
void print_num(deque<int> &num) {
for(int i=0;i < num.size();i++) {
cout<<num[i];
}
cout<<endl;
}
deque<int> sum(deque<int> &oppA, deque<int> &oppB) {
if (oppA.size() == 0) return oppB;
if (oppB.size() == 0) return oppA;
deque<int> result;
unsigned int carry = 0;
deque<int>::reverse_iterator r_oppA = oppA.rbegin();
deque<int>::reverse_iterator r_oppB = oppB.rbegin();
while ((r_oppA != oppA.rend()) && (r_oppB != oppB.rend())) {
int tmp = *r_oppA + *r_oppB + carry;
result.push_front(tmp % 10);
carry = tmp / 10;
r_oppB++;
r_oppA++;
}
while (r_oppA != oppA.rend()) {
int tmp = *r_oppA + carry;
result.push_front(tmp % 10);
carry = tmp / 10;
r_oppA++;
}
while (r_oppB != oppB.rend()) {
int tmp = *r_oppB + carry;
result.push_front(tmp % 10);
carry = tmp / 10;
r_oppB++;
}
return result;
}
deque<int> multiply(deque<int>& multiplicand, deque<int>& multiplier) {
unsigned int carry = 0;
deque<int> result;
int deci_cnt = 0;
deque<int>::reverse_iterator r_multiplier = multiplier.rbegin();
deque<int> tmp_result;
while (r_multiplier != multiplier.rend()) {
for (int i=0; i<deci_cnt ;i++) {
tmp_result.push_front(0);
}
deque<int>::reverse_iterator r_multiplicand = multiplicand.rbegin();
while (r_multiplicand != multiplicand.rend()) {
int tmp = (*r_multiplicand) * (*r_multiplier) + carry;
tmp_result.push_front(tmp % 10);
carry = tmp / 10;
r_multiplicand++;
}
if (carry != 0) {
tmp_result.push_front(carry);
carry = 0;
}
result = sum(result, tmp_result);
deci_cnt++;
tmp_result.clear();
r_multiplier++;
}
return result;
}
deque<int> int_to_deque(unsigned long num) {
deque<int> result;
if (num == 0) {
result.push_front(0);
}
while (num > 0) {
result.push_front(num % 10);
num = num / 10;
}
return result;
}
int main() {
deque<int> num1 = int_to_deque(18446744073709551615ULL);
deque<int> num2 = int_to_deque(18446744073709551615ULL);
deque<int> result = multiply(num1, num2);
print_num(result);
return 0;
}
Output: 340282366920928463426481119284349108225

You're going to have to treat each int in the array as a single "digit". Instead of using base 10 where each digit goes from 0 to 9, you'll have to use base 2^32 = 4294967296, where every digit goes from 0 to 4294967295.
I would first implement addition, as your algorithm for multiplication might use addition as an auxiliary.

As this is for homework I'll give a few hints.
You could approach it the same way you show your example, using strings to hold numbers of any length and implementing:
add one number to another
multiply as your example by appending zeroes and calling the addition method per step (so for multiply with 20, append the "0" and addd that number twice
The addition method you can build by retrieving the char[] from the strings, allocate a result char[] that is 1 longer than the longest and add like you would do on paper from the end back to the start of both arrays.
The end result will not be the best performing solution, but it it easy to show it is correct and will handle any length numbers (as long they will fit a Java string.)
Update
Ok, if you solved adding two numbers, you could:
implement multiplication by 10
implement multiplication by repeated addition like in your example
or:
implement multiplication by 2 (left shift)
implement a binary multiplication via the same concept, only this time x 2 and add once
to illustrate the latter,
13
5 x
----
13 x 1
26 x 0
52 x 1
---- +
65
note that the 1 0 1 are the bits in the number (5) you multiply with and 26 = 13 x 2, 52 = 26 x 2. Your get the idea :-)

did it my own way :
int bigger = t1.length;
int smaller = t2.length;
int resultLength = bigger + smaller;
int []resultTemp = new int[resultLength];
int []result = new int[bigger + smaller];
int []temporary = new int[resultLength+1];
int z = resultLength-1;
int zet = z;
int step = 0;
int carry = 0;
int modulo = 0;
for(int i=smaller-1; i>=0; i--){
for(int k = bigger-1; k>= -1; k--){
if(k == -1 && carry != 0 ){
resultTemp[z] = carry;
carry = 0;
break;
}
else if(k == -1 && carry == 0){
resultTemp[z] = 0;
break;
}
resultTemp[z] = carry + t1[k]*t2[i];
carry = 0;
if( resultTemp[z] > 9 ){
modulo = resultTemp[z] % 10;
carry = resultTemp[z]/10;
resultTemp[z] = modulo;
}
else{
resultTemp[z] = resultTemp[z];
}
z--;
}
temporary = add(resultTemp, result);
result = copyArray(temporary);
resultTemp = clear(resultTemp);
z = zet;
step++;
z = z - step;
}
then I check the sign.

Since this is homework... Are you sure using an int array is your best shot?
I tried to implement something similar a year ago for performance in a research
project, and we ended up going with concatenated primitives..
Using this you can take advantage of what's already there, and "only" have to worry about overflows near the ends.. This might prove to be fairly simple when you implement your multiplication with <<'s (bit shift lefts) and additions..
Now if you want a real challenge try to implement a modulo... ;)

You can check the below solution which teaches us both multiplication and addition of bigger numbers. Please comment if it can be improved.
public static void main(String args[]) {
String s1 = "123666666666666666666666666666666666666666666666669999999999999999999999999666666666666666666666666666666666666666666666666666666666666666666";
String s2 = "45688888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888";
System.out.println(multiply(s1, s2));
}
private static String multiply(String s1, String s2) {
int[] firstArray = convert(s1);
int[] secondArray = convert(s2);
//System.out.println(Arrays.toString(firstArray));
//System.out.println(Arrays.toString(secondArray));
// pass the arrays and get the array which is holding the individual
// rows while we multiply using pen and paper
String[] result = doMultiply(firstArray, secondArray);
//System.out.println(Arrays.toString(result));
// Now we are almost done lets format them as we like
result = format(result);
//System.out.println(Arrays.toString(result));
//Add elements now and we are done
String sum="0";
for(String s:result){
sum=add(sum,s);
}
return sum;
}
private static String[] doMultiply(int[] firstArray, int[] secondArray) {
String[] temp = new String[secondArray.length];
for (int i = secondArray.length - 1; i >= 0; i--) {
int result = 0;
int carry = 0;
int rem = 0;
temp[secondArray.length - 1 - i] = "";
for (int j = firstArray.length - 1; j >= 0; j--) {
result = (secondArray[i] * firstArray[j]) + carry;
carry = result / 10;
rem = result % 10;
temp[secondArray.length - 1 - i] = rem
+ temp[secondArray.length - 1 - i];
}
// if the last carry remains in the last digit
if (carry > 0)
temp[secondArray.length - 1 - i] = carry
+ temp[secondArray.length - 1 - i];
}
return temp;
}
public static int[] convert(String str) {
int[] arr = new int[str.length()];
for (int i = 0; i < str.length(); i++) {
arr[i] = Character.digit(str.charAt(i), 10);
}
return arr;
}
private static String[] format(String[] result) {
for (int i = 0; i < result.length; i++) {
int j = 0;
while (j < i) {
result[i] += "0";
j++;
}
}
return result;
}
public static String add(String num1, String num2) {
//System.out.println("First Number :" + num1);
//System.out.println("Second Number :" + num2);
int max = num1.length() > num2.length() ? num1.length() : num2.length();
int[] numArr1 = new int[max];
int[] numArr2 = new int[max];
for (int i = 0; i < num1.length(); i++) {
numArr1[i] = Integer.parseInt(""
+ num1.charAt(num1.length() - 1 - i));
}
for (int i = 0; i < num2.length(); i++) {
numArr2[i] = Integer.parseInt(""
+ num2.charAt(num2.length() - 1 - i));
}
int carry = 0;
int[] sumArr = new int[max + 1];
for (int k = 0; k < max; k++) {
int tempsum = numArr1[k] + numArr2[k] + carry;
sumArr[k] = tempsum % 10;
carry = 0;
if (tempsum >= 10) {
carry = 1;
}
}
sumArr[max] = carry;
/* System.out.println("Sum :"
+ new StringBuffer(Arrays.toString(sumArr)).reverse()
.toString().replaceAll(",", "").replace("[", "")
.replace("]", "").replace(" ", ""));*/
return new StringBuffer(Arrays.toString(sumArr)).reverse().toString()
.replaceAll(",", "").replace("[", "").replace("]", "")
.replace(" ", "");
}

I think this will help you
import java.util.ArrayList;
import java.util.List;
public class Multiply {
static int len;
public static void main(String[] args) {
System.out.println(multiply("123456789012345678901","123456789012345678901");
}
private static ArrayList<Integer> addTheList(List<ArrayList<Integer>> myList) {
ArrayList<Integer> result=new ArrayList<>();
for(int i=0;i<len;i++)
{
result.add(0);
}
int index=0;
for(int i=0;i<myList.size();i++)
{
ArrayList<Integer> a=new ArrayList<>(myList.get(index));
ArrayList<Integer> b=new ArrayList<>(myList.get(index+1));
for (int j = 0; j < a.size()||j < b.size(); i++) {
result.add(a.get(i) + b.get(i));
}
}
return result;
}
private static ArrayList<Integer> multiply(ArrayList<Integer> list1, Integer integer) {
ArrayList<Integer> result=new ArrayList<>();
int prvs=0;
for(int i=0;i<list1.size();i++)
{
int sum=(list1.get(i)*integer)+prvs;
System.out.println(sum);
int r=sum/10;
int m=sum%10;
if(!(r>0))
{
result.add(sum);
}
else
{
result.add(m);
prvs=r;
}
if(!(i==(list1.size()-1)))
{
prvs=0;
}
}
if(!(prvs==0))
{
result.add(prvs);
}
return result;
}
private static ArrayList<Integer> changeToNumber(String str1) {
ArrayList<Integer> list1=new ArrayList<>();
for(int i=0;i<str1.length();i++)
{
list1.add(Character.getNumericValue(str1.charAt(i)));
}
return list1;
}
public static String multiply(String num1, String num2) {
String n1 = new StringBuilder(num1).reverse().toString();
String n2 = new StringBuilder(num2).reverse().toString();
int[] d = new int[num1.length()+num2.length()];
//multiply each digit and sum at the corresponding positions
for(int i=0; i<n1.length(); i++){
for(int j=0; j<n2.length(); j++){
d[i+j] += (n1.charAt(i)-'0') * (n2.charAt(j)-'0');
}
}
StringBuilder sb = new StringBuilder();
//calculate each digit
for(int i=0; i<d.length; i++){
int mod = d[i]%10;
int carry = d[i]/10;
if(i+1<d.length){
d[i+1] += carry;
}
sb.insert(0, mod);
}
//remove front 0's
while(sb.charAt(0) == '0' && sb.length()> 1){
sb.deleteCharAt(0);
}
return sb.toString();
}
}

Related

How to determine how many times a character is repeated in a string?

I am having some trouble with writing a method that when prompted with a number returns how many times each value is repeated. For example, if the number 7846597 is entered the method would return:
0 - 0
1 - 0
2 - 0
3 - 0
4 - 1
5 - 1
6 - 1
7 - 2
8 - 1
9 - 1
I know this would be most easily done with a loop, but I am not sure how to write the actual code. I also know that I need to convert the number value I get as an input into a string so I can use char methods.
This is my attempt:
public double countOccurences(int num)
{
String str = num + "";
int goneThrough = 0;
int count0 = 0;
int count1 = 0;
int count2 = 0;
int count3 = 0;
int count4 = 0;
int count5 = 0;
int count6 = 0;
int count7 = 0;
int count8 = 0;
int count9 = 0;
while(goneThrough <= str.length())
{
int value = 0;
if(value >= 10){
value = value * 0;
}
if(str.charAt(0) == 0)
count0++;
if(str.charAt(0) = 1)
count1++;
}
return count0;
return count1;
return count2;
return count3;
return count4;
return count5;
return count6;
return count7;
return count8;
return count9;
}
countOccurences(int num) should return the number of occurrences of each digit as int[10].
static int[] countOccurences(int num) {
int[] result = new int[10];
for ( ; num > 0; num /= 10)
++result[num % 10];
return result;
}
public static void main(String[] args) {
int input = 7846597;
int[] output = countOccurences(input);
for (int i = 0; i < 10; ++i)
System.out.println(i + " - " + output[i]);
}
output:
0 - 0
1 - 0
2 - 0
3 - 0
4 - 1
5 - 1
6 - 1
7 - 2
8 - 1
9 - 1
This is my code where I used HashTable and stored number as string and count as value. This is optimized code where time complexity is O(n).
// code
import java.util.*;
class Main {
public static void main(String args[]) {
String number = "7846597";
Hashtable<String, Integer> result = new Hashtable<String, Integer>();
for(int i=0; i<number.length(); i++){
String current = "" + number.charAt(i);
if(result.contains(current)) {
int val = result.get(current);
result.put(current, ++val);
} else {
result.put(current, 1);
}
}
System.out.print(result);
}
}
Using int array of size 10 and increment value at index that maps to digit of 0-9.
public static void digitFrequencies(int number) {
int[] arr = new int[10];
for (char ch : String.valueOf(number).toCharArray()) {
int digit = Character.digit(ch, 10);
arr[digit] = arr[digit] + 1;
}
for (int i = 0; i < arr.length; i++) {
System.out.print(i + " - " + arr[i] + " ");
}
}

Java - number in expanded form

I have given number and want it to return as a String in expanded form. For example
expandedForm(12); # Should return "10 + 2"
expandedForm(42); # Should return "40 + 2"
expandedForm(70304); # Should return "70000 + 300 + 4"
My function works for first and second case, but with 70304 it gives this:
70 + 00 + 300 + 000 + 4
Here's my code
import java.util.Arrays;
public static String expandedForm(int num)
{
String[] str = Integer.toString(num).split("");
String result = "";
for(int i = 0; i < str.length-1; i++) {
if(Integer.valueOf(str[i]) > 0) {
for(int j = i; j < str.length-1; j++) {
str[j] += '0';
}
}
}
result = Arrays.toString(str);
result = result.substring(1, result.length()-1).replace(",", " +");
System.out.println(result);
return result;
}
I think there's a problem with the second loop, but can't figure out why.
You should be adding '0's to str[i], not str[j]:
for(int i = 0; i < str.length-1; i++) {
if(Integer.valueOf(str[i]) > 0) {
for(int j = i; j < str.length-1; j++) {
str[i] += '0';
}
}
}
This will result in:
70000 + 0 + 300 + 0 + 4
You still have to get rid of the 0 digits.
One possible way to get rid of them:
result = result.substring(1, result.length()-1).replace(", 0","").replace(",", " +");
Now the output is
70000 + 300 + 4
Pseudocode uses integer arithmetics to extract decimal digits one-by-one (from the right one):
mul = 1 //will contain power of 10
while (num > 0):
dig = num % 10 //integer modulo retrieves the last digit
if (dig > 0): //filter out zero summands
add (dig * mul) to output //like 3 * 100 = 300
num = num / 10 //integer division removes the last decimal digit 6519 => 651
mul = mul * 10 //updates power of 10 for the next digit
You could do the same with pure math, using modulo % and integer division /, e.g. using Stream API:
int n = 70304;
String res = IntStream
.iterate(1, k -> n / k > 0, k -> k * 10) // divisors
.map(k -> (n % (k*10) / k ) * k) // get 1s, 10s, 100s, etc.
.filter(x -> x > 0) // throw out zeros
.mapToObj(Integer::toString) // convert to string
.collect(Collectors.joining(" + ")); // join with '+'
System.out.println(res); // 4 + 300 + 70000
There are many variations possible. If the usage of a list is allowed:
public static String expandedForm(int num){
String[] str = Integer.toString(num).split("");
String result;
List<String> l = new ArrayList<String>();
for(int i = 0; i < str.length; i++){
if(Integer.valueOf(str[i]) > 0){
String s = str[i];
for(int j = i; j < str.length - 1; j++){
s += '0';
}
l.add(s);
}
}
result = l.toString();
result = result.substring(1, result.length() - 1).replace(",", " +");
System.out.println(result);
return result;
}
One could also work directly on result:
public static String expandedForm2(int num){
String[] str = Integer.toString(num).split("");
String result = "";
for(int i = 0; i < str.length; i++){
if(Integer.valueOf(str[i]) > 0){
result += str[i];
for(int j = i; j < str.length - 1; j++){
result += '0';
}
result += " + ";
}
}
result = result.substring(0, result.length() - 3);
System.out.println(result);
return result;
}
This is also possible to do recursively. Here an example implementation:
String g(int n, int depth){ // Recursive method with 2 int parameters & String return-type
int remainder = n % depth; // The current recursive remainder
if(depth < n){ // If we aren't done with the number yet:
int nextDepth = depth * 10; // Go to the next depth (of the power of 10)
int nextN = n - remainder; // Remove the remainder from the input `n`
// Do a recursive call with these next `n` and `depth`
String resultRecursiveCall = g(nextN, nextDepth);
if(remainder != 0){ // If the remainder was not 0:
// Append a " + " and this remainder to the result
resultRecursiveCall += " + " + remainder;
}
return resultRecursiveCall; // And return the result
} else{ // Else:
return Integer.toString(n); // Simply return input `n` as result
}
}
String f(int n){ // Second method so we can accept just integer `n`
return g(n, 1); // Which will call the recursive call with parameters `n` and 1
}
The second method is so we can call the method with just a single input n. For example:
String result = f(70304);
Which will result in the String 70000 + 300 + 4.
Try it online.
To explain a bit more in depth of what this recursive method does, let's just do a step-by-step for the input 70304:
In the first recursive iteration: n=70304, depth=1, remainder=70304%1 = 0.
Since depth < n is truthy, it will do a recursive call with 70304-0 and 1*10
And since remainder is 0, it will append nothing more to the result
In the second recursive iteration: n=70304, depth=10, remainder=70304%10 = 4.
Since depth < n is still truthy, it will do a recursive call with 70304-4 and 10*10
And since remainder is 4, it will append a " + " and this 4 to the result
In the third recursive iteration: n=70300, depth=100, remainder=70300%100 = 0.
Since depth < n is still truthy, it will do a recursive call with 70300-0 and 100*10
And since remainder is 0, it will append nothing more to the result
In the fourth recursive iteration: n=70300, depth=1000, remainder=70300%1000 = 300.
Since depth < n is still truthy, it will do a recursive call with 70300-300 and 1000*10
And since remainder is 300, it will append a " + " and this 300 to the result
In the fifth recursive iteration: n=70000, depth=10000, remainder=70000%10000 = 0.
Since depth < n is still truthy, it will do a recursive call with 70000-0 and 10000*10
And since remainder is 0, it will append nothing more to the result
In the sixth recursive iteration: n=70000, depth=100000, remainder=70000%100000 = 70000.
Since now depth < n is falsey, it won't do any more recursive calls, but instead return the current n (which is 70000).
And since these were all recursive calls, we should actually look at it backwards for the result, so it will result in 70000 + 300 + 4.
So in general:
The depth < n if-check is to see when we are done with the recursive calls.
The g(n-remainder, depth*10) will remove the digits we've already output in a previous recursive iteration, and goes to the next 10k power in the next recursive iteration
The remainder != 0 if-check determines if the number we want to append was not a 0
public class Kata
{
public static String expandedForm(int num)
{
String outs = "";
for (int i = 10; i < num; i *= 10) {
int rem = num % i;
outs = (rem > 0) ? " + " + rem + outs : outs;
num -= rem;
}
outs = num + outs;
return outs;
}
}
package backup;
import java.util.Arrays;
public class FileOutput {
public static void main(String[] args){
String expForm = expandedForm(70304);
//System.out.println(expForm);
}
public static String expandedForm(int num)
{
String[] str = Integer.toString(num).split("");
String result = "";
for(int i = 0; i < str.length-1; i++) {
if(Integer.valueOf(str[i]) > 0) {
for(int j = i; j < str.length-1; j++) {
str[i] += '0';
}
}
}
result = Arrays.toString(str);
result = result.substring(1, result.length()-1).replace(",", " +");
System.out.println(result);
return result;
}
}
Output : 70000 + 0 + 300 + 0 + 4
Solution in most inner loop you need to add '0' to str[i] : str[i] += '0';
Then you need to replace "+ 0" from the resulted output.
for(int i = 0; i < str.length; i++) {
if(Integer.valueOf(str[i]) > 0) {
for(int j = 0; j < str.length - i - 1; j++) {
str[i] += '0';
}
}
}
I think the challenge of this problem is omitting 0(zero) and extra +(plus) while iterating throughout the number. String concat function can be used with condition as bellow:
public static String expandedForm(int num) {
String st = String.valueOf(num);
String finalResult = "";
for (int i = 0; i < st.length(); i++) {
String s = String.valueOf(st.charAt(i));
if (Integer.valueOf(s) > 0) {
for (int j = i; j < st.length() - 1; j++) {
s = s.concat("0");
}
if (i == st.length() - 1) {
finalResult = finalResult.concat(s);
} else {
finalResult = finalResult.concat(s + " + ");
}
}
}
return finalResult;
}
public static String expandedForm(int num)
{
String[] str = Integer.toString(num).split("");
String result = "";
String st="";
for(int i = 0; i < str.length-1; i++) {
if(Integer.valueOf(str[i]) > 0) {
for(int j = i; j < str.length-1; j++) {
str[i] += '0';
}
}
}
for(String s:str) {
st += s+" ";
}
result=st;
result = result.substring(0, result.length()-1).replace(" 0","").replace(" ", " + ");
System.out.println(result);
return result;
}
public static String expandedForm(int num)
{
int numberOfDigits =(int) Math.floor(Math.log10(num)+1);
String result="";
while(numberOfDigits-->0){
int divisor = (int)Math.pow(10,numberOfDigits);
int quotient = num/divisor;
num%=divisor;
int value = quotient * divisor;
if(value!=0)
result+=value+(numberOfDigits != 0 ?"+":"");
}
return result;
}
Try with this.
Find number of digits and iterate for every single digit.
Make a divisor of 10 power (number of digits -1) and divide the number to get quotient.
Take reminder for next iteration.
Multiply quotient and divisor and store in result if it value is not zero.
Simple Javascript Expanded Form of a number
Asked in interviews for beginners/Juniors
function expandedForm(n){
let temp = n;
let count=0;
while(temp>0){
console.log(((temp%10)*(10**count)));
count++;
temp = Math.floor(temp/10);
}
}
output will be like this:-
7
80
400
5000
10000

Java binary multiplication using integer arrays not working

I'm making a program that accepts two decimal numbers and convert them into binary numbers, which are stored in integer arrays. Then I need to do multiplication using the two integer arrays. The result should also be a binary integer array (I need to validate that using a for loop). Then I convert them result to decimal number.
So far, I have the following code. My logic to convert the decimal number to binary works fine and vice verse. However, the binary result is always somehow smaller than the expected result. I have spent a lot of time on this, could you help me check what is wrong?
public class BinaryMultiplication {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int num1 = scanner.nextInt();
int num2 = scanner.nextInt();
int[] binaryNum1 = toBinary(num1);
int[] binaryNum2 = toBinary(num2);
System.out.println("Expected result: " + num1 * num2);
System.out.println("Decimal number 1: " + toDecimal(binaryNum1));
System.out.println("Decimal number 2: " + toDecimal(binaryNum2));
int[] resultBinaries = new int[100];
for (int i = 0; i < resultBinaries.length; ++i) {
resultBinaries[i] = 0;
}
for (int i = 0; binaryNum1[i] != -1; ++i) {
for (int j = 0; binaryNum2[j] != -1; ++j) {
resultBinaries[i + j] += binaryNum1[i] * binaryNum2[j] % 2;
resultBinaries[i + j] %= 2;
}
}
resultBinaries[99] = -1;
for (int i = 0; resultBinaries[i] != -1; ++i) {
if (resultBinaries[i] > 1) {
System.out.println("The result is not a binary!!");
}
}
System.out.println("Actual decimal result: " + toDecimal(resultBinaries));
}
public static int toDecimal(int[] binaryNum) {
int result = 0;
int factor = 1;
for (int i = 0; binaryNum[i] != -1; ++i) {
result += binaryNum[i] * factor;
factor *= 2;
}
return result;
}
public static int[] toBinary(int num) {
int[] binaries = new int[100];
int index = 0;
while (num > 0) {
binaries[index++] = num % 2;
num /= 2;
}
binaries[index] = -1;
return binaries;
}
}
A sample input & output: ( the binary validation loop works fine)
45 67
Expected result: 3015
Decimal number 1: 45
Decimal number 2: 67
Actual decimal result: 2871
for (int i = 0; binaryNum1[i] != -1; ++i) {
for (int j = 0; binaryNum2[j] != -1; ++j) {
resultBinaries[i + j] += binaryNum1[i] * binaryNum2[j] % 2;
resultBinaries[i + j] %= 2;
}
}
What happens when resultBinaries[i + j] increases to 2? It's reduced to 0 and then resultBinaries[i + j + 1] should be increased with 1, but this isn't happening in the code as far as I can see.

Converting ISBN10 to ISBN13

I have tried to convert ISBN10 codes to ISBN13 numbers with Java. From . On isbn-13.info I found the way to convert them.
Example: 0-123456-47-9
Begin with prefix of “978”
Use the first nine numeric characters of the ISBN (include dashes) 978-0-123456-47-
Calculate the EAN check digit using the “Mod 10 Algorithm” 978-0-123456-47-2
Using that I have created a Java program to do the conversion.
public class ISBNConverter {
public static void main(String[] args) {
String isbn10 = "9513218589";
String isbn13 = "";
int sum = 0;
int checkNumber = 0;
int multiplier = 2;
String code = "978" + isbn10.substring(0, isbn10.length() - 1);
for(int i = code.length() - 1; i >= 0; i--) {
int num = Character.getNumericValue(code.charAt(i));
isbn13 += String.valueOf(num * multiplier);
multiplier = (multiplier == 2) ? 1 : 2;
}
for(int i = 0; i < isbn13.length(); i++) {
sum += Character.getNumericValue(isbn13.charAt(i));
}
while(sum % 10 != 0) {
sum++;
checkNumber++;
}
System.out.println(checkNumber);
}
}
For the example ISBN10 code 9513218589 (978951321858 ISBN13 without the check number) it returns 5 as the check number. If I calculate it using the converter on ISBN's official site I get 4 as the check sum. For some reason, the sum of the numbers in the new code is one less than it should be.
I have being fighting with this for a long time and I believe I have began blind: I just can't find what I'm doing wrong. Could someone help with this?
Here you go
public static String ISBN10toISBN13( String ISBN10 ) {
String ISBN13 = ISBN10;
ISBN13 = "978" + ISBN13.substring(0,9);
//if (LOG_D) Log.d(TAG, "ISBN13 without sum" + ISBN13);
int d;
int sum = 0;
for (int i = 0; i < ISBN13.length(); i++) {
d = ((i % 2 == 0) ? 1 : 3);
sum += ((((int) ISBN13.charAt(i)) - 48) * d);
//if (LOG_D) Log.d(TAG, "adding " + ISBN13.charAt(i) + "x" + d + "=" + ((((int) ISBN13.charAt(i)) - 48) * d));
}
sum = 10 - (sum % 10);
ISBN13 += sum;
return ISBN13;
}
pardon the log lines in between, I am copy pasting it from an android project i am working on
In the
for(int i = 0; i < isbn13.length(); i++) {
sum += Character.getNumericValue(isbn13.charAt(i));
}
You're adding up all the digits from the ISBN, including the doubled ones.
Example:
digit 7 -> double = 14
You're adding 14 to the sum. Is should be
digit 7 -> double = 14 -> bigger than 9? yes, so 1+4 = 5
and you should add 5.
You could use the Apache commons-validator library to do this for you. See the ISBNValidator::convertToISBN13 method.
import org.apache.commons.validator.routines.ISBNValidator;
String isbn13 = ISBNValidator.getInstance().convertToISBN13("9513218589");
It's really easy.
Please look at my JavaScript example to understand the logic of conversion:
function isbn13to10(isbn13) {
var digits = [];
var sum = 0; var chk_tmp, chk_digit;
digits = (isbn13 + "").substr(3,9).split("") ;
for(var i = 0; i < 9; i++) {
sum += digits[i] * (10 - i);
}
chk_tmp = 11 - (sum % 11);
if (chk_tmp == 10) {
chk_digit = 'x';
} else if (chk_tmp == 11) {
chk_digit = 0;
} else {
chk_digit = chk_tmp;
}
digits.push(chk_digit);
return digits.join("");
}
function isbn10to13(isbn10){
var sum = (isbn10 + "").charAt(9);
var mltp = 0;
var total = 0;
if (sum == "X") { sum = 10; }
isbn10 = "978"+isbn10.substring(0,9);
for (i=0; i<12; i++) {
mltp = (i % 2) == 0 ? 1 : 3;
total = total+(isbn10.charAt(i)*mltp);
}
sum = (10 - (total % 10)) % 10;
return isbn10+sum;
}

How to convert a Binary String to a base 10 integer in Java

I have an array of Strings that represent Binary numbers (without leading zeroes) that I want to convert to their corresponding base 10 numbers. Consider:
binary 1011 becomes integer 11
binary 1001 becomes integer 9
binary 11 becomes integer 3 etc.
What's the best way to proceed? I've been exploring java.lang.number.* without finding a direct conversion method. Integer.parseInt(b) yields an integer EQUAL to the String...e.g., 1001 becomes 1,001 instead of 9...and does not seem to include a parameter for an output base. toBinaryString does the conversion the wrong direction. I suspect I'll need to do a multistep conversion, but can't seem to find the right combination of methods or subclasses. I'm also not sure the extent to which leading zeros or lack thereof will be an issue. Anyone have any good directions to point me?
You need to specify the radix. There's an overload of Integer#parseInt() which allows you to.
int foo = Integer.parseInt("1001", 2);
This might work:
public 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;
}
int foo = Integer.parseInt("1001", 2);
works just fine if you are dealing with positive numbers but if you need to deal with signed numbers you may need to sign extend your string then convert to an Int
public class bit_fun {
public static void main(String[] args) {
int x= (int)Long.parseLong("FFFFFFFF", 16);
System.out.println("x =" +x);
System.out.println(signExtend("1"));
x= (int)Long.parseLong(signExtend("1"), 2);
System.out.println("x =" +x);
System.out.println(signExtend("0"));
x= (int)Long.parseLong(signExtend("0"), 2);
System.out.println("x =" +x);
System.out.println(signExtend("1000"));
x= (int)Long.parseLong(signExtend("1000"), 2);
System.out.println("x =" +x);
System.out.println(signExtend("01000"));
x= (int)Long.parseLong(signExtend("01000"), 2);
System.out.println("x =" +x);
}
private static String signExtend(String str){
//TODO add bounds checking
int n=32-str.length();
char[] sign_ext = new char[n];
Arrays.fill(sign_ext, str.charAt(0));
return new String(sign_ext)+str;
}
}
output:
x =-1
11111111111111111111111111111111
x =-1
00000000000000000000000000000000
x =0
11111111111111111111111111111000
x =-8
00000000000000000000000000001000
x =8
I hope that helps!
static int binaryToInt (String binary){
char []cA = binary.toCharArray();
int result = 0;
for (int i = cA.length-1;i>=0;i--){
//111 , length = 3, i = 2, 2^(3-3) + 2^(3-2)
// 0 1
if(cA[i]=='1') result+=Math.pow(2, cA.length-i-1);
}
return result;
}
public Integer binaryToInteger(String binary){
char[] numbers = binary.toCharArray();
Integer result = 0;
int count = 0;
for(int i=numbers.length-1;i>=0;i--){
if(numbers[i]=='1')result+=(int)Math.pow(2, count);
count++;
}
return result;
}
I guess I'm even more bored! Modified Hassan's answer to function correctly.
For me I got NumberFormatException when trying to deal with the negative numbers. I used the following for the negative and positive numbers.
System.out.println(Integer.parseUnsignedInt("11111111111111111111111111110111", 2));
Output : -9
Using bitshift is more elegant and faster than Math.pow. Simply bitshift the digits (0 or 1) into position with val <<= 1
// parse an unsigned binary string, valid up to 31 bits
static int binaryToBase10(String binaryString) {
int val = 0;
for (char c : binaryString.toCharArray()) {
val <<= 1;
val += c-'0';
}
return val;
}
Example use
int val = binaryToBase10("1011");
System.out.println(val);
prints 11
Fixed version of java's Integer.parseInt(text) to work with negative numbers:
public static int parseInt(String binary) {
if (binary.length() < Integer.SIZE) return Integer.parseInt(binary, 2);
int result = 0;
byte[] bytes = binary.getBytes();
for (int i = 0; i < bytes.length; i++) {
if (bytes[i] == 49) {
result = result | (1 << (bytes.length - 1 - i));
}
}
return result;
}
I love loops! Yay!
String myString = "1001001"; //73
While loop with accumulator, left to right (l doesn't change):
int n = 0,
j = -1,
l = myString.length();
while (++j < l) n = (n << 1) + (myString.charAt(j) == '0' ? 0 : 1);
return n;
Right to left with 2 loop vars, inspired by Convert boolean to int in Java (absolutely horrible):
int n = 0,
j = myString.length,
i = 1;
while (j-- != 0) n -= (i = i << 1) * new Boolean(myString.charAt(j) == '0').compareTo(true);
return n >> 1;
A somewhat more reasonable implementation:
int n = 0,
j = myString.length(),
i = 1;
while (j-- != 0) n += (i = i << 1) * (myString.charAt(j) == '0' ? 0 : 1);
return n >> 1;
A readable version :p
int n = 0;
for (int j = 0; j < myString.length(); j++) {
n *= 2;
n += myString.charAt(j) == '0' ? 0 : 1;
}
return n;
Now you want to do from binary string to Decimal but Afterword, You might be needed contrary method. It's down below.
public static String decimalToBinaryString(int value) {
String str = "";
while(value > 0) {
if(value % 2 == 1) {
str = "1"+str;
} else {
str = "0"+str;
}
value /= 2;
}
return str;
}
You can also use this method to convert the binary to decimal integer if you are given with string.(Java Language)
static int binaryTodecimal(String s){
int i= -1;
char[] str = s.toCharArray();
int dec_val= 0;
for (int j=str.length-1; j>=0 ;j-- ){
int k= Integer.valueOf(str[j]) - '0';
i = i+1;
dec_val += k*(Math.pow(2, i));
}
System.out.println(dec_val);
}
If you're worried about performance, Integer.parseInt() and Math.pow() are too expensive. You can use bit manipulation to do the same thing twice as fast (based on my experience):
final int num = 87;
String biStr = Integer.toBinaryString(num);
System.out.println(" Input Number: " + num + " toBinary "+ biStr);
int dec = binaryStringToDecimal(biStr);
System.out.println("Output Number: " + dec + " toBinary "+Integer.toBinaryString(dec));
Where
int binaryStringToDecimal(String biString){
int n = biString.length();
int decimal = 0;
for (int d = 0; d < n; d++){
// append a bit=0 (i.e. shift left)
decimal = decimal << 1;
// if biStr[d] is 1, flip last added bit=0 to 1
if (biString.charAt(d) == '1'){
decimal = decimal | 1; // e.g. dec = 110 | (00)1 = 111
}
}
return decimal;
}
Output:
Input Number: 87 toBinary 1010111
Output Number: 87 toBinary 1010111

Categories