Skip to content

Commit 2421111

Browse files
committed
Cleaned up multiplyUsingLoopWithStringInput, adjusted to account for negative numbers. Also added a multiplyUsingLoopWithInteger which has the same logic but uses integers as input and doesn't need any Arrays
1 parent 219f2c3 commit 2421111

File tree

3 files changed

+338
-66
lines changed

3 files changed

+338
-66
lines changed

src/com/jwetherell/algorithms/mathematics/Multiplication.java

+116-25
Original file line numberDiff line numberDiff line change
@@ -125,49 +125,52 @@ public static String multiplyUsingFFT(String a, String b) {
125125
return result.toString();
126126
}
127127

128-
public static String multiplyUsingLoopWithStringInput(String a,String b){
129-
ArrayList<Integer> first=new ArrayList();
130-
ArrayList<Integer> second=new ArrayList();
131-
}
132-
133-
public static String multiplyUsingLoopWithStringInput(String a,String b){
128+
public static String multiplyUsingLoopWithStringInput(String a, String b) {
134129
int k,i,j,carry=0,rem,flag=0,lim1,lim2,mul;
135-
ArrayList<Integer> first=new ArrayList();
136-
ArrayList<Integer> second=new ArrayList();
137130

138-
for(char n:a.toCharArray()){
131+
boolean aIsNegative = false;
132+
ArrayList<Integer> first = new ArrayList<Integer>();
133+
for (char n : a.toCharArray()){
134+
if (n=='-') {
135+
aIsNegative = true;
136+
continue;
137+
}
139138
first.add(n-'0');
140139
}
141-
for (char n:b.toCharArray()){
140+
141+
boolean bIsNegative = false;
142+
ArrayList<Integer> second = new ArrayList<Integer>();
143+
for (char n : b.toCharArray()){
144+
if (n=='-') {
145+
bIsNegative = true;
146+
continue;
147+
}
142148
second.add(n-'0');
143149
}
144150

145151
lim1=first.size()-1;
146152
lim2=second.size()-1;
147153

148-
ArrayList<Integer> res=new ArrayList<>(Collections.nCopies(first.size()+second.size(), 0));
149-
150-
for(i=0;i<=lim1;i++)
151-
{
154+
ArrayList<Integer> res = new ArrayList<Integer>(Collections.nCopies(first.size()+second.size(), 0));
155+
for (i=0;i<=lim1;i++) {
152156
k=i;
153-
for(j=0;j<=lim2;j++)
154-
{
155-
mul=first.get(i)*second.get(j);
157+
for (j=0;j<=lim2;j++) {
158+
int f = first.get(i);
159+
int s = second.get(j);
160+
mul=f*s;
156161
res.set(k,res.get(k)+(mul/10));
157162
k++;
158163
res.set(k,res.get(k)+(mul%10));
159164
}
160165
}
161166

162-
for(i=(lim1+lim2)+1;i>=0;i--)
163-
{
164-
if(flag==1){
167+
for (i=(lim1+lim2)+1;i>=0;i--) {
168+
if (flag==1){
165169
res.set(i,res.get(i)+carry);
166170
flag=0;
167171
}
168172

169-
if(res.get(i)>=10 && i!=0)
170-
{
173+
if (res.get(i)>=10 && i!=0) {
171174
rem=res.get(i)%10;
172175
carry=res.get(i)/10;
173176
res.set(i,rem);
@@ -176,11 +179,99 @@ public static String multiplyUsingLoopWithStringInput(String a,String b){
176179
}
177180

178181
StringBuilder sb = new StringBuilder();
179-
for (Integer s : res)
180-
{
182+
if (aIsNegative ^ bIsNegative)
183+
sb.append('-');
184+
boolean zeroCheck = true;
185+
for (Integer s : res) {
186+
if (zeroCheck && s.equals("0"))
187+
continue;
188+
zeroCheck = false;
181189
sb.append(s);
182190
}
183-
184191
return sb.toString();
185192
}
193+
194+
public static int multiplyUsingLoopWithIntegerInput(int a, int b) {
195+
boolean aIsNegative = a<0;
196+
boolean bIsNegative = b<0;
197+
a = Math.abs(a);
198+
b = Math.abs(b);
199+
200+
// Find the largest multiple of ten which is larger than 'a'
201+
int largerMultipleA=1;
202+
int numberOfDigitsInA=0;
203+
while (largerMultipleA<a){
204+
largerMultipleA *= 10;
205+
numberOfDigitsInA++;
206+
}
207+
208+
// Find the largest multiple of ten which is larger than 'b'
209+
int largerMultipleB = 1;
210+
int numberOfDigitsInB=0;
211+
while (largerMultipleB<b){
212+
largerMultipleB *= 10;
213+
numberOfDigitsInB++;
214+
}
215+
216+
// Store the results
217+
int[] res = new int[numberOfDigitsInA+numberOfDigitsInB];
218+
219+
// Reduce the digits to the first digit on the left
220+
largerMultipleA /= 10;
221+
numberOfDigitsInA--;
222+
largerMultipleB /= 10;
223+
numberOfDigitsInB--;
224+
225+
// Store original 'q' and 'b', to reset
226+
int originalMultipleB = largerMultipleB;
227+
int originalB = b;
228+
229+
int carry=0,rem,flag=0,mul;
230+
for (int i=numberOfDigitsInA; i>=0; i--) {
231+
int k=numberOfDigitsInA-i;
232+
// reset
233+
largerMultipleB = originalMultipleB;
234+
b = originalB;
235+
for (int j=numberOfDigitsInB; j>=0; j--) {
236+
int f = a/largerMultipleA;
237+
int s = b/largerMultipleB;
238+
239+
b %= largerMultipleB;
240+
largerMultipleB /= 10;
241+
242+
mul=f*s;
243+
res[k] = res[k]+(mul/10);
244+
k++;
245+
res[k] = res[k]+(mul%10);
246+
}
247+
a %= largerMultipleA;
248+
largerMultipleA /= 10;
249+
}
250+
251+
for (int i=(numberOfDigitsInA+numberOfDigitsInB)+1; i>=0; i--) {
252+
if (flag==1){
253+
res[i] = res[i]+carry;
254+
flag=0;
255+
}
256+
257+
if (res[i] >=10 && i!=0) {
258+
rem = res[i]%10;
259+
carry = res[i] /10;
260+
res[i] = rem;
261+
flag++;
262+
}
263+
}
264+
265+
int result = 0;
266+
int m = 1;
267+
for (int idx=res.length-1; idx>=0; idx--) {
268+
int s = res[idx];
269+
result += s*m;
270+
m *= 10;
271+
}
272+
// adjust for negatives
273+
if (aIsNegative ^ bIsNegative)
274+
result *= -1;
275+
return result;
276+
}
186277
}

test/com/jwetherell/algorithms/mathematics/test/Mathematics.java

+126-25
Original file line numberDiff line numberDiff line change
@@ -29,31 +29,132 @@ private static int nextRandomInt(int min, int max) {
2929

3030
@Test
3131
public void multiplication() {
32-
int a = nextRandomInt(MIN, MAX);
33-
int b = nextRandomInt(MIN, MAX);
34-
long result = Multiplication.multiplyUsingLoop(a, b);
35-
long check = Multiplication.multiplication(a, b);
36-
assertTrue("Multiplication using a loop. a=" + a + " b=" + b + " result=" + result + " check=" + check, (result == check));
37-
38-
result = Multiplication.multiplyUsingRecursion(a, b);
39-
check = Multiplication.multiplication(a, b);
40-
assertTrue("Multiplication using recursion. a=" + a + " b=" + b + " result=" + result + " check=" + check, (result == check));
41-
42-
result = Multiplication.multiplyUsingShift(a, b);
43-
check = Multiplication.multiplication(a, b);
44-
assertTrue("Multiplication using shifts. a=" + a + " b=" + b + " result=" + result + " check=" + check, (result == check));
45-
46-
result = Multiplication.multiplyUsingLogs(a, b);
47-
check = Multiplication.multiplication(a, b);
48-
assertTrue("Multiplication using logs. a=" + a + " b=" + b + " result=" + result + " check=" + check, (result == check));
49-
50-
result = Integer.parseInt(Multiplication.multiplyUsingFFT(Integer.toString(a), Integer.toString(b)));
51-
check = Multiplication.multiplication(a, b);
52-
assertTrue("Multiplication using FFT. a=" + a + " b=" + b + " result=" + result + " check=" + check, (result == check));
53-
54-
result = Integer.parseInt(Multiplication.multiplyUsingLoopWithStringInput(Integer.toString(a), Integer.toString(b)));
55-
check = Multiplication.multiplication(a, b);
56-
assertTrue("Multiplication using loop with string input. a=" + a + " b=" + b + " result=" + result + " check=" + check, (result == check));
32+
int a = Math.abs(nextRandomInt(MIN, MAX));
33+
int b = Math.abs(nextRandomInt(MIN, MAX));
34+
// positive * positive
35+
{
36+
long result = Multiplication.multiplyUsingLoop(a, b);
37+
long check = Multiplication.multiplication(a, b);
38+
assertTrue("Multiplication using a loop. a=" + a + " b=" + b + " result=" + result + " check=" + check, (result == check));
39+
40+
result = Multiplication.multiplyUsingRecursion(a, b);
41+
check = Multiplication.multiplication(a, b);
42+
assertTrue("Multiplication using recursion. a=" + a + " b=" + b + " result=" + result + " check=" + check, (result == check));
43+
44+
result = Multiplication.multiplyUsingShift(a, b);
45+
check = Multiplication.multiplication(a, b);
46+
assertTrue("Multiplication using shifts. a=" + a + " b=" + b + " result=" + result + " check=" + check, (result == check));
47+
48+
result = Multiplication.multiplyUsingLogs(a, b);
49+
check = Multiplication.multiplication(a, b);
50+
assertTrue("Multiplication using logs. a=" + a + " b=" + b + " result=" + result + " check=" + check, (result == check));
51+
52+
result = Integer.parseInt(Multiplication.multiplyUsingFFT(Integer.toString(a), Integer.toString(b)));
53+
check = Multiplication.multiplication(a, b);
54+
assertTrue("Multiplication using FFT. a=" + a + " b=" + b + " result=" + result + " check=" + check, (result == check));
55+
56+
result = Integer.parseInt(Multiplication.multiplyUsingLoopWithStringInput(Integer.toString(a), Integer.toString(b)));
57+
check = Multiplication.multiplication(a, b);
58+
assertTrue("Multiplication using loop with string input. a=" + a + " b=" + b + " result=" + result + " check=" + check, (result == check));
59+
60+
result = Multiplication.multiplyUsingLoopWithIntegerInput(a,b);
61+
check = Multiplication.multiplication(a, b);
62+
assertTrue("Multiplication using loop with int input. a=" + a + " b=" + b + " result=" + result + " check=" + check, (result == check));
63+
}
64+
// negative * positive
65+
a *= -1;
66+
{
67+
long result = Multiplication.multiplyUsingLoop(a, b);
68+
long check = Multiplication.multiplication(a, b);
69+
assertTrue("Multiplication using a loop. a=" + a + " b=" + b + " result=" + result + " check=" + check, (result == check));
70+
71+
result = Multiplication.multiplyUsingRecursion(a, b);
72+
check = Multiplication.multiplication(a, b);
73+
assertTrue("Multiplication using recursion. a=" + a + " b=" + b + " result=" + result + " check=" + check, (result == check));
74+
75+
result = Multiplication.multiplyUsingShift(a, b);
76+
check = Multiplication.multiplication(a, b);
77+
assertTrue("Multiplication using shifts. a=" + a + " b=" + b + " result=" + result + " check=" + check, (result == check));
78+
79+
result = Multiplication.multiplyUsingLogs(a, b);
80+
check = Multiplication.multiplication(a, b);
81+
assertTrue("Multiplication using logs. a=" + a + " b=" + b + " result=" + result + " check=" + check, (result == check));
82+
83+
result = Integer.parseInt(Multiplication.multiplyUsingFFT(Integer.toString(a), Integer.toString(b)));
84+
check = Multiplication.multiplication(a, b);
85+
assertTrue("Multiplication using FFT. a=" + a + " b=" + b + " result=" + result + " check=" + check, (result == check));
86+
87+
result = Integer.parseInt(Multiplication.multiplyUsingLoopWithStringInput(Integer.toString(a), Integer.toString(b)));
88+
check = Multiplication.multiplication(a, b);
89+
assertTrue("Multiplication using loop with string input. a=" + a + " b=" + b + " result=" + result + " check=" + check, (result == check));
90+
91+
result = Multiplication.multiplyUsingLoopWithIntegerInput(a,b);
92+
check = Multiplication.multiplication(a, b);
93+
assertTrue("Multiplication using loop with int input. a=" + a + " b=" + b + " result=" + result + " check=" + check, (result == check));
94+
}
95+
// positive * negative
96+
a *= -1;
97+
b *= -1;
98+
{
99+
long result = Multiplication.multiplyUsingLoop(a, b);
100+
long check = Multiplication.multiplication(a, b);
101+
assertTrue("Multiplication using a loop. a=" + a + " b=" + b + " result=" + result + " check=" + check, (result == check));
102+
103+
result = Multiplication.multiplyUsingRecursion(a, b);
104+
check = Multiplication.multiplication(a, b);
105+
assertTrue("Multiplication using recursion. a=" + a + " b=" + b + " result=" + result + " check=" + check, (result == check));
106+
107+
result = Multiplication.multiplyUsingShift(a, b);
108+
check = Multiplication.multiplication(a, b);
109+
assertTrue("Multiplication using shifts. a=" + a + " b=" + b + " result=" + result + " check=" + check, (result == check));
110+
111+
result = Multiplication.multiplyUsingLogs(a, b);
112+
check = Multiplication.multiplication(a, b);
113+
assertTrue("Multiplication using logs. a=" + a + " b=" + b + " result=" + result + " check=" + check, (result == check));
114+
115+
result = Integer.parseInt(Multiplication.multiplyUsingFFT(Integer.toString(a), Integer.toString(b)));
116+
check = Multiplication.multiplication(a, b);
117+
assertTrue("Multiplication using FFT. a=" + a + " b=" + b + " result=" + result + " check=" + check, (result == check));
118+
119+
result = Integer.parseInt(Multiplication.multiplyUsingLoopWithStringInput(Integer.toString(a), Integer.toString(b)));
120+
check = Multiplication.multiplication(a, b);
121+
assertTrue("Multiplication using loop with string input. a=" + a + " b=" + b + " result=" + result + " check=" + check, (result == check));
122+
123+
result = Multiplication.multiplyUsingLoopWithIntegerInput(a,b);
124+
check = Multiplication.multiplication(a, b);
125+
assertTrue("Multiplication using loop with int input. a=" + a + " b=" + b + " result=" + result + " check=" + check, (result == check));
126+
}
127+
// negative * negative
128+
a *= -1;
129+
{
130+
long result = Multiplication.multiplyUsingLoop(a, b);
131+
long check = Multiplication.multiplication(a, b);
132+
assertTrue("Multiplication using a loop. a=" + a + " b=" + b + " result=" + result + " check=" + check, (result == check));
133+
134+
result = Multiplication.multiplyUsingRecursion(a, b);
135+
check = Multiplication.multiplication(a, b);
136+
assertTrue("Multiplication using recursion. a=" + a + " b=" + b + " result=" + result + " check=" + check, (result == check));
137+
138+
result = Multiplication.multiplyUsingShift(a, b);
139+
check = Multiplication.multiplication(a, b);
140+
assertTrue("Multiplication using shifts. a=" + a + " b=" + b + " result=" + result + " check=" + check, (result == check));
141+
142+
result = Multiplication.multiplyUsingLogs(a, b);
143+
check = Multiplication.multiplication(a, b);
144+
assertTrue("Multiplication using logs. a=" + a + " b=" + b + " result=" + result + " check=" + check, (result == check));
145+
146+
result = Integer.parseInt(Multiplication.multiplyUsingFFT(Integer.toString(a), Integer.toString(b)));
147+
check = Multiplication.multiplication(a, b);
148+
assertTrue("Multiplication using FFT. a=" + a + " b=" + b + " result=" + result + " check=" + check, (result == check));
149+
150+
result = Integer.parseInt(Multiplication.multiplyUsingLoopWithStringInput(Integer.toString(a), Integer.toString(b)));
151+
check = Multiplication.multiplication(a, b);
152+
assertTrue("Multiplication using loop with string input. a=" + a + " b=" + b + " result=" + result + " check=" + check, (result == check));
153+
154+
result = Multiplication.multiplyUsingLoopWithIntegerInput(a,b);
155+
check = Multiplication.multiplication(a, b);
156+
assertTrue("Multiplication using loop with int input. a=" + a + " b=" + b + " result=" + result + " check=" + check, (result == check));
157+
}
57158
}
58159

59160
@Test

0 commit comments

Comments
 (0)