An interview question - implement Biginteger Multiply - math

Implement Biginteger Multiply
use integer array to store a biginteger
like 297897654 will be stored as {2,9,7,8,9,7,6,5,4}
implement the multiply function for bigintegers
Expamples: {2, 9, 8, 8, 9, 8} * {3,6,3,4,5,8,9,1,2} = {1,0,8,6,3,7,1,4,1,8,7,8,9,7,6}
I failed to implement this class and thought it for a few weeks, couldn't get the answer.
Anybody can help me implement it using C#/Java?
Thanks a lot.

Do you know how to do multiplication on paper?
123
x 456
-----
738
615
492
-----
56088
I would just implement that algorithm in code.

C++ Implementation:
Source Code:
#include <iostream>
using namespace std;
int main()
{
int a[10] = {8,9,8,8,9,2};
int b[10] = {2,1,9,8,5,4,3,6,3};
// INPUT DISPLAY
for(int i=9;i>=0;i--) cout << a[i];
cout << " x ";
for(int i=9;i>=0;i--) cout << b[i];
cout << " = ";
int c[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
for(int i=0;i<10;i++)
{
int carry = 0;
for(int j=0;j<10;j++)
{
int t = (a[j] * b[i]) + c[i+j] + carry;
carry = t/10;
c[i+j] = t%10;
}
}
// RESULT DISPLAY
for(int i=19;i>=0;i--) cout << c[i];
cout << endl;
}
Output:
0000298898 x 0363458912 = 00000108637141878976

There is a superb algorithm called Karatsuba algorithm..Here
Which uses divide and conquer startegy..Where you can multiply large numbers..
I have implemented my it in java..
Using some manipulation..
package aoa;
import java.io.*;
public class LargeMult {
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws IOException
{
// TODO code application logic here
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter 1st number");
String a=br.readLine();
System.out.println("Enter 2nd number");
String b=br.readLine();
System.out.println("Result:"+multiply(a,b));
}
static String multiply(String t1,String t2)
{
if(t1.length()>1&&t2.length()>1)
{
int mid1=t1.length()/2;
int mid2=t2.length()/2;
String a=t1.substring(0, mid1);//Al
String b=t1.substring(mid1, t1.length());//Ar
String c=t2.substring(0, mid2);//Bl
String d=t2.substring(mid2, t2.length());//Br
String s1=multiply(a, c);
String s2=multiply(a, d);
String s3=multiply(b, c);
String s4=multiply(b, d);
long ans;
ans=Long.parseLong(s1)*(long)Math.pow(10,
b.length()+d.length())+Long.parseLong(s3)*(long)Math.pow(10,d.length())+
Long.parseLong(s2)*(long)Math.pow(10, b.length())+Long.parseLong(s4);
return ans+"";
}
else
{
return (Integer.parseInt(t1)*Integer.parseInt(t2))+"";
}
}
}
I hope this helps!!Enjoy..

Give the number you want to multiply in integer type array i.e. int[] one & int[] two.
public class VeryLongMultiplication {
public static void main(String args[]){
int[] one={9,9,9,9,9,9};
String[] temp=new String[100];
int c=0;
String[] temp1=new String[100];
int c1=0;
int[] two={9,9,9,9,9,9};
int car=0,mul=1; int rem=0; int sum=0;
String str="";
////////////////////////////////////////////
for(int i=one.length-1;i>=0;i--)
{
for(int j=two.length-1;j>=0;j--)
{
mul=one[i]*two[j]+car;
rem=mul%10;
car=mul/10;
if(j>0)
str=rem+str;
else
str=mul+str;
}
temp[c]=str;
c++;
str="";
car=0;
}
////////////////////////////////////////
for(int jk=0;jk<c;jk++)
{
for(int l=c-jk;l>0;l--)
str="0"+str;
str=str+temp[jk];
for(int l=0;l<=jk-1;l++)
str=str+"0";
System.out.println(str);
temp1[c1]=str;
c1++;
str="";
}
///////////////////////////////////
String ag="";int carry=0;
System.out.println("========================================================");
for(int jw=temp1[0].length()-1;jw>=0;jw--)
{
for(int iw=0;iw<c1;iw++)
{
int x=temp1[iw].charAt(jw)-'0';
sum+=x;
}
sum+=carry;
int n=sum;
sum=n%10;carry=n/10;
ag=sum+ag;
sum=0;
}
System.out.println(ag);
}
}
Output:
0000008999991
0000089999910
0000899999100
0008999991000
0089999910000
0899999100000
______________
0999998000001

If you do it the long-hand way, you'll have to implement an Add() method too to add up all the parts at the end. I started there just to get the ball rolling. Once you have the Add() down, the Multipy() method gets implemented along the same lines.
public static int[] Add(int[] a, int[] b) {
var maxLen = (a.Length > b.Length ? a.Length : b.Length);
var carryOver = 0;
var result = new List<int>();
for (int i = 0; i < maxLen; i++) {
var idx1 = a.Length - i - 1;
var idx2 = b.Length - i - 1;
var val1 = (idx1 < 0 ? 0 : a[idx1]);
var val2 = (idx2 < 0 ? 0 : b[idx2]);
var addResult = (val1 + val2) + carryOver;
var strAddResult = String.Format("{0:00}", addResult);
carryOver = Convert.ToInt32(strAddResult.Substring(0, 1));
var partialAddResult = Convert.ToInt32(strAddResult.Substring(1));
result.Insert(0, partialAddResult);
}
if (carryOver > 0) result.Insert(0, carryOver);
return result.ToArray();
}

Hint: use divide-and-conquer to split the int into halves, this can effectively reduce the time complexity from O(n^2) to O(n^(log3)). The gist is the reduction of multiplication operations.

I'm posting java code that I wrote. Hope, this will help
import org.junit.Test;
import static org.junit.Assert.*;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Created by ${YogenRai} on 11/27/2015.
*
* method multiply BigInteger stored as digits in integer array and returns results
*/
public class BigIntegerMultiply {
public static List<Integer> multiply(int[] num1,int[] num2){
BigInteger first=new BigInteger(toString(num1));
BigInteger result=new BigInteger("0");
for (int i = num2.length-1,k=1; i >=0; i--,k=k*10) {
result = (first.multiply(BigInteger.valueOf(num2[i]))).multiply(BigInteger.valueOf(k)).add(result);
}
return convertToArray(result);
}
private static List<Integer> convertToArray(BigInteger result) {
List<Integer> rs=new ArrayList<>();
while (result.intValue()!=0){
int digit=result.mod(BigInteger.TEN).intValue();
rs.add(digit);
result = result.divide(BigInteger.TEN);
}
Collections.reverse(rs);
return rs;
}
public static String toString(int[] array){
StringBuilder sb=new StringBuilder();
for (int element:array){
sb.append(element);
}
return sb.toString();
}
#Test
public void testArray(){
int[] num1={2, 9, 8, 8, 9, 8};
int[] num2 = {3,6,3,4,5,8,9,1,2};
System.out.println(multiply(num1, num2));
}
}

Related

Inverted half pyramid using numbers in JavaFX

I made a normal half pyramid in JavaFX with this code
public void buttonpressed() {
int iNum = Integer.parseInt(Num.getText());
String sResult = "";
String sNumber = "";
for (int i = 1; i<=iNum; i++ ) {
sNumber += i;
sResult += sNumber + "\n";
result.setText(sResult);
}
}
Which outputs (if the inputted number was 5)
1
12
123
1234
12345
Now I have to make 2 triangles (one normal and one inverted) which would look like this (inputted number = 5)
1 12345
12 1234
123 123
1234 12
12345 1
The problem is that I don't understand how to make an inverted triangle, I found how to make one in Java
public class Main {
public static void main(String[] args) {
int rows = 5;
for (int i = rows; i >= 1; --i) {
for (int j = 1; j <= i; ++j) {
System.out.print(j + " ");
}
System.out.println();
}
}
}
But I can't adapt it to JavaFX so please help me with that.
I tried copying the for loops and adapting it to JavaFX but it didn't work.
public void buttonpressed() {
int iNum = Integer.parseInt(Num.getText());
String sResult = "";
String sNumber = "";
for (int i = inum3; i >= 1; i--) {
for (int j = 1; j <= i; ++j) {
sNumber+=j;
sResult += sNumber +"\n";
}
result.setText(sResult);
}
}
The result I want is
12345
1234
123
12
1
Instead, with the provided code, I get
1
12
123
1234
12345
123451
1234512
12345123
123451234
123451234123
1234512341231
12345123412312
123451234123121
The whole code is
package application;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
public class invertedtriangle extends Application{
TextField num = new TextField();
Label result = new Label();
public void start(Stage stage) {
GridPane p = new GridPane();
Scene scene = new Scene(p, 1000, 900);
Label input = new Label("Input a number");
Button press = new Button("Press");
p.add(input,0,1);
p.add(num, 0,2);
p.add(press, 0, 3);
p.add(result, 0, 4);
press.setOnAction(e -> buttonpressed());
p.setHgap(10.0);
p.setVgap(7.0);
stage.setTitle("inv triangle");
stage.setScene(scene);
stage.show();
}
public void buttonpressed() {
int iNum = Integer.parseInt(num.getText());
String sResult = "";
String sNumber = "";
for (int i = iNum; i >= 1; i--) {
for (int j = 1; j <= i; ++j) {
sNumber+=j;
sResult += sNumber +"\n";
}
result.setText(sResult);
}
}
public static void main(String[] args){
launch (args);
}
}
Just use the solution you already have, appending text to a string instead of sending it to the console:
public void buttonPressed() {
int iNum = Integer.parseInt(num.getText());
String sResult = "";
for (int i = iNum; i >= 1; --i) {
for (int j = 1; j <= i; ++j) {
// System.out.print(j + " ");
sResult = sResult + (j+" ");
}
// System.out.println();
sResult = sResult + "\n";
}
result.setText(sResult);
}
Note that it is far more efficient to use a StringBuilder instead of building up strings by concatenation (basically, in Java, you should never repeatedly perform string concatenation on the same string in a loop):
public void buttonPressed() {
int iNum = Integer.parseInt(num.getText());
StringBuilder text = new StringBuilder();
for (int i = iNum; i >= 1; --i) {
for (int j = 1; j <= i; ++j) {
text.append(j).append(" ");
}
text.append("\n");
}
result.setText(text.toString());
}

Leetcode 2360 Longest Cycle in a Graph

I use nearly the same method as in the discussion. But mine reaches the time limitation but his passes all cases. I want to know how to improve my code and why there is difference?
Here is my entire code:
boolean[] visited;
public int dfs(int step, int[] edges, int node, Map<Integer, Integer> path) {
path.put(node, step);
visited[node] = true;
if (edges[node] == -1) {
return -1;
}
if (path.containsKey(edges[node])) {
return step - path.get(edges[node]) + 1;
}
return dfs(step + 1, edges, edges[node], path);
}
public int longestCycle(int[] edges) {
int res = -1;
visited = new boolean[edges.length];
for (int i = 0; i < edges.length; i++) {
if (visited[i]) {
continue;
}
int maxCircleLength = dfs(0, edges, i, new HashMap<Integer, Integer>());
res = Math.max(maxCircleLength, res);
}
return res;
}
This is his solution:
public int longestCycle(int[] edges) {
int longest = -1;
boolean visited[] = new boolean[edges.length]; // global visisted
HashMap<Integer, Integer> map;
for(int i=0; i<edges.length; i++){
if(visited[i]) continue;
int distance = 0, curr_node = i;
map = new HashMap<>(); // local visited
while(curr_node != -1){
if(map.containsKey(curr_node)){
longest = Math.max(longest, distance - map.get(curr_node));
break;
}
if(visited[curr_node]) break;
visited[curr_node] = true;
map.put(curr_node, distance);
curr_node = edges[curr_node];
distance++;
}
}
return longest;
}

Hashing, can't insert to hash table

struct googlePlayApp{
string name;
string category;
double rating;
int reviews;
googlePlayApp *next;
};
void appInsert(googlePlayApp &newApp, int &cmps) {
int slot = hash1(newApp.name, HASH_SIZE);
int cmps1 = 1;
googlePlayApp *tmp = appHash[slot];
if (tmp == 0)
appHash[slot] = &newApp;
else
{
while(tmp->next != 0)
{
tmp = tmp->next;
cmps1++;
}
tmp->next = &newApp;
}
cmps += cmps1;
}
while (getline(inFile, inputLine)) {
googlePlayApp newApp;
readSingleApp(inputLine, newApp);
appInsert(newApp, cmps);
linesRead++;
}
My program stops on the 65th iteration of the while loop....
64th for the appInsert call...
Why can't I get this to work?
This is a program where it reads a data file and stores it in a hash table and collision dealt with open addressing....
updated question
bool appFind(const string &name, googlePlayApp &foundApp, int &cmps) {
// Implement this function
int slot = hash1(name);
int cmps1 = 1;
googlePlayApp *tmp = appHash[slot];
while(tmp && tmp->name != name)
{
cmps1++;
tmp = tmp->next;
}
cmps += cmps1;
if(tmp)
{
foundApp.name = appHash[slot]->name;
foundApp.category = appHash[slot]->category;
foundApp.rating = appHash[slot]->rating;
foundApp.reviews = appHash[slot]->reviews;
}
else return false;
}
this is my serach function and I'm trying to search if an app exists based on the data I stored from my code above. I'm trying to search it by the hash addresses, but it's not working...

Heapsort Error during runtime

Here is a heapsort program I've created in Java, but I'm having an issue where it won't run.
I'm not getting any errors during compilation, which made the error hard to identify, but if I comment out the size decrement in my extract maximum function the program will run, so I assume that's where the error is. Unfortunately, that line is crucial to the program functioning properly.
If there's anything simple causing this problem, or if major adjustments need to be made to the program, I'd like to know either way.
All input is welcome.
Update
added main function.
Code can now be copy-and-pasted to run.
public class Heap
{
private int [] data;
private int [] fin;
private int size;
private int tmp = 0;
/**
* Constructor for objects of class Heap
*/
public Heap(int[] A)
{
data = A;
size = data.length;
fin = new int [size];
this.buildHeap(0);
for(int n = size - 1; n >= 0; n--)
{
fin[n] = this.extractMax();
}
}
public int getSize()
{
return size;
}
private void setSize(int i)
{
size = i;
}
public void print()
{
for(int i = 0; i < this.getSize(); i++)
System.out.printf("%d\n", fin[i]);
}
/**
* build heap using top down method
*
* #param i the index of the node being built upon
*/
private void buildHeap(int i)
{
if(i <= (size - 2)/2)
{
buildHeap(2*i + 1);
buildHeap(2*i + 2);
heapify(i);
}
}
/**
* Extract maximum number
*
* #return maximum number of heap
*/
private int extractMax()
{
int n = size;
int store = 0;
store = data[0];
data[0] = data[n - 1];
size--;
this.heapify(0);
return store;
}
/**
* Heapify array
*
* #param i the index to heapify upon
*/
private void heapify(int i)
{
if(2*i + 1 < size && data[2*i + 1] > data[i])
{
if(2*i + 2 < size && data[2*i + 2] > data[2*i + 1])
{
this.exchange(i, 2*i + 2);
heapify(2*i + 2);
}
else
{
this.exchange(i, 2*i + 1);
heapify(2*i + 1);
}
}
if(2*i + 2 < size && data[2*i + 2] > data[i])
{
this.exchange(i, 2*i + 2);
heapify(2*i + 2);
}
}
private boolean exchange(int i, int k)
{
tmp = data[i];
data[i] = data[k];
data[k] = tmp;
return true;
}
public static void main(String [] args)
{
int [] arr = {5,13,2,25,7,17,20,8,4};
Heap heapsort = new Heap(arr);
heapsort.print();
}
}

Get Positive Bits Indexes from Bit Array

Say I have the following BitArray combinedResults = searchBitArray.And(genreBitArray);
Which contains positive bits i.e 100100110000
How can I get the indexes of all the positive ones ?
Here's a first, decidedly ghetto, crack at it:
BitArray ba = new BitArray(new bool[] {true,false,false,true,false,false,true,true,false,false,false,false});
List<int> pos = new List<int>();
for (int i = 0; i < ba.Length; i++)
{
if (ba[i])
pos.Add(i);
}
That would give you a list containing 0, 3, 6, 7. You could start at ba.Length - 1 and decrement down to zero if you need to read from right to left.
edit: Wrapped in an extension method, just because:
void Main()
{
BitArray ba = new BitArray(new bool[] {true,false,false,true,false,false,true,true,false,false,false,false});
List<int> positives = ba.GetBitPositions(true);
List<int> negatives = ba.GetBitPositions(false);
}
public static class BitArrayExtensions
{
public static List<int> GetBitPositions(this BitArray ba, bool MatchCondition)
{
List<int> pos = new List<int>();
for (int i = 0; i < ba.Length; i++)
{
if (ba[i] == MatchCondition)
pos.Add(i);
}
return pos;
}
}

Resources