Array Index out of bounds think there is a specfic line - java

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 100 at ham.main(ham.java:34)
line 34 on my console says if (h[c] == 1)
i wrote a code to generate hamming code..i am getting the javaindexoutbounds exception..i even gave absurdly large array sizes to counter tht..still not working!
The array is outbounds even thou there plenty of space for the array
the line 27 might be a mistake...checking for c
import java.util.*;
public class ham {
public static void main(String ar[]) {
Scanner s = new Scanner(System.in);
System.out.println("input no. of bits");
int n = s.nextInt();
int a[] = new int[100]; // user's input
int h[] = new int[100]; // hamming code array
System.out.println("i/p the data");
int i = 1, j = 1, pb = 1;
for (i = 1; i < n + 1; i++)
a[i] = s.nextInt();
i = 1;
while (i < n + 1) {
if (j == pb) // if the index is a parity bit leave it
{
j++;
pb = pb * 2;
} else {
h[j] = a[i];
j++;
i++;
} // else copy the data bits from a[] to h[]
}
int c = 0, counter = 0; // to fill the parity bits(k)
for (int k = 1; k <= j; k = 2 * k) {
c = k;
while (c <= j) // 'j' is position of the last data bit in h[]
{
for (c = k; c < (c + k); c++) {
if (h[c] == 1) // this is line 34
counter++;
}
c = c + k + 1;
}
if (counter % 2 == 0)
h[k] = 0;
else
h[k] = 1;
}
System.out.println("hamming code is");
for (i = 1; i <= j; i++)
System.out.print(h[i] + " ");
}
}

The if (h[c] == 1) test is causing the exception.
Your h array has a fixed size of 100, but the maximum value of c seems to depend on the user's input, n. You will need to figure out how to dynamically determine your array sizes, depending on the user input.

Related

how to calculate total number of combinations for 4*3 matrix where 2 elements in matrix are not present

below is the format of the matrix. and no diagonal combinations of letters is allowed ,only vertical and horizontal combinations are allowed.
Can anyone suggest how to calculate the number of combinations required for a particular level.
example: if i say level is 1 then , only 1 letter combination is allowed i.e. A,B,C,D,E,F,G,H,I i.e. 10 combinations
if i say level is 2 then possible combinations are AA,BB,AB,AD,BC,BE,... and so on so total 36 combinations for level 2.
Like that if input is any level number given, then how do i calculate the possible number of combinations ?
A B C
D E F
G H I
J
I tried using this formula :
(n!/(r!(n-r)!)
but it doesnt calculate properly from level 2 onwards.
note : on both sides of J no letter is present.
Please suggest.
#Thientvse
This is the code that i coded... it gives correct output...can you please tell me whether my code is correct and whether it will satisfy all test cases for this scenario
import java.util.ArrayList;
import java.util.Scanner;
public class Game {
public static int combinationCounts(int input1){
ArrayList<String> mainalternatestring = new ArrayList<String>();
ArrayList<String> mainverticalstring = new ArrayList<String>();
String sb = "ABC#DEF#GHI# J ";
String a=null,b=null,c=null,nw=null;
int mainindex = 0,counter,totalcount=10,index=0,mainindex_duplicate=0,count=1;
if(input1 > 1 && input1 <= 4){
while(mainindex != 11){
int level = 0;
counter = 0;
count=1;
char[] strtoworkon = new char[sb.length()];
index=0;
if(mainindex != 0)
mainindex = mainindex+1;
for(int j = mainindex; count!= (sb.length()-mainindex) ; j++){
if(level == input1)
break;
if(sb.charAt(j) == '#'){
level++;
if (counter == 0){
mainindex_duplicate = j;
counter = 1;
}
}
if(level <= input1){
strtoworkon[index] = sb.charAt(j);
index++;
}
count++;
}
mainindex = mainindex_duplicate;
// for sideways combinations
for(int m = 0; m <= strtoworkon.length; m++){
c = null;
if(strtoworkon[m] == ' ')
break;
if(!String.valueOf(strtoworkon).substring(m, m+(input1)).contains("#")){
c = String.valueOf(strtoworkon).substring(m, m+(input1));
if(!c.matches(".*[A-Z].*"))
break;
if(!mainalternatestring.contains(c))
mainalternatestring.add(c);
}
}
//for vertical combinations
nw = "#" + (String.valueOf(strtoworkon));
int counter1=0;
while(counter1 != 3){
c="";
for(int n = 0; n<= strtoworkon.length; n++){
if(nw.charAt(n) == '#'){
Character test = nw.charAt(n+counter1);
a = Character.toString(strtoworkon[n+counter1]).trim();
if(a.contains("#"))
break;
c = a+c;
c.trim();
}
}
if(!mainverticalstring.contains(c) && c.length() == input1)
mainverticalstring.add(c);
counter1++;
}
if(mainindex == 11)
break;
}
totalcount = totalcount + (2*mainalternatestring.size()) + (2*mainverticalstring.size());
}
return totalcount;
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int output = 0;
int ip1 = Integer.parseInt(in.nextLine().trim());
output = combinationCounts(ip1);
System.out.println(String.valueOf(output));
}
}

Traveling salesman code not working (Java)

Traveling salesman code in java below (gives wrong result)
http://www.sanfoundry.com/java-program-solve-travelling-salesman-problem-unweighted-graph/
package com.hinguapps.graph;
import java.util.InputMismatchException;
import java.util.Scanner;
public class TSP {
private int numberOfNodes;
private Stack < Integer > stack;
public TSP() {
stack = new Stack < Integer > ();
}
public void tsp(int adjacencyMatrix[][]) {
numberOfNodes = adjacencyMatrix[1].length - 1;
int[] visited = new int[numberOfNodes + 1];
visited[1] = 1;
stack.push(1);
int element, dst = 0, i;
int min = Integer.MAX_VALUE;
boolean minFlag = false;
System.out.print(1 + "\t");
while (!stack.isEmpty()) {
element = stack.peek();
i = 1;
min = Integer.MAX_VALUE;
while (i <= numberOfNodes) {
if (adjacencyMatrix[element][i] > 1 && visited[i] == 0) {
if (min > adjacencyMatrix[element][i]) {
min = adjacencyMatrix[element][i];
dst = i;
minFlag = true;
}
}
i++;
}
if (minFlag) {
visited[dst] = 1;
stack.push(dst);
System.out.print(dst + "\t");
minFlag = false;
continue;
}
stack.pop();
}
}
public static void main(String...arg) {
int number_of_nodes;
Scanner scanner = null;
try {
System.out.println("Enter the number of nodes in the graph");
scanner = new Scanner(System.in);
number_of_nodes = scanner.nextInt();
int adjacency_matrix[][] = new int[number_of_nodes + 1][number_of_nodes + 1];
System.out.println("Enter the adjacency matrix");
for (int i = 1; i <= number_of_nodes; i++) {
for (int j = 1; j <= number_of_nodes; j++) {
adjacency_matrix[i][j] = scanner.nextInt();
}
}
for (int i = 1; i <= number_of_nodes; i++) {
for (int j = 1; j <= number_of_nodes; j++) {
if (adjacency_matrix[i][j] == 1 &&
adjacency_matrix[j][i] == 0) {
adjacency_matrix[j][i] = 1;
}
}
}
System.out.println("The cities are visited as follows: ");
TSP tspNearestNeighbour = new TSP();
tspNearestNeighbour.tsp(adjacency_matrix);
} catch (InputMismatchException inputMismatch) {
System.out.println("Wrong Input format");
}
scanner.close();
}
}
Matrix should be :
0 10 5 40
2 0 5 1
6 13 0 12
1 8 9 0
Expected result: 1 3 2 4 1
Code result : 1 3 4 2 1
This implementation is wrong. This is a hard problem, because you need to either touch every path, or at the very least CONSIDER every path. This implementation basically boils down to "Each step, move to the closest node that I haven't visited". Since the stack is not keeping memory of where you have been, it does not backtrack to consider that a better path may have existed down one of the longer roads.
To fix this, the algorithm needs to keep the path in memory somehow, and not start printing the solution until the best solution has actually been found. (Can use recursion, a stack that holds the whole path, or some other method.)

Need help to solve the hackerrank challenge

I'm trying to solve an "Almost Sorted" challenge in hackerrank the problem is:
Given an array with elements, can you sort this array in ascending order using only one of the following operations?
Swap two elements.
Reverse one sub-segment.
Input Format
The first line contains a single integer, , which indicates the size of the array.
The next line contains integers separated by spaces.
Sample Input #1
2
4 2
Sample Output #1
yes
swap 1 2
Sample Input #2
3
3 1 2
Sample Output #2
no
Sample Input #3
6
1 5 4 3 2 6
Sample Output #3
yes
reverse 2 5
I tried to solve the challenge and my code is working but it seems it's to slow for big arrays.
Kindly asking you to help me to find a better solution for mentioned problem.
Below is my code:
import java.util.*;
public class Solution
{
private static int[] arr;
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int N = in.nextInt();
arr = new int[N];
for (int i = 0; i < N; i++)
{
arr[i] = in.nextInt();
}
if (IsSorted(arr))
{
System.out.println("yes");
return;
}
if(CheckSingleSwap(arr))
return;
if(CheckSingleReverse(arr))
return;
System.out.println("no");
}
private static boolean CheckSingleReverse(int[] arr)
{
int length = arr.length;
int limit = length - 2;
int current = 1;
List<Integer> indexes = new ArrayList<Integer>();
while (current < limit)
{
for (int i = 0; i < length; i++)
{
int temp = current + i;
for (int j = i; j <= temp && temp < length; j++)
{
indexes.add(j);
}
if (IsSorted(ReverseArrayPart(arr, indexes)))
{
System.out.println("yes");
System.out.println("reverse " + (indexes.get(0) + 1) + " " + (indexes.get(indexes.size() - 1) + 1));
return true;
}
indexes.clear();
}
current++;
}
return false;
}
private static int[] ReverseArrayPart(int[] arr, List<Integer> indexes)
{
int[] result = new int[arr.length];
int[] arrayPart = new int[indexes.size()];
int j = 0;
for (int i = 0; i < arr.length; i++)
{
if (indexes.contains(i))
{
arrayPart[j] = arr[i];
j++;
}
result[i] = arr[i];
}
for(int i = 0; i < arrayPart.length / 2; i++)
{
int temp = arrayPart[i];
arrayPart[i] = arrayPart[arrayPart.length - i - 1];
arrayPart[arrayPart.length - i - 1] = temp;
}
j = 0;
for (int i = 0; i < result.length; i++)
{
if (indexes.contains(i))
{
result[i] = arrayPart[j];
j++;
}
}
return result;
}
private static boolean CheckSingleSwap(int[] arr)
{
int count = 0;
int[] B = Arrays.copyOf(arr, arr.length);
Arrays.sort(B);
List<Integer> indexes = new ArrayList<Integer>();
for(int i = 0; i < arr.length; i++)
{
if(arr[i] != B[i])
{
count++;
indexes.add(i+1);
}
}
if(count > 2)
return false;
System.out.println("yes");
System.out.println("swap " + indexes.get(0) + " " + indexes.get(1));
return true;
}
private static boolean IsSorted(int[] arr)
{
int length = arr.length;
for (int i = 0; i < length - 1; i++)
{
if (arr[i] > arr[i + 1])
{
return false;
}
}
return true;
}
}
For the following code, pass in A as the original array and B as the sorted array.
CheckSingleSwap:
Instead of adding the indices to another list, store the first swap you encounter, and keep going; if you find the corresponding other swap, then store it and record the finding; if you find a different swap, exit with false. At the end if you've recorded the finding, print the corresponding indices.
private static boolean CheckSingleSwap(int[] A, int[] B)
{
int L = A.length;
int firstSwap = -1, secondSwap = -1;
for(int i = 0; i < L; i++)
{
if(A[i] != B[i])
{
if (firstSwap == -1)
firstSwap = i;
else if (secondSwap == -1 && A[i] == B[firstSwap] && A[firstSwap] == B[i])
secondSwap = i;
else
return false;
}
}
if (firstSwap != -1 && secondSwap != -1)
{
System.out.println("yes");
System.out.println("swap " + (firstSwap + 1) + " " + (secondSwap + 1));
return true;
}
System.out.println("array is already sorted!");
return false; // or whatever you decide to do; maybe even an exception or enumerated type
}
CheckSingleReverse:
You are doing WAY too much here! You seem to be brute forcing every single possible case (at first glance).
What you can do instead is to find the region where all the numbers are different. If there are more than two of these, or two which are separated by more than one element, then return false immediately.
The reason for the "more than one" thing above is because of odd-number length regions - the middle element would be the same. If you find such two regions, treat them as one. Then you can proceed to find out if the region is reversed.
private static boolean CheckSingleReverse(int[] A, int[] B)
{
// find region
int L = A.length;
int diffStart = -1, diffEnd = -1; boolean mid = false, found = false;
for (int i = 0; i < L; i++)
{
if (A[i] != B[i])
{
if (found)
{
if (i - diffEnd == 2 && !mid)
{
mid = true;
found = false;
diffEnd = -1;
}
else
return false;
}
else if (diffStart == -1)
diffStart = i;
}
else
if (diffStart != -1 && diffEnd == -1)
{
found = true;
diffEnd = i - 1;
}
}
if (diffEnd == -1)
{
if (A[L - 1] != B[L - 1])
diffEnd = L - 1;
else if (!found)
{
System.out.println("array is already sorted!");
return false;
}
}
// find out if it's reversed
int count = (diffEnd - diffStart + 1) / 2;
for (int i = 0; i < count; i++)
{
int oneEnd = diffStart + i, otherEnd = diffEnd - i;
if (!(A[oneEnd] == B[otherEnd] && A[otherEnd] == B[oneEnd]))
return false;
}
System.out.println("yes");
System.out.println("reverse " + (diffStart + 1) + " " + (diffEnd + 1));
return true;
}
Just to give you an idea of the performance boost, on ideone.com, with an array length of 150, the original implementation of CheckSingleReverse took 1.83 seconds, whereas the new one took just 0.1 seconds. With a length of 250, the original actually exceeded the computational time limit (5 seconds), whereas the new one still took just 0.12 seconds.
From this it would seem that your implementation takes exponential time, whereas mine is linear time (ignoring the sorting).
Funnily enough, with an array size of 3 million I'm still getting around 0.26 seconds (ideone's execution time fluctuates a bit as well, probs due to demand)

Find the Last Digit In An Array

I need to find the last digit in a array and see if it is equal to zero. Here is the code I'm using;
import java.util.Scanner;
public class NrOccurrence
{
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
System.out.print("Enter the integers between 1 and 100: ");
int[] numbers = new int[100], times = new int[100];
boolean zero = false;
while (zero == false)
{
for (int a = 0; a <= numbers.length; a++)
{
numbers[a] = scan.nextInt();
times[a]++;
if (numbers.equals(0))
{
zero = true;
}
}
}
for (int b = 0; b <= numbers.length; b++)
{
System.out.println(numbers[b] + " occurs " + times[b] + " times");
}
scan.close();
}
}
Create a method like this:
private boolean isLastItemZero(int[] numbers)
{
boolean isLastItemZero = false;
if ((numbers != null) && (numbers.length > 0))
{
isLastItemZero = numbers[numbers.length - 1] == 0;
}
return isLastItemZero;
}
And call it once you're done reading in all of the numbers from the user.
First of all for (int a = 0; a <= numbers.length; a++) will give youIndexOutOfBoundsException .Java uses 0 bases indexing which means that an array of size n has indices up to and including n-1. Change it tofor (int a = 0; a < numbers.length; a++) . Same thing here for (int b = 0; b <= numbers.length; b++)
Second i am not sure what you are trying to check here :
if (numbers.equals(0))
{
zero = true;
}
but you could simply do :
if(numbers[i] == 0);
Now if you wanna check if the last element in the array is 0you can simply do:
if(numbers[numbers.length - 1] == 0)
//do something
By definition, if the remainder of a number divided by 10 is 0, then the last digit must be 0. So you just need;
if(numbers[i] % 10 == 0) { zero = true; }
Hope this helps.

Homework: how to write own multiplication of big numbers?

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

Categories