Running sum of an ArrayList with 2 possible operations - java

I am trying to create a program insert two possible operations (* and +) in between inputed numbers and keep track of the total. The program simply reads from left to right so therefor do not apply BEDMAS
For instance if I inputed: 1 2 3
The output would be 1 + 2 + 3 -> Sum = 6
Or output would be 1 + 2 * 3 -> Sum = 9
Or output would be 1 * 2 + 3 -> Sum = 5
Etc
I am having difficulty because my program continues to try to numbers.remove() from an empty ArrayList(numbers).
public static void calculate(ArrayList<Integer> numbers, int target){
ArrayList<Integer> temp_array = new ArrayList<Integer>(numbers);
int sum = 0;
int n = (numbers.size() - 1);
System.out.println("This is where we calcutale L");
for (int i = 0; i < Math.pow(2, n); i++) {
String bin = Integer.toBinaryString(i);
while (bin.length() < n)
bin = "0" + bin;
char[] chars = bin.toCharArray();
char[] charArray = new char[n];
while(charArrayCount < Math.pow(2,n)){
for (int j = 0; j < chars.length; j++) {
charArray[j] = chars[j] == '0' ? '+' : '*';
}
for(char c : charArray){
int current = numbers.get(0);
if (c == '+'){
sum = sum + current;
}
numbers.remove(0);
System.out.println(sum);
}
numbers = temp_array;
sum = 0;
}
}
}

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

Adding integers in Range not working for negative numbers

I am trying to do this exercise:
Write a program that asks the user for N and M and adds up the
integers between N and M using the formula
SUM(N to M) = SUM( 1 to M ) - SUM( 1 to N-1 )
I can get this to work for positive numbers but not negative numbers.
static int method2(int n, int m) {
int sum = 0;
int sum2 = 0;
for (int i = 1; i <= m; i++) {
sum = sum + i;
}
for (int i = 1; i <= n - 1; i++) {
sum2 = sum2 + i;
}
System.out.println("sum: " + sum + ", sum2: " + sum2);
return sum = sum - sum2;
}
e.g.
using n = -1, m = 1 returns sum = 1.
Using n = -5, m = 5 returns sum = 15.
Using n = 5, m = -5 returns sum = -10.
These should all return 0.
e.g.
Using n = -2, m = 3, returns sum = 6.
Using n = -2, m = 4, returns sum = 10.
The problem is with for (int i = 1; i <= n - 1; i++), specifically i <= n - 1 because when n-1 <= 0 this will not run. I just can't think of a way around it.
Your formula
SUM(N to M) = SUM( 1 to M ) - SUM( 1 to N-1 )
Doesn't really make sense for negative values. If you give that up you can make your program simpler. We very often start for loops at 0 or 1 but that doesn't have to be the case. You could instead start your loop at a n which might be negative:
static int method2(int n, int m) {
int sum = 0;
for (int i = n; i <= m; i++) {
sum = sum + i;
}
System.out.println("sum: " + sum);
return sum;
}
You could always check before if n < 0.
And then do another reverse loop for negative numbers.
e.g.
int sum = 0;
if(m < 0){
for(int i = 0; i >= m; i--) {
sum += i;
}
} else {
for (int i = 1; i <= m; i++) {
sum += i;
}
}
If you really have to use that formula you could use instead of:
for (int i = 1; i <= m; i++) {
the following code which changes the index either by 1 or by -1
for (int i = 1; i <= m; i+=(int)Math.signum(m-1+0.1)) {
(added 0.1 such that in case m is 1 the result is positive and not 0)
Ofc you should do the same for n.

Trying to convert a String of digits to a array of numbers

I wrote a function that validates credit cards. It usses the last 10 digits of the card number. The card number is stored as a String. I'm trying to figure out how to converts the last 10 digits of the card number into a array numbers. I found some code on stack overflow, but it usses string instad of String. So I get a error when I try to access the string as a arrow
Code:
int[] n = { 0, 0, 0, 8, 2, 9, 8, 7, 0, 1 };
boolean ValidCredt()
{
String strNum = "1230008298701";
int p = strNum.length() - 1;
int pt = 9;
// this is where I'm trying to convert the String into a arrow of
// numbers
for (int i = 0; i < 10; i++)
{
n[pt--] = strNum[p--] - '0'; // get a error for tryinmg to usr
// String as a array
}
// step 1 double every other digit
n[9] = n[9] + n[9];
n[7] = n[7] + n[7];
n[5] = n[5] + n[5];
n[3] = n[3] + n[3];
n[1] = n[1] + n[1];
// Your number is now “0-0-0-16-2-18-8-14-0-2.”
// step 3 add together 2 digy
for (int i = 0; i < n.length; i++)
{
if (n[i] > 9)
{
int low = n[i] % 10;
int hi = n[i] / 10;
n[i] = low + hi;
}
}
// Your number is now “0-0-0-7-2-9-8-5-0-2.”
// step 4
int sum = 0;
for (int i = 0; i < n.length; i++)
sum = sum + n[i];
// step 5
int step5 = sum * 9;
int step5b = 10 - sum % 10;
// step 6
int step6 = sum + step5 % 10;
if (step5 % 10 == 0)
return true;
return false;
}
I'm not sure why have you tried so complicated stuff, but I think this might be useful:
String ccNumber = "1234567890";
char[] characters = ccNumber.toCharArray();
int[] result = new int[characters.length];
int i = 0;
for (char c : characters) {
result[i++] = c - '0';
}
int[] result = new int[string.size()];
for(int i = 0; i < string.size(); i++){
result[i] = string.charAt(i) - '0';
}

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