Related
i'm just created a java project to print string that is given in rows and column just like matrix. Here's the output that i just made:
h e l l o
_ w o r l
d _ i t s
_ b e a u
t i f u l
Is it possible to show the output like a spiral pattern like this?
h e l l o
_ b e a _
s u l u w
t f i t o
i _ d l r
For the clarification how this spiral matrix created:
Here's my current code:
String str = "hello world its beautiful";
double length = Math.sqrt(str.length());
int x = (int) length;
for (int i = 0, len = str.length(); i < len; i++) {
System.out.print(str.charAt(i) + " ");
if (i % x == x - 1) {
System.out.println();
}
}
I'm trying to make the same pattern like that, but it's never be. Let me know that you can help me with this. I appreciate for every answer that you gave, thank you.
Basically, you move through the string from start to end, but treat the stringbuffer as an array.
You#ll also need to to keep track of your direction (dx,dy) and where your bounds are.
The following code will produce:
hello
beau
l.tw
sufio
i dlr
given the input "hello world is beautiful"
public class Main {
public static void main(String[] args) {
String text ="hello world is beautiful";
int len = text.length();
double sideLength = Math.sqrt( len );
int width = 0;
int height = 0;
// check if it's a square
if ( sideLength > (int) sideLength) {
// nope... it#s a rectangle
width = (int) sideLength +1;
height = (int) Math.ceil((double)len / (double)width);
} else {
// square
width = (int) sideLength;
height = (int) sideLength;
}
// create a buffer for the spiral
StringBuffer buf = new StringBuffer( width * height );
buf.setLength( width * height );
// clear it.
for (int a=0; a < buf.length(); a++ ) {
buf.setCharAt(a, '.');
}
int dstX = 0;
int dstY = 0;
int curWidth = width;
int curHeight = height;
int startX = 0;
int startY = 0;
int dx = 1;
int dy = 0;
// go through the string, char by char
for (int srcPos =0; srcPos < len; srcPos++) {
buf.setCharAt( dstX + dstY * width, text.charAt( srcPos ));
// move cursor
dstX += dx;
dstY += dy;
// check for bounds
if ( dstX == curWidth-1 && dx > 0) {
// end of line while going right, need to go down
dx = 0;
dy = 1;
// also, reduce width
curWidth--;
startY++;
} else if (dstY == curHeight-1 && dy > 0) {
// end of column while going down, need to go left
dx = -1;
dy = 0;
// also, reduce height
curHeight--;
} else if (dstX == startX && dx < 0) {
// hit left border while going left, need to go up
dx = 0;
dy = -1;
// also, increase startX
startX++;
} else if (dstY == startY && dy < 0) {
// hit top border, while going up, need to go right
dx = 1;
dy = 0;
// also, increase startY
startY++;
}
}
// display string
for (int line = 0; line < height; line++) {
System.out.println( buf.substring( line* width, line*width +width) );
}
}
}
spiralMatrix(int s) returns s x s spiral matrix.
static int[][] spiralMatrix(int s) {
int[][] a = new int[s][s];
int n = 0;
for (int b = s - 1, c = 0, x = 0, y = 0, dx = 0, dy = 1; b > 0; b -= 2, x = y = ++c)
for (int j = 0, t = 0; j < 4; ++j, t = dx, dx = dy, dy = -t)
for (int i = 0; i < b; ++i, x += dx, y += dy, ++n)
a[x][y] = n;
if (s % 2 == 1)
a[s / 2][s / 2] = n;
return a;
}
test
for (int s = 0; s < 6; ++s) {
int[][] a = spiralMatrix(s);
System.out.println("s=" + s);
for (int[] row : a)
System.out.println(Arrays.toString(row));
System.out.println();
}
result
s=0
s=1
[0]
s=2
[0, 1]
[3, 2]
s=3
[0, 1, 2]
[7, 8, 3]
[6, 5, 4]
s=4
[0, 1, 2, 3]
[11, 12, 13, 4]
[10, 15, 14, 5]
[9, 8, 7, 6]
s=5
[0, 1, 2, 3, 4]
[15, 16, 17, 18, 5]
[14, 23, 24, 19, 6]
[13, 22, 21, 20, 7]
[12, 11, 10, 9, 8]
And you can do it with this method.
String str = "hello world its beautiful";
int[][] spiral = spiralMatrix(5);
int length = str.length();
for (int x = 0, h = spiral.length, w = spiral[0].length; x < h; ++x) {
for (int y = 0; y < w; ++y) {
int p = spiral[x][y];
System.out.print((p < length ? str.charAt(p) : " ") + " " );
}
System.out.println();
}
result
h e l l o
b e a
s u l u w
t f i t o
i d l r
you could try to make the spiral algorithm first and try to find the value of its each index in the matrix so that later you could map every index of your string into the specific index in the spiral array matrix.
for example:
Input: n = 5
Output: 1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
Aligned Output: 1 2 3 4 5 16 17 18 19 6 15 24 25 20 7 14 23 22 21 8 13 12 11 10 9
the algorithm can be found here or here.
now you know all the index of each position to make the letters aligned in a spiral way, what you have to do is map each letter of your string to be print according to the number of the spiral matrix sequentially.
print string 1.
print string 2.
print string 3.
print string 4.
print string 5.
print string 16.
print string 17.
print string 18.
print string 19.
print string 6.
print string 15.
cont...
Probably I'll add my answer too, idea is to flatten a two dimensional array to 1d and use the 1D array and transform it to a 2D spiral array. Hope it helps.
Code:
class Test {
static String[][] spiralPrint(int m, int n, String[] a) {
String[][] output = new String[m][n];
int count = 0;
int i, k = 0, l = 0;
while (k < m && l < n) {
for (i = l; i < n; ++i) {
output[k][i] = a[count++];
}
k++;
for (i = k; i < m; ++i) {
output[i][n - 1] = a[count++];
}
n--;
if (k < m) {
for (i = n - 1; i >= l; --i) {
output[m - 1][i] = a[count++];
}
m--;
}
if (l < n) {
for (i = m - 1; i >= k; --i) {
output[i][l] = a[count++];
}
l++;
}
}
return output;
}
private static String[] flattenArray(String[][] input, int m, int n) {
String[] output = new String[m * n];
int k = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
output[k++] = input[i][j];
}
}
return output;
}
public static void main(String[] args) {
String[][] input = {
{"h", "e", "l", "l", "o"},
{"_", "w", "o", "r", "l"},
{"d", "_", "i", "t", "s"},
{"_", "b", "e", "a", "u"},
{"t", "i", "f", "u", "l"}};
int m = 5;
int n = 5;
String[] flattenArray = flattenArray(input, m, n);
String[][] spiralArray = spiralPrint(m, n, flattenArray);
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
System.out.print(spiralArray[i][j] + " ");
}
System.out.println();
}
}
}
Output:
h e l l o
_ b e a _
s u l u w
t f i t o
i _ d l r
Note: Indeed that I followed this Spiral transform to 1D, but it is not straight forward, I have re-modified to fit to the problem.
I think that the best way to implement this is the following:
create an instruction object (Dictionary.java) which controls the fill-in process of the matrix
fill in the matrix with data (Spiral.java)
then show the matrix
With this approach, you can change the pattern easily, without changing the rest of the code because the pattern generator works detached from the rest of the code.
This is how the basic Dictionary class may look like:
public abstract class Dictionary {
protected int matrixSize;
protected String[] dictionary;
public Dictionary(int matrixSize) {
this.matrixSize = matrixSize;
dictionary = new String[matrixSize * matrixSize];
}
public abstract String[] createPattern();
public void showPattern() {
Arrays.stream(dictionary).forEach(System.out::println);
}
}
For each pattern, you need to implement the createPattern() method differently.
For example, a frame pattern implementation can be something like this:
public class FrameDictionary extends Dictionary {
protected int dictionaryIndex = 0;
protected int startX, endX;
protected int startY, endY;
public FrameDictionary(int matrixSize) {
super(matrixSize);
startX = -1;
endX = matrixSize - 1;
startY = 0;
endY = matrixSize - 1;
}
#Override
public String[] createPattern() {
while (dictionaryIndex < matrixSize) {
pattern1();
pattern2();
}
return dictionary;
}
/**
* pattern 1
* direction: left -> right then top -> bottom
*/
protected void pattern1() {
startX++;
for (int i = startX; i <= endX; i++) {
dictionary[dictionaryIndex] = i + ":" + startY;
dictionaryIndex++;
}
startY++;
for (int i = startY; i <= endY; i++) {
dictionary[dictionaryIndex] = endX + ":" + i;
dictionaryIndex++;
}
}
/**
* pattern 2
* direction: right -> left then bottom -> top
*/
protected void pattern2() {
endX--;
for (int i = endX; i >= startX; i--) {
dictionary[dictionaryIndex] = i + ":" + endY;
dictionaryIndex++;
}
endY--;
for (int i = endY; i >= startY; i--) {
dictionary[dictionaryIndex] = startX + ":" + i;
dictionaryIndex++;
}
}
}
Output:
a b c d e f
t g
s h
r i
q j
p o n m l k
You can draw the pattern what you need with the following implementation of the createPattern() method:
public class ClockWiseDictionary extends FrameDictionary {
public ClockWiseDictionary(int matrixSize) {
super(matrixSize);
}
#Override
public String[] createPattern() {
int pixelsInMatrix = matrixSize * matrixSize;
while (dictionaryIndex < pixelsInMatrix) {
pattern1();
pattern2();
}
return dictionary;
}
}
Output:
a b c d e f
t u v w x g
s 6 7 8 y h
r 5 0 9 z i
q 4 3 2 1 j
p o n m l k
Or just for fun, a "snake" pattern implementation:
public class SnakeDictionary extends Dictionary {
private int dictionaryIndex = 0;
private int startY = 0;
public SnakeDictionary(int matrixSize) {
super(matrixSize);
}
#Override
public String[] createPattern() {
int pixelsInMatrix = matrixSize * matrixSize;
while (dictionaryIndex < pixelsInMatrix) {
pattern1();
if (dictionaryIndex < pixelsInMatrix) {
pattern2();
}
}
return dictionary;
}
public void pattern1() {
for (int i = 0; i < matrixSize; i++) {
dictionary[dictionaryIndex] = i + ":" + startY;
dictionaryIndex++;
}
startY++;
}
public void pattern2() {
for (int i = matrixSize - 1; i >= 0; i--) {
dictionary[dictionaryIndex] = i + ":" + startY;
dictionaryIndex++;
}
startY++;
}
}
Output:
a b c d e f
l k j i h g
m n o p q r
x w v u t s
y z 1 2 3 4
0 9 8 7 6 5
This is how the main method looks like:
public static void main(String[] args) {
String sentence = "abcdefghijklmnopqrstuvwxyz1234567890";
String[][] spiral = new String[MATRIX_SIZE][MATRIX_SIZE];
// Dictionary dictionary = new FrameDictionary(MATRIX_SIZE);
Dictionary dictionary = new ClockWiseDictionary(MATRIX_SIZE);
// Dictionary dictionary = new SnakeDictionary(MATRIX_SIZE);
String[] pattern = dictionary.createPattern();
//dictionary.showPattern();
Spiral.fill(sentence, pattern, spiral);
Spiral.show(spiral);
}
You can check/download the complete source code from GitHub.
Hope that it helps you.
Here's a one with a recursive approach,
I am traversing the matrix in right -> down -> left -> up fashion on the boundaries
Then change the size and do the same for inner boundaries,
Matrix M would be a spiral matrix then of character indices
Create spiral matrix C for characters by traversing matrix M.
int m = 5;
int n = 5;
int limit = m * n;
int[][] M = new int[m][n];
public void spiral(int[][] M, int row, int col, int c, int start, int m, int n) {
if (c > limit | row >= m | col >= n)
return;
if (M[row][col] == 0)
M[row][col] = c;
if (row == start) // go right
spiral(M, row, col + 1, c + 1, start, m, n);
if (col == n - 1) // go down
spiral(M, row + 1, col, c + 1, start, m, n);
if (row == m - 1 && col > start) // go left
spiral(M, row, col - 1, c + 1, start, m, n);
if (col == start && row >= start) // go up
spiral(M, row - 1, col, c + 1, start, m, n);
};
spiral(M, 0, 0, 1, 0, m, n);
for (int i = m - 1, x = 1, j = n - 1; i >= m - 2 && j >= n - 2; i--, j--, x++)
spiral(M, x, x, M[x][x - 1] + 1, x, i, j);
This would give you spiral Matrix M
Output:
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
Then create a spiral matrix for characters using matrix M
String string = "hello_world_its_beautiful";
char[][] C = new char[size][size];
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++)
C[i][j] = string.charAt(M[i][j] - 1);
}
Output:
h e l l o
_ b e a _
s u l u w
t f i t o
i _ d l r
When can't go straight turn left to walk, this is the theory used in this solution
int dr[] = {0, 1, 0, -1};
int dc[] = {1, 0, -1, 0};
this is used for always move pattern. And curr & curc represent current position and curm represent current move pattern.
public int[][] solve(int r, int c, String s) {
int m[][] = new int[5][5];
int curr = 0, curc = 0;
for (int pos = 0, curm = 0; pos < r*c; pos++) {
m[curr][curc] = (int) s.charAt(pos);
if (curr + dr[curm] < 0 || curr + dr[curm] >= r || curc + dc[curm] < 0 || curc + dc[curm] >= c
|| m[curr + dr[curm]][curc + dc[curm]] != 0)
curm = (curm + 1) % 4;
curr = curr + dr[curm];
curc = curc + dc[curm];
}
return m;
}
Then you can print this way
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
System.out.printf("%c ", m[i][j]);
}
System.out.println("");
}
I need to design an algorithm to find the maximum value I can get from (stepping) along an int[] at predefined (step lengths).
Input is the number of times we can "use" each step length; and is given by n2, n5 and n10. n2 means that we move 2 spots in the array, n5 means 5 spots and n10 means 10 spots. We can only move forward (from left to right).
The int[] contains the values 1..5, the size of the array is (n2*2 + n5*5 + n10*10). The starting point is int[0].
Example: we start at int[0]. From here we can move to int[0+2] == 3, int[0+5] == 4 or int[0+10] == 1. Let's move to int[5] since it has the highest value. From int[5] we can move to int[5+2], int[5+5] or int[5+10] etc.
We should move along the array in step lengths of 2, 5 or 10 (and we can only use each step length n2-, n5- and n10-times) in such a manner that we step in the array to collect as high sum as possible.
The output is the maximum value possible.
public class Main {
private static int n2 = 5;
private static int n5 = 3;
private static int n10 = 2;
private static final int[] pokestops = new int[n2 * 2 + n5 * 5 + n10 * 10];
public static void main(String[] args) {
Random rand = new Random();
for (int i = 0; i < pokestops.length; i++) {
pokestops[i] = Math.abs(rand.nextInt() % 5) + 1;
}
System.out.println(Arrays.toString(pokestops));
//TODO: return the maximum value possible
}
}
This is an answer in pseudocode (I didn't run it, but it should work).
fill dp with -1.
dp(int id, int 2stepcount, int 5stepcount, int 10stepcount) {
if(id > array_length - 1) return 0;
if(dp[id][2stepcount][5stepcount][10stepcount] != -1) return dp[id][2stepcount][5stepcount][10stepcount];
else dp[id][2stepcount][5stepcount][10stepcount] = 0;
int 2step = 2stepcount < max2stepcount? dp(id + 2, 2stepcount + 1, 5stepcount, 10stepcount) : 0;
int 5step = 5stepcount < max5stepcount? dp(id + 5, 2stepcount, 5stepcount + 1, 10stepcount) : 0;
int 10step = 10stepcount < max10stepcount? dp(id + 10, 2stepcount, 5stepcount, 10stepcount + 1) : 0;
dp[id][2stepcount][5stepcount][10stepcount] += array[id] + max(2step, 5step, 10step);
return dp[id][2stepcount][5stepcount][10stepcount];
}
Call dp(0,0,0,0) and the answer is in dp[0][0][0][0].
If you wanna go backwards, then you do this:
fill dp with -1.
dp(int id, int 2stepcount, int 5stepcount, int 10stepcount) {
if(id > array_length - 1 || id < 0) return 0;
if(dp[id][2stepcount][5stepcount][10stepcount] != -1) return dp[id][2stepcount][5stepcount][10stepcount];
else dp[id][2stepcount][5stepcount][10stepcount] = 0;
int 2stepForward = 2stepcount < max2stepcount? dp(id + 2, 2stepcount + 1, 5stepcount, 10stepcount) : 0;
int 5stepForward = 5stepcount < max5stepcount? dp(id + 5, 2stepcount, 5stepcount + 1, 10stepcount) : 0;
int 10stepForward = 10stepcount < max10stepcount? dp(id + 10, 2stepcount, 5stepcount, 10stepcount + 1) : 0;
int 2stepBackward = 2stepcount < max2stepcount? dp(id - 2, 2stepcount + 1, 5stepcount, 10stepcount) : 0;
int 5stepBackward = 5stepcount < max5stepcount? dp(id - 5, 2stepcount, 5stepcount + 1, 10stepcount) : 0;
int 10stepBackward = 10stepcount < max10stepcount? dp(id - 10, 2stepcount, 5stepcount, 10stepcount + 1) : 0;
dp[id][2stepcount][5stepcount][10stepcount] += array[id] + max(2stepForward, 5stepForward, 10stepForward, 2stepBackward, 5backForward, 10backForward);
return dp[id][2stepcount][5stepcount][10stepcount];
}
But your paths don't get fulled explored, because we stop if the index is negative or greater than the array size - 1, you can add the wrap around functionality, I guess.
this is a solution but i am not sure how optimal it is !
i did some optimization on it but i think much more can be done
I posted it with the example written in question
import java.util.Arrays;
import java.util.Random;
public class FindMax {
private static int n2 = 5;
private static int n5 = 3;
private static int n10 = 2;
private static final int[] pokestops = new int[n2 * 2 + n5 * 5 + n10 * 10];
public static int findMaxValue(int n2, int n5, int n10, int pos, int[] pokestops) {
System.out.print("|");
if (n2 <= 0 || n5 <= 0 || n10 <= 0) {
return 0;
}
int first;
int second;
int third;
if (pokestops[pos] == 5 || ((first = findMaxValue(n2 - 1, n5, n10, pos + 2, pokestops)) == 5) || ((second = findMaxValue(n2, n5 - 1, n10, pos + 5, pokestops)) == 5) || ((third = findMaxValue(n2, n5, n10 - 1, pos + 10, pokestops)) == 5)) {
return 5;
}
return Math.max(Math.max(Math.max(first, second), third), pokestops[pos]);
}
public static void main(String[] args) {
Random rand = new Random();
for (int i = 0; i < pokestops.length; i++) {
pokestops[i] = Math.abs(rand.nextInt() % 5) + 1;
}
System.out.println(Arrays.toString(pokestops));
//TODO: return the maximum value possible
int max = findMaxValue(n2, n5, n10, 0, pokestops);
System.out.println("");
System.out.println("Max is :" + max);
}
}
You need to calculate following dynamic programming dp[c2][c5][c10][id] - where c2 is number of times you've stepped by 2, c5 - by 5, c10 - by 10 and id - where is your current position. I will write example for c2 and c5 only, it can be easily extended.
int[][][][] dp = new int[n2 + 1][n5 + 1][pokestops.length + 1];
for (int[][][] dp2 : dp) for (int[][] dp3 : dp2) Arrays.fill(dp3, Integer.MAX_VALUE);
dp[0][0][0] = pokestops[0];
for (int c2 = 0; c2 <= n2; c2++) {
for (int c5 = 0; c5 <= n5; c5++) {
for (int i = 0; i < pokestops.length; i++) {
if (c2 < n2 && dp[c2 + 1][c5][i + 2] < dp[c2][c5][i] + pokestops[i + 2]) {
dp[c2 + 1][c5][i + 2] = dp[c2][c5][i] + pokestops[i + 2];
}
if (c5 < n5 && dp[c2][c5 + 1][i + 5] < dp[c2][c5][i] + pokestops[i + 5]) {
dp[c2][c5 + 1][i + 5] = dp[c2][c5][i] + pokestops[i + 5];
}
}
}
}
I know the target language is java, but I like pyhton and conversion will not be complicated.
You can define a 4-dimensional array dp where dp[i][a][b][c] is the maximum value that you can
get starting in position i when you already has a steps of length 2, b of length 5 and c of length
10. I use memoization to get a cleaner code.
import random
values = []
memo = {}
def dp(pos, n2, n5, n10):
state = (pos, n2, n5, n10)
if state in memo:
return memo[state]
res = values[pos]
if pos + 2 < len(values) and n2 > 0:
res = max(res, values[pos] + dp(pos + 2, n2 - 1, n5, n10))
if pos + 5 < len(values) and n5 > 0:
res = max(res, values[pos] + dp(pos + 5, n2, n5 - 1, n10))
if pos + 10 < len(values) and n10 > 0:
res = max(res, values[pos] + dp(pos + 10, n2, n5, n10 - 1))
memo[state] = res
return res
n2, n5, n10 = 5, 3, 2
values = [random.randint(1, 5) for _ in range(n2*2 + n5*5 + n10*10)]
print dp(0, n2, n5, n10)
Suspiciously like homework. Not tested:
import java.util.Arrays;
import java.util.Random;
public class Main {
private static Step[] steps = new Step[]{
new Step(2, 5),
new Step(5, 3),
new Step(10, 2)
};
private static final int[] pokestops = new int[calcLength(steps)];
private static int calcLength(Step[] steps) {
int total = 0;
for (Step step : steps) {
total += step.maxCount * step.size;
}
return total;
}
public static void main(String[] args) {
Random rand = new Random();
for (int i = 0; i < pokestops.length; i++) {
pokestops[i] = Math.abs(rand.nextInt() % 5) + 1;
}
System.out.println(Arrays.toString(pokestops));
int[] initialCounts = new int[steps.length];
for (int i = 0; i < steps.length; i++) {
initialCounts[i] = steps[i].maxCount;
}
Counts counts = new Counts(initialCounts);
Tree base = new Tree(0, null, counts);
System.out.println(Tree.max.currentTotal);
}
static class Tree {
final int pos;
final Tree parent;
private final int currentTotal;
static Tree max = null;
Tree[] children = new Tree[steps.length*2];
public Tree(int pos, Tree parent, Counts counts) {
this.pos = pos;
this.parent = parent;
if (pos < 0 || pos >= pokestops.length || counts.exceeded()) {
currentTotal = -1;
} else {
int tmp = parent == null ? 0 : parent.currentTotal;
this.currentTotal = tmp + pokestops[pos];
if (max == null || max.currentTotal < currentTotal) max = this;
for (int i = 0; i < steps.length; i++) {
children[i] = new Tree(pos + steps[i].size, this, counts.decrement(i));
// uncomment to allow forward-back traversal:
//children[2*i] = new Tree(pos - steps[i].size, this, counts.decrement(i));
}
}
}
}
static class Counts {
int[] counts;
public Counts(int[] counts) {
int[] tmp = new int[counts.length];
System.arraycopy(counts, 0, tmp, 0, counts.length);
this.counts = tmp;
}
public Counts decrement(int i) {
int[] tmp = new int[counts.length];
System.arraycopy(counts, 0, tmp, 0, counts.length);
tmp[i] -= 1;
return new Counts(tmp);
}
public boolean exceeded() {
for (int count : counts) {
if (count < 0) return true;
}
return false;
}
}
static class Step {
int size;
int maxCount;
public Step(int size, int maxCount) {
this.size = size;
this.maxCount = maxCount;
}
}
}
There's a line you can uncomment to allow forward and back movement (I'm sure someone said in the comments that was allowed, but now I see in your post it says forward only...)
Here is my part of code. I am looking for a way to reduce the redundancy to get red, green, and blue by three big parts but looks like similar calculation. Is any better way to make it work? For loop? or any idea? Is anyone can give me an idea? please!!!!! Thank you!!!
for(int row = 1; row < pi.getHeight() - 1; row++) {
for(int col = 1; col < pi.getWidth() - 1; col++) {
int red_P_C = 4 * data[row][col].red;
int red_P_1 = 1 * data[row-1][col-1].red;
int red_P_2 = 2 * data[row-1][col].red;
int red_P_3 = 1 * data[row-1][col+1].red;
int red_P_4 = 2 * data[row][col-1].red;
int red_P_5 = 2 * data[row][col+1].red;
int red_P_6 = 1 * data[row+1][col-1].red;
int red_P_7 = 2 * data[row+1][col].red;
int red_P_8 = 1 * data[row+1][col+1].red;
int redTotal = red_P_C + red_P_1 + red_P_2 + red_P_3 + red_P_4 + red_P_5 + red_P_6 + red_P_7 + red_P_8;
int redActual = redTotal/16;
int g_P_C = 4 * data[row][col].green;
int g_P_1 = data[row-1][col-1].green;
int g_P_2 = 2 * data[row-1][col].green;
int g_P_3 = data[row-1][col+1].green;
int g_P_4 = 2 * data[row][col-1].green;
int g_P_5 = 2 * data[row][col+1].green;
int g_P_6 = data[row+1][col-1].green;
int g_P_7 = 2 * data[row+1][col].green;
int g_P_8 = data[row+1][col+1].green;
int gTotal = g_P_C + g_P_1 + g_P_2 + g_P_3 + g_P_4 + g_P_5 + g_P_6 + g_P_7 + g_P_8;
int gActual = gTotal/16;
int blu_P_C = data[row][col].blue * 4;
int blu_P_1 = data[row-1][col-1].blue;
int blu_P_2 = 2 * data[row-1][col].blue;
int blu_P_3 = data[row-1][col+1].blue;
int blu_P_4 = 2 * data[row][col-1].blue;
int blu_P_5 = 2 * data[row][col+1].blue;
int blu_P_6 = data[row+1][col-1].blue;
int blu_P_7 = 2 * data[row+1][col].blue;
int blu_P_8 = data[row+1][col+1].blue;
int bluTotal = blu_P_C + blu_P_1 + blu_P_2 + blu_P_3 + blu_P_4 + blu_P_5 + blu_P_6 + blu_P_7 + blu_P_8;
int bluActual = bluTotal/16;
newData[row][col].red = redActual;
newData[row][col].green = gActual;
newData[row][col].blue = bluActual;
You can make an array of naybor offsets. Simplified:
int[][] nayborOffsets = new int[][] {
{ -1, -1 }, { 0, -1 }, { 1, -1 },
{ -1, 0 }, { 1, 0},
{ -1, 1 }, { 0, 1 }, { 1, 1 }
};
MyColor[] nayborRGBs = new MyColor[nayborOffsets.length];
for (int i = 0; i < nayborOffsets.length; ++i) {
int[] offsets = nayborOffsets[i];
nayborRGBs[i] = data[row + offsets[0]][col + offsets[1]];
}
where MyColor should be the class of a data element.
You could try to refactor the parts for red, green, blue to something like this:
Note: RGB refers to your unspecified type of data
public int getActualSubPixel(/*this*/ RGB[][] data, int subPixelType, int row, int col) {
int P_C = 4 * getSubPixel(data[row][col], subPixelType);
int P_1 = getSubPixel(data[row - 1][col - 1], subPixelType);
int P_2 = 2 * getSubPixel(data[row - 1][col], subPixelType);
int P_3 = getSubPixel(data[row - 1][col + 1], subPixelType);
int P_4 = 2 * getSubPixel(data[row][col - 1], subPixelType);
int P_5 = 2 * getSubPixel(data[row][col + 1], subPixelType);
int P_6 = getSubPixel(data[row + 1][col - 1], subPixelType);
int P_7 = 2 * getSubPixel(data[row + 1][col], subPixelType);
int P_8 = getSubPixel(data[row + 1][col + 1], subPixelType);
int Total = P_C + P_1 + P_2 + P_3 + P_4 + P_5 + P_6 + P_7 + P_8;
int Actual = Total / 16;
return Actual;
}
//possible member method
public int getSubPixel(/*this*/ RGB rgb, int subPixelType) {
switch (subPixelType) {
case 0:
return rgb.red;
case 1:
return rgb.green;
case 2:
return rgb.blue;
default:
throw new IllegalArgumentException();
}
}
//possible member method
public void setSubPixel(/*this*/ RGB rgb, int subPixelType, int value) {
switch (subPixelType) {
case 0:
rgb.red = value;
return;
case 1:
rgb.green = value;
return;
case 2:
rgb.blue = value;
return;
default:
throw new IllegalArgumentException();
}
}
Then call it in your code:
for (int row = 1; row < pi.getHeight() - 1; row++) {
for (int col = 1; col < pi.getWidth() - 1; col++) {
for (int i = 0; i < 3; i++) {
setSubPixel(newData[row][col], i, getActualSubPixel(data, i, row, col));
}
}
}
Recently learned about Cramers rule in precalculus, and decided to make an algorithm in Java to help me understand it better.
The following code works 100% correctly, however it does not use any sort of for loop to do what it does in a much simpler fashion.
Question: Is there a more elegant implementation of Cramers Rule in Java?
I'm thinking that making a basic determinant method, and then doing some column swapping for when I need to take the determinant of Dx, Dy, and Dz. (for Dx, swap column 4 with column 1 of the original matrix, then take determinant and divide by original determinant.)
This sound good?
public static void main(String[] args) {
int[][] matrix = new int[3][3];
matrix[0] = new int[] { 3, 5, -1, -2 };
matrix[1] = new int[] { 1, -4, 2, 13 };
matrix[2] = new int[] { 2, 4, 3, 1 };
int[] r = crame(matrix);
info("x: " + r[0] + ", y: " + r[1] + ", z: " + r[2]);
for(int i = 0; i < matrix.length; i++) {
int[] base = matrix[i];
if(check(base, r, base[3])) {
info("System " + (i+1) + " checks!");
} else {
info("System " + (i+1) + " fails check!");
}
}
}
public static int[] crame(int[][] m) {
int[] result;
if (m.length == 2) {
result = new int[2];
int D = (m[0][0] * m[1][1]) - (m[1][0] * m[0][1]);
int Dx = (m[0][2] * m[1][1]) - (m[1][2] * m[0][1]);
int Dy = (m[0][0] * m[1][2]) - (m[1][0] * m[0][2]);
result[0] = (int) (Dx / D);
result[1] = (int) (Dy / D);
} else if (m.length == 3) {
result = new int[3];
int D = (((m[0][2] * m[1][1] * m[0][2]) + (m[2][1] * m[1][2] * m[0][0]) + (m[2][2]
* m[1][0] * m[0][2])) - ((m[0][0] * m[1][1] * m[2][2])
+ (m[0][1] * m[1][2] * m[0][2]) + (m[0][2] * m[1][0] * m[2][1])));
int Dx = (((m[2][3] * m[1][1] * m[0][2]) + (m[2][1] * m[1][2] * m[0][3]) + (m[2][2]
* m[1][3] * m[0][1])) - ((m[0][3] * m[1][1] * m[2][2])
+ (m[0][1] * m[1][2] * m[2][3]) + (m[0][2] * m[1][3] * m[2][1])));
int Dy = (((m[2][0] * m[1][3] * m[0][2]) + (m[2][3] * m[1][2] * m[0][3]) + (m[2][2]
* m[1][0] * m[0][3])) - ((m[0][0] * m[1][3] * m[2][2])
+ (m[0][3] * m[1][2] * m[2][0]) + (m[0][2] * m[1][0] * m[2][3])));
int Dz = (((m[2][0] * m[1][1] * m[0][3]) + (m[2][1] * m[1][3] * m[0][0]) + (m[2][3]
* m[1][0] * m[0][1])) - ((m[0][0] * m[1][1] * m[2][3])
+ (m[0][1] * m[1][3] * m[2][0]) + (m[0][3] * m[1][0] * m[2][1])));
result[0] = (int) (Dx / D);
result[1] = (int) (Dy / D);
result[2] = (int) (Dz / D);
} else {
return new int[] {};
}
return result;
}
public static int product(int[] a, int[] b) {
int p = 0;
int[] fin = new int[(a.length -1)];
for(int x = 0; x < fin.length; x++) {
fin[x] = a[x] * b[x];
}
for (int f : fin) {
p += f;
}
return p;
}
public static boolean check(int[] a, int[] b, int z) {
return product(a, b) == z;
}
public static void info(String log) {
System.out.println(log);
}
My question pertains to the specific algorithm that can be used to solve systems of equations using Cramers rule only, is there any algorithm that is more elegant? The function is only designed for square matrices.
This is not a homework assignment, after HS I will be studying CS and I've been working on developing algorithms as preliminary practice.
Thank you for checking this out
First of, there is one way in which Cramers rule is perfect: It gives the algebraic solution of a linear system as a rational function in its coefficients.
However, practically, it has its limits. While the most perfect formula for a 2x2 system, and still good for a 3x3 system, its performance, if implemented in the straightforward way, deteriorates with each additional dimension.
An almost literal implementation of Cramers rule can be achieved with the Leverrier-Faddeev algorithm a b. It only requires the computation of matrix products and matrix traces, and manipulations of the matrix diagonal. Not only does it compute the determinant of the matrix A (along with the other coefficients of the characteristic polynomial), it also has the adjugate or co-factor matrix A# in its iteration matrix. The interesting fact about this matrix is that it allows to write the solution of A*x=b as (A#*b)/det(A), that is, the entries of A#*b already are the other determinants required by Cramers rule.
Leverrier-Faddeev requires n4+O(n3) operations. The same results can be obtained by the more complicated Samuelson-Berkowitz algorith, which has one third of that complexity, that is n4/3+O(n3).
The computation of the determinants required in Cramers rule becomes downright trivial if the system (A|b) is first transformed into triangular form. That can be achieved by Gauß elimination, aka LU decomposition (with pivoting for numerical stability) or the QR decomposition (easiest to debug should be the variant with Givens rotations). The efficient application of Cramers rule is then backward substitution in the triangular system.
Your method sounds good to me at least; however, I just may not be aware of any more efficient methods. The not-fun part may be figuring out how to best implement the determinant-calculating method, as apparently it's not an inexpensive operation.
But once you know that that's working, the rest sounds pretty OK to me. Cache the determinant of the original matrix, substitute in columns, etc.
Figured out exactly how to do this effectively.
http://sandsduchon.org/duchon/math/determinantJava.html
Provides a method for seamless determinants, and mentions matrix decomposition. I have not learned this yet as it's not a HS level concept however I did some problems using it and it's a solid method.
Final Code:
public static void main(String[] args) {
int[][] matrix = new int[3][3];
matrix[0] = new int[] { 3, 5, -1, -2 };
matrix[1] = new int[] { 1, -4, 2, 13 };
matrix[2] = new int[] { 2, 4, 3, 1 };
int[] r = crame(matrix);
info("x: " + r[0] + ", y: " + r[1] + ", z: " + r[2]);
for (int i = 0; i < matrix.length; i++) {
int[] base = matrix[i];
if (check(base, r, base[3])) {
info("System " + (i + 1) + " checks!");
} else {
info("System " + (i + 1) + " fails check!");
}
}
}
public static int getDet(int[][] a) {
int n = a.length - 1;
if (n < 0)
return 0;
int M[][][] = new int[n + 1][][];
M[n] = a; // init first, largest, M to a
// create working arrays
for (int i = 0; i < n; i++)
M[i] = new int[i + 1][i + 1];
return getDet(M, n);
} // end method getDecDet double [][] parameter
public static int getDet(int[][][] M, int m) {
if (m == 0)
return M[0][0][0];
int e = 1;
// init subarray to upper left mxm submatrix
for (int i = 0; i < m; i++)
for (int j = 0; j < m; j++)
M[m - 1][i][j] = M[m][i][j];
int sum = M[m][m][m] * getDet(M, m - 1);
// walk through rest of rows of M
for (int i = m - 1; i >= 0; i--) {
for (int j = 0; j < m; j++)
M[m - 1][i][j] = M[m][i + 1][j];
e = -e;
sum += e * M[m][i][m] * getDet(M, m - 1);
} // end for each row of matrix
return sum;
} // end getDecDet double [][][], int
public static int[] crame(int[][] m) {
int[] result;
if (m.length == 2) {
result = new int[m.length];
int D = getDet(m);
for (int i = 0; i < m.length; i++) {
result[i] = getDet(slide(m, i, m.length)) / D;
}
} else if (m.length == 3) {
result = new int[m.length];
int D = getDet(m);
for (int i = 0; i < m.length; i++) {
result[i] = (getDet(slide(m, i, m.length)) / D);
}
} else {
return new int[] {};
}
return result;
}
public static int[][] slide(int[][] base, int col, int fin) {
int[][] copy = new int[base.length][];
for (int i = 0; i < base.length; i++) {
int[] aMatrix = base[i];
int aLength = aMatrix.length;
copy[i] = new int[aLength];
System.arraycopy(aMatrix, 0, copy[i], 0, aLength);
}
for (int i = 0; i < base.length; i++) {
copy[i][col] = base[i][fin];
}
return copy;
}
public static int product(int[] a, int[] b) {
int p = 0;
int[] fin = new int[(a.length - 1)];
for (int x = 0; x < fin.length; x++) {
fin[x] = a[x] * b[x];
}
for (int f : fin) {
p += f;
}
return p;
}
public static boolean check(int[] a, int[] b, int z) {
return product(a, b) == z;
}
public static void info(String log) {
System.out.println(log);
}
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();
}
}