Inverted half pyramid using numbers in JavaFX - 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());
}

Related

FloodFill method not working properly. (Recursion)

I am trying to make minesweeper game. Everything is working fine except the floodFill method. Once the floodFill method reveals one number, the recursion stops. I do not want the recursion to stop but go on so that it checks other neighbors as well but it does not. I am not sure what I am doing wrong.
package zProject_MineSweeper;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.*;
import javax.swing.JPanel;
public class MyPanel extends JPanel{
/**
*
*/
private static final long serialVersionUID = 1L;
static final int screenW = 600;
static final int screenH = 600;
static final int unitSize = 40;
static final int rowsNum = screenW/unitSize;
static final int colsNum = screenH/unitSize;
// In this code i have defined bomb as -5
static final int bombNum = -5;
static final int bombGap = 10;
static final double bombProb = 0.05;
static final int fontSize = 20;
int[][] values;
boolean[][] path;
Random random;
MyPanel(){
initializeAll();
initializeValues();
}
private void initializeAll() {
this.addMouseListener(new MyMouseListeners());
this.setPreferredSize(new Dimension(screenW,screenH));
this.setFocusable(true);
this.setBackground(new Color(200,200,200));
random = new Random();
values = new int[rowsNum][colsNum];
path = new boolean[rowsNum][colsNum];
}
private void initializeValues() {
double randomBombProb;
for(int i=0; i<rowsNum; i++) {
for(int j=0; j<colsNum; j++) {
path[i][j] = false;
}
}
for(int i=0; i<rowsNum; i++) {
for(int j=0; j<colsNum; j++) {
randomBombProb = random.nextDouble();
if (randomBombProb< bombProb) {
values[i][j] = bombNum;
}
}
}
for(int i=0; i<rowsNum; i++) {
for(int j=0; j<colsNum; j++) {
if (values[i][j] != bombNum) {
setNumbers(i,j);
}
}
}
}
private void setNumbers(int i, int j) {
//Check number of bombs near each node
int sum = 0;
for(int x=-1; x<2; x++) {
for(int y=-1; y<2; y++) {
int rowx = (i + x + rowsNum) / rowsNum;
int coly = (j + y + colsNum) / colsNum;
if (rowx==1 && coly==1) {
if(values[i+x][j+y] == bombNum) {
sum++;
}
}
}
}
values[i][j] = sum;
}
public void floodFill(int i, int j) {
if(values[i][j]==0) {
for(int x=-1; x<2; x++) {
for(int y=-1; y<2; y++) {
int rowx = (i + x + rowsNum)/rowsNum;
int coly = (j + y + colsNum)/colsNum;
if (rowx == 1 && coly == 1 && !path[i][j]) {
path[i][j] = true;
floodFill(i+x,j+y);
}
}
}
}
else {
path[i][j] = true;
}
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
draw(g);
}
private void draw(Graphics g) {
g.setFont(new Font("Times Roman", Font.BOLD, fontSize));
FontMetrics metrics = getFontMetrics(g.getFont());
for(int i=0; i<rowsNum; i++) {
for(int j=0; j<colsNum; j++) {
if (path[i][j]==true) {
drawValue(g,metrics,i,j);
}
else {
g.setColor(new Color(120,120,120));
g.fillRect(i*unitSize, j*unitSize, unitSize, unitSize);
}
}
}
drawGrid(g);
}
private void drawValue(Graphics g, FontMetrics metrics,int i, int j) {
// Centering the numbers in each cell
if (values[i][j] != bombNum) {
g.setColor(new Color(10,10,10));
g.drawString("" + values[i][j],
i*unitSize + unitSize/2 - metrics.stringWidth("" + values[i][j])/2,
j*unitSize + unitSize/2 + fontSize/2);
}
else {
g.setColor(Color.RED);
g.fillOval(i*unitSize+bombGap, j*unitSize+bombGap, unitSize-(2*bombGap), unitSize-(2*bombGap));
}
}
private void drawGrid(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setStroke(new BasicStroke(2));
g2.setColor(new Color(10,10,10));
for(int i=0; i<rowsNum; i++) {
g2.drawLine(unitSize*i, 0, unitSize*i, screenH);
}
for(int i=0; i<colsNum; i++) {
g2.drawLine(0, unitSize*i, screenW, unitSize*i);
}
}
public class MyMouseListeners implements MouseListener {
public void mouseClicked(MouseEvent e) {
if(e.getButton() == 1) {
int i = e.getX()/unitSize;
int j = e.getY()/unitSize;
floodFill(i, j);
repaint();
}
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
}
}

Showing the values of an ArrayList<List<String>> in a TableView (JavaFX)

I' m trying to create a TableView from a dataset consisting of a doublenested ArrayList with String values. Unfortunately, I cannot display all values in a TableView. The rows are not numbered according to the data set.
The most solutions of the internet demonstrate, that I should use a specific object instance. However, I do not work that way. Instead, I use a matrix of Strings that has an indefinite size. The data is structured as follows:
List<List<String>> values = new ArrayList<List<String>>();
int rows = 10;
int cols = 4;
for(int r=0; r<rows; r++) {
List<String> line = new ArrayList<String>();
for(int c=0; c<cols; c++)
line.add("r: "+r+", c: "+c);
values.add(line);
}
My best (but wrong) result was achieved with the following code:
import java.util.ArrayList;
import java.util.List;
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.stage.Stage;
public class TestApplication extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) throws Exception {
// create values
List<List<String>> values = new ArrayList<List<String>>();
int rows = 10;
int cols = 4;
for (int r = 0; r < rows; r++) {
List<String> line = new ArrayList<String>();
for (int c = 0; c < cols; c++)
line.add("r: " + r + ", c: " + c);
values.add(line);
}
// show values in table
TableView<List<StringProperty>> tableView = new TableView<List<StringProperty>>();
ObservableList<List<StringProperty>> data = FXCollections.observableArrayList();
for (int c = 0; c < cols; c++) {
TableColumn<List<StringProperty>, String> col = new TableColumn<>("Col: " + c);
tableView.getColumns().add(col);
}
for (int r = 0; r < values.size(); r++) {
List<StringProperty> row = new ArrayList<StringProperty>();
for (int c = 0; c < values.get(r).size(); c++) {
TableColumn<List<StringProperty>, String> col = (TableColumn<List<StringProperty>, String>) tableView.getColumns().get(c);
String val = values.get(r).get(c);
col.setCellValueFactory(cl -> new SimpleStringProperty(new String(val)));
}
data.add(row);
}
tableView.setItems(data);
stage.setScene(new Scene(tableView, 300, 500));
stage.show();
}
}
It gives the following result:
However, the table does not show the numbered rows. I have already tried many things. But I did not get a satisfactory result. What is my mistake?
The cellValueFactory for a given column is a function that takes a wrapper containing the data for a row (i.e. the List<StringProperty>) and generates the ObservableValue (e.g. a Property) whose value is to be displayed in that row and column.
In your code you change the cellValueFactory every time you add a row, so the resulting cellValueFactory is just the one from the last row you add, and you see only the data from the last row.
You should set the cellValueFactory just once per column, and it should be a function mapping the row data to the specific value for that column.
For example, the following will give you what you need:
#Override
public void start(Stage stage) throws Exception {
// create values
List<List<String>> values = new ArrayList<List<String>>();
int rows = 10;
int cols = 4;
for (int r = 0; r < rows; r++) {
List<String> line = new ArrayList<String>();
for (int c = 0; c < cols; c++)
line.add("r: " + r + ", c: " + c);
values.add(line);
}
// show values in table
TableView<List<StringProperty>> tableView = new TableView<>();
ObservableList<List<StringProperty>> data = FXCollections.observableArrayList();
for (int c = 0; c < cols; c++) {
TableColumn<List<StringProperty>, String> col = new TableColumn<>("Col: " + c);
final int colIndex = c ;
col.setCellValueFactory(cd -> cd.getValue().get(colIndex));
tableView.getColumns().add(col);
}
for (int r = 0; r < values.size(); r++) {
List<StringProperty> row = new ArrayList<StringProperty>();
for (int c = 0; c < values.get(r).size(); c++) {
row.add(new SimpleStringProperty(values.get(r).get(c)));
}
data.add(row);
}
tableView.setItems(data);
stage.setScene(new Scene(tableView, 300, 500));
stage.show();
}
If the data are not going to change, you might prefer to use something lighter weight than a StringProperty, though the benefit to this small performance saving is debatable:
#Override
public void start(Stage stage) throws Exception {
// create values
List<List<String>> values = new ArrayList<List<String>>();
int rows = 10;
int cols = 4;
for (int r = 0; r < rows; r++) {
List<String> line = new ArrayList<String>();
for (int c = 0; c < cols; c++)
line.add("r: " + r + ", c: " + c);
values.add(line);
}
// show values in table
TableView<List<String>> tableView = new TableView<>();
for (int c = 0; c < cols; c++) {
TableColumn<List<String>, String> col = new TableColumn<>("Col: " + c);
final int colIndex = c ;
col.setCellValueFactory(cd -> new ObservableValue<String>() {
// If data are immutable, there's nothing for a listener to do, so we ignore them:
#Override
public void addListener(InvalidationListener listener) {}
#Override
public void removeListener(InvalidationListener listener) {}
#Override
public void addListener(ChangeListener<? super String> listener) {}
#Override
public void removeListener(ChangeListener<? super String> listener) {}
#Override
public String getValue() {
return cd.getValue().get(colIndex);
}
});
tableView.getColumns().add(col);
}
tableView.setItems(FXCollections.observableList(values));
stage.setScene(new Scene(tableView, 300, 500));
stage.show();
}
That's how it seems to work...i have been guided by
this.
#Override
public void start(Stage stage) throws Exception {
// create values
List<List<String>> values = new ArrayList<List<String>>();
int rows = 10;
int cols = 4;
for (int r = 0; r < rows; r++) {
List<String> line = new ArrayList<String>();
for (int c = 0; c < cols; c++)
line.add("r: " + r + ", c: " + c);
values.add(line);
}
List<String> colHeads = new ArrayList<String>();
for (int c = 0; c < cols; c++) {
String ch = "Col: " + c;
colHeads.add(ch);
}
// show values in table
List<TableColumn<Map<String, String>, String>> tcs = new ArrayList<TableColumn<Map<String, String>, String>>();
for (int c = 0; c < cols; c++) {
String ch = colHeads.get(c);
TableColumn<Map<String, String>, String> col = new TableColumn<>(ch);
col.setCellValueFactory(new MapValueFactory(ch));
tcs.add(col);
}
TableView<Map<String, String>> tableView = new TableView<>(generateDataInMap(colHeads, values));
tableView.getColumns().setAll(tcs);
stage.setScene(new Scene(tableView, 300, 500));
stage.show();
}
private ObservableList<Map<String, String>> generateDataInMap(List<String> colHeads, List<List<String>> values ) {
ObservableList<Map<String, String>> allData = FXCollections.observableArrayList();
for(int r=0; r<values.size(); r++) {
Map<String, String> dataRow = new HashMap<String, String>();
for(int c=0; c<values.get(r).size(); c++) {
String val = values.get(r).get(c);
dataRow.put(colHeads.get(c), val);
}
allData.add(dataRow);
}
return allData;
}

Why the line XXX showing an error saying java.lang.ArrayIndexOutOfBoundsException?

//Firstly I need to create a 2-D array of floating points(randomly generated) and store them in a text file no of rows and columns are user input
import java.io.;
import java.util.;
public class ClaransS {
public static void main(String args[]) throws IOException {
// *********************************************************************
// Variables declaration n-no.of rows k-forget it for now n_o_d-no. of
// columns
// *********************************************************************
int n, k, n_o_d;
// *********************************************************************
// Creating the text file to store data
// *********************************************************************
File f = new File("C:/x/y/clarans.text");
try {
f.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
// *********************************************************************
// Taking user inputs
// *********************************************************************
Scanner userInputScanner = new Scanner(System.in);
System.out.println("Enter the no. of data you want to cluster");
n = userInputScanner.nextInt();
System.out.println(n);
System.out.println("Enter the no. of clusters you want to form");
k = userInputScanner.nextInt();
System.out.println(k);
System.out
.println("Enter the no. of dimensions each data will be in a space of");
n_o_d = userInputScanner.nextInt();
System.out.println(n_o_d);
userInputScanner.close();
// *********************************************************************
// Storing random data in the data-set
// *********************************************************************
double data_set[][] = new double[n][n_o_d];
int count = 1;
int i = 0;
int j = 1;
for (i = 0; i < n; i++) {
data_set[i][0] = count;
for (j = 1; j <= n_o_d; j++) {
//THIS LINE GIVES ERROR
data_set[i][j] = (double) Math.random();//YES THIS ONE XXX
}
count++;
}
for (i = 0; i < n; i++) {
for (j = 0; j <= n_o_d; j++) {
try (PrintWriter out = new PrintWriter(new BufferedWriter(
new FileWriter(f, true)))) {
out.print(data_set[i][j] + "\t");
} catch (IOException e) {
}
}
try (PrintWriter out = new PrintWriter(new BufferedWriter(
new FileWriter(f, true)))) {
out.println();
}
}
}
}
The error is in test condition of for
(j = 1; j <= n_o_d; j++).
Test condition will be j < n_o_d

JFreechart filling sectors series

I am trying to create a filled series over each region of a polar plot. But the colors are not filled out right. Here is an image of what I get: http://i1122.photobucket.com/albums/l539/jpo2/polar-1.gif
Here is the code I have to loop through a given section is as follows:
if (i < 8) {
for(int r = 0; r< 20; r+=(NumberAxis) plot.getAxis()).getTickUnit().getSize()){
for(int theta = 0; theta <= 180; theta+=30){
XYSeries series = new XYSeries(i + "π/8 " + "< θ < 2π+" + i + "π/8");
for (int e = theta; e < theta+30; e++) {
series.add(90-e-i*45, r);
series.add(90-e-i*45, r- ((NumberAxis) plot.getAxis()).getTickUnit().getSize());
}
result.addSeries(series);
setFilled(result);
i++;
}
}
}
private void setFilled(XYDataset dataset) {
for (int i = 0; i < dataset.getSeriesCount(); i++) {
renderers.setSeriesFilled(i, true);
}
}
This is a modification of #trashgod's draw method at JFreechart Loop through polar chart sectors
Please help.
Full code:
import java.awt.Color;
import java.awt.Dimension;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.NumberTick;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.event.ChartProgressEvent;
import org.jfree.chart.event.ChartProgressListener;
import org.jfree.chart.plot.PolarPlot;
import org.jfree.chart.renderer.DefaultPolarItemRenderer;
import org.jfree.chart.renderer.PolarItemRenderer;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.ui.TextAnchor;
public class tests extends JFrame implements ChartProgressListener {
private static final String title = "Archimedes' Spirals";
private XYSeriesCollection result = new XYSeriesCollection();
private DefaultPolarItemRenderer renderers = new DefaultPolarItemRenderer();
private int i;
public tests(String title) {
super(title);
JFreeChart chart = createChart(result);
ChartPanel panel = new ChartPanel(chart);
panel.setPreferredSize(new Dimension(500, 500));
panel.setMouseZoomable(false);
this.add(panel);
}
private JFreeChart createChart(XYDataset dataset) {
ValueAxis radiusAxis = new NumberAxis();
radiusAxis.setTickLabelsVisible(false);
PolarItemRenderer renderer = new DefaultPolarItemRenderer();
PolarPlot plot = new PolarPlot(dataset, radiusAxis, renderer) {
#Override
protected List refreshAngleTicks() {
List<NumberTick> ticks = new ArrayList<NumberTick>();
int delta = (int) this.getAngleTickUnit().getSize();
for (int t = 0; t < 360; t += delta) {
int tp = (360 + 90 - t) % 360;
NumberTick tick = new NumberTick(
Double.valueOf(t), String.valueOf(tp),
TextAnchor.CENTER, TextAnchor.CENTER, 0.0);
ticks.add(tick);
}
return ticks;
}
};
plot.setBackgroundPaint(new Color(0x00f0f0f0));
plot.setRadiusGridlinePaint(Color.gray);
plot.addCornerTextItem("r(θ) = θ; 0 < θ < 2π; +iπ/8");
setFilled(dataset);
plot.setRenderer(renderers);
JFreeChart chart = new JFreeChart(
title, JFreeChart.DEFAULT_TITLE_FONT, plot, true);
chart.setBackgroundPaint(Color.white);
chart.addProgressListener(this);
return chart;
}
public static void main(String[] args) {
tests demo = new tests(title);
demo.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
demo.pack();
demo.setLocationRelativeTo(null);
demo.setVisible(true);
}
#Override
public void chartProgress(ChartProgressEvent e) {
if (e.getType() == ChartProgressEvent.DRAWING_FINISHED) {
System.out.println(e);
JFreeChart chart = e.getChart();
draw();
}
}
public void draw() {
if (i < 4) {
for (int g = 0; g < 30; g += 5) {
for (int h = 0; h < 180; h += 45) {
XYSeries series = new XYSeries(i + "π/8 " + "< θ < 2π+" + i + "π/8");
for (int t = h; t <= h + 45; t++) {
series.add(90 - t, g);
series.add(90 - t, g + 5);
}
result.addSeries(series);
setFilled(result);
i++;
}
}
}
}
private void setFilled(XYDataset dataset) {
for (int i = 0; i < dataset.getSeriesCount(); i++) {
renderers.setSeriesFilled(i, true);
}
}
}
Here's a simplified version the uses PolarPlot directly, without any transformation. It might be easier to experiment with.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.JFrame;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.PolarPlot;
import org.jfree.chart.renderer.DefaultPolarItemRenderer;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
/** #see http://stackoverflow.com/questions/6669734 */
public class PolarArcs {
private static final String title = "PolarArcs";
private static final double PI2 = 90d; // π/2 radians = 90°
private void display() {
JFrame f = new JFrame(title);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ChartPanel panel = new ChartPanel(createChart(createDataset()));
panel.setPreferredSize(new Dimension(400, 400));
f.add(panel);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private JFreeChart createChart(XYDataset dataset) {
JFreeChart chart = ChartFactory.createPolarChart(
title, dataset, true, false, false);
PolarPlot plot = (PolarPlot) chart.getPlot();
plot.setBackgroundPaint(Color.white);
plot.setAngleGridlinesVisible(false);
plot.setRadiusGridlinesVisible(false);
DefaultPolarItemRenderer r = (DefaultPolarItemRenderer) plot.getRenderer();
for (int i = 0; i < dataset.getSeriesCount(); i++ ) {
r.setSeriesFilled(i, true);
}
NumberAxis rangeAxis = (NumberAxis) plot.getAxis();
rangeAxis.setTickLabelsVisible(false);
return chart;
}
private XYDataset createDataset() {
XYSeriesCollection result = new XYSeriesCollection();
for (int r = 8; r > 0; r--) {
XYSeries series = new XYSeries(title + String.valueOf(r));
for (int t = (int) -PI2; t <= PI2; t++) {
series.add(t, r);
}
result.addSeries(series);
}
return result;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new PolarArcs().display();
}
});
}
}

An interview question - implement Biginteger Multiply

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));
}
}

Resources