The following code finds the correct hamiltonian cycle for a knight in a chessboard when started on position 0 0 in a 10x10 or 8x8 chessboard but throws a NullPointerException when started anywhere else.
Input here should be
8
8
0
0
for the hamiltonian cycle on a 8x8 chessboard starting in position 0 0, which runs the correct output:
1 16 27 22 3 18 29 32
26 23 2 17 28 31 4 19
15 64 25 36 21 50 33 30
24 37 48 61 56 35 20 5
47 14 63 38 49 60 51 34
42 39 44 57 62 55 6 9
13 46 41 54 11 8 59 52
40 43 12 45 58 53 10 7
on
8
8
1
1
I get:
Exception in thread "main" java.lang.NullPointerException
at horseBETA.mover(horseBETA.java:55)
at horseBETA.search(horseBETA.java:130)
at horseBETA.main(horseBETA.java:164)
Java Result: 1
Why?
import java.util.Scanner;
/**
*
* #author Darwin Martinez
*/
class position{
int x,y;
position() {};
position(int a, int b) { x=a; y=b; }
}
public class horseBETA {
static int number_of_movements = 8;
static int dx[] = {-1, -2, -2, -1, 1, 2, 2, 1};
static int dy[] = {-2, -1, 1, 2, 2, 1, -1, -2};
static int longCycle;
static int N,M,I,J;
static int[][] order;
position solucion[];
static boolean free[][];
static int longitud;
static int dfs_visited[][],stampdfs;
horseBETA(int N, int M, int I, int J) {
longCycle = N*M;
order = new int[N][M];
solucion = new position[longCycle];
free = new boolean [N][M];
dfs_visited = new int[N][M];
for (int i=0;i<N;i++)
for (int j=0;j<M;j++) {
free[i][j] = true;
dfs_visited[i][j] = 0;
}
stampdfs = 0;
position aux=new position(I,J);
int index=(I*N)+J;
solucion[index]=aux;
free[I][J] = false;
longitud = 1;
}
boolean valida(position p) {
return 0<=p.x && p.x<N &&
0<=p.y && p.y<M && free[p.x][p.y];
}
position mover(position p,int i) {
return new position(p.x+dx[i],p.y+dy[i]);
}
boolean es_terminal() {
return longitud == longCycle;
}
boolean is_factible(position p) {
return ((p.x == I+dx[0] && p.y == J+dy[0]) || (p.x == I+dx[1] && p.y == J+dy[1])
|| (p.x == I+dx[2] && p.y == J+dy[2])|| (p.x == I+dx[3] && p.y == J+dy[3])
|| (p.x == I+dx[4] && p.y == J+dy[4])|| (p.x == I+dx[5] && p.y == J+dy[5])
|| (p.x == I+dx[6] && p.y == J+dy[6])|| (p.x == I+dx[7] && p.y == J+dy[7]));
}
boolean prometedor_recurs(position d) {
if (is_factible(d)) return true;
for (int i=0;i<number_of_movements;i++) {
position a = mover(d,i);
if (valida(a) && dfs_visited[a.x][a.y] != stampdfs) {
dfs_visited[a.x][a.y] = stampdfs;
if (prometedor_recurs(a)) return true;
}
}
return false;
}
boolean promising(position d) {
stampdfs++;
return prometedor_recurs(d);
}
void print_solution() {
for (int i=0;i<longCycle;i++)
order[solucion[i].x][solucion[i].y] = i+1;
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if(order[i][j]<10)
System.out.print(" "+order[i][j]);
else{
if(order[i][j]>=10&&order[i][j]<100)
System.out.print(" "+order[i][j]);
else
System.out.print(" "+order[i][j]);
}
}System.out.print("\n");
}
System.exit(0);
}
void insertionSort(position p[], int r[], int n) {
int i,j,aux;
position auxp;
for (i=1; i<n; i++) {
aux=r[i]; auxp = p[i];
for (j=i-1; j>=0 && aux<r[j]; j--) {
r[j+1]=r[j]; p[j+1]=p[j];
}
r[j+1]=aux; p[j+1] = auxp;
}
}
public boolean search() {
if (es_terminal()) {
if (is_factible(solucion[longCycle-1])){
print_solution();
return true;
}
} else {
int nchildren = 0;
position p[]=new position[number_of_movements];
int r[]=new int[number_of_movements];
for (int i=0;i<number_of_movements;i++) {
position a = mover(solucion[longitud-1],i);
if (valida(a)) {
int grado = 0;
for (int j=0;j<number_of_movements;j++)
if (valida(mover(a,j)))
grado++;
p[nchildren] = a;
r[nchildren] = grado;
nchildren++;
}
}
insertionSort(p,r,nchildren);
for (int i=0; i<nchildren; i++) {
solucion[longitud] = p[i]; longitud++;
free[p[i].x][p[i].y] = false;
if (promising(p[i]))
search();
free[p[i].x][p[i].y] = true;
longitud--;
}
}return false;
}
public static void main(String[] args) {
Scanner x= new Scanner(System.in);
N = x.nextInt();
M = x.nextInt();
I = x.nextInt();
J = x.nextInt();
horseBETA yy = new horseBETA(N,M,I,J);
if(!yy.search())
System.out.println("\nNo hay solucion");
}
}
Here is a HINT to get you started:
Start with the stacktrace. The first line of the trace says:
at horseBETA.mover(horseBETA.java:55)
This means that the exception occurred in the mover method, and that method consists of just one line:
return new position(p.x+dx[i],p.y+dy[i]);
A NPE is thrown when an attempt is made to dereference a null reference. There are 4 sub-expressions in the line above where object references are dereferenced, and NPEs could possibly occur.
p.x and p.y could throw an NPE if p is null.
dx[i] or dy[i] could throw an NPE if (respectively) dx and dy are null.
Two out of four of those possible causes can be excluded by simple inspection of the code; dx and dy are initialized to non-null values and then never assigned to. That leaves p being null as the probable cause. (You could confirm this with a traceprint or using a debugger.)
Now over to you ...
(I also agree with #Speck. You've got some serious style problems with your code which make it painful to read and hard to debug ... )
First, your code is illegible. If you use accepted style guidelines it will help when debugging.
A couple of things to help improve:
Use names not letters for variables and favor camelCaseVariables. These will help with readability especially when asking a question like this.
Use open and close brackets even for one lined if statements and loops. It will better set off loops and make them more readable and helps prevent bugs in program flow.
Anyway, you may be passing a null position object (capitalize your class names btw) to the mover method. In your IDE, set a breakpoint on that line and make it conditional to stop only when the passed pointer object is null. You'll quickly see why.
Related
I am using binary search to find a balance point between the planets. The method binaryBalance takes in Arraylist of planets which is an object with displacement and mass property. It also takes in the displacement of two planets between which I am trying to find a balance point of. Double x is the inital starting point of the search and I am setting the average displacement of p1 and p2 here. The code runs smoothly but it is off the answer for a minute amount. I try to increase the precision by setting the error interval to more than 1e-10, but I keep getting Stack Overflow error. How do I solve this problem with higher precision?
import java.util.*;
import java.lang.*;
public class Solution {
public static void main(String[] arg) {
Scanner sc = new Scanner(System.in);
int numCase = sc.nextInt();
for (int k = 1; k <= numCase; k++) {
//Initializing Space...
int numPlanets = sc.nextInt();
ArrayList<Planet> space = new ArrayList<>();
int[] weights = new int[numPlanets];
int[] displacements = new int[numPlanets];
for (int i = 0; i < numPlanets; i++) {
displacements[i] = sc.nextInt();
}
for (int i = 0; i < numPlanets;i++) {
weights[i] = sc.nextInt();
}
for (int i = 0; i < numPlanets;i++) {
Planet p = new Planet(displacements[i],weights[i]);
space.add(p);
}
System.out.print("#" + k + " ");
for (int i = 0; i < numPlanets-1; i++) {
double init = (double) (space.get(i).getDisplacement() + space.get(i+1).getDisplacement()) /2;
binaryBalance(space,space.get(i).getDisplacement(),space.get(i+1).getDisplacement(),init);
}
System.out.println();
}
}
public static class Planet {
private int d;
private int m;
public Planet(int d,int m) {
this.d = d;
this.m = m;
}
public void setDisplacement(int d) {
this.d = d;
}
public void setMass(int m) {
this.m = m;
}
public double getG(double dPlanet) {
double betweenDistance = this.d - dPlanet;
return this.m/(betweenDistance*betweenDistance);
}
public int getDisplacement() {
return d;
}
public int getMass() {
return m;
}
}
public static void binaryBalance(ArrayList<Planet> space, double p1, double p2, double x) {
double leftg = 0;
double rightg = 0;
for (int i = 0; i < space.size(); i++) {
if (space.get(i).getDisplacement() < x) {
leftg = leftg + space.get(i).getG(x);
} else {
rightg = rightg + space.get(i).getG(x);
}
}
if (Math.abs(leftg - rightg) < 1e-10) {
System.out.print(String.format("%.10f",x) + " ");
return;
}
if (leftg < rightg) {
binaryBalance(space, p1, x, (p1 + x) / 2);
} else {
binaryBalance(space, x, p2, (p2 + x) / 2);
}
}
Test Cases are:
10
2
1 2 1 1
2
1 2 1 1000
2
457 468 333 321
3
1 2 3 1 2 1
4
2 3 5 7 3 2 7 5
5
3 11 12 19 29 542 661 450 521 366
6
42 75 88 94 113 144 669 551 355 344 294 155
7
62 86 279 323 363 516 579 810 749 736 297 136 107 52
8
10 34 64 73 93 97 101 122 466 463 441 373 315 292 225 83
10
9 14 38 39 48 73 179 190 207 302 560 497 640 722 437 259 449 470 709 520
And the expected answer is:
#1 1.5000000000
#2 1.0306534300
#3 462.5504629633
#4 1.4060952085 2.5939047915
#5 2.5328594461 3.7271944335 6.0999536409
#6 6.3428568767 11.5477377494 15.9641592998 24.9267991615
#7 57.8805685415 81.8651598883 91.0573691382 105.0835650491 133.2934094881
#8 74.2211477711 190.6837563313 305.8269181686 348.3304429927 470.2694219293 555.4943093854
#9 21.5171374463 47.9890597763 68.6536668433 82.9131954023 95.0052272762 99.1999097770 116.4978330953
#10 11.5573600056 24.0238341337 38.4847676134 44.6137453708 64.7500445424 126.9908128982 184.3221650927 197.9760596291 266.0574653677
With the leftg-rightg tolerance of 1e-10, the greatest number of iterations is 47, on the second case where the masses are so different. That won't overflow any stacks, but of course you asked about increasing the accuracy. Unfortunately, it's impossible to even reach 1e-11 on case 6, because of the scale of the numbers involved (as I mentioned in a comment). So you get infinite recursion if you change the tolerance exponent at all.
But maybe a fixed balance tolerance isn't what you're expected to do for this exercise! I get exactly the expected answers (to their given precision) if I instead refine until the interval has "zero" width. (p1 and p2 need not be equal, but there are no floating-point numbers between them. You detect this by noticing that x==p1 || x==p2; x will be whichever ends in a 0 in binary.) This takes at most 53 bisections for these cases: a number which should be familiar to any numerical analyst since it is the effective number of bits in the significand of a double. I didn't check whether a larger p2-p1 tolerance might give the correct answers.
Since it's useless to get (much) above 53 levels deep, the choice of recursion here is harmless (although tail recursion with a void function looks very odd), and changing to iteration won't help at all. Either way, you do have to make sure that it terminates!
Try to use iteration instead of recursion. I also added line with logging of data on each iteration.
public static void binaryBalance(ArrayList<Planet> space, double p1, double p2, double x) {
while(true) {
//You can use this line to log evolution of your data
System.out.println(String.format("p1=%s p2=%s x=%s", p1, p2, x));
double leftg = 0;
double rightg = 0;
for (int i = 0; i < space.size(); i++) {
if (space.get(i).getDisplacement() < x) {
leftg = leftg + space.get(i).getG(x);
} else {
rightg = rightg + space.get(i).getG(x);
}
}
if (Math.abs(leftg - rightg) < 1e-10) {
System.out.print(String.format("%.10f",x) + " ");
return;
}
double p1Tmp = p1;
double p2Tmp = p2;
double xTmp = x;
if (leftg < rightg) {
p1 = p1Tmp;
p2 = xTmp;
x = (p1Tmp + xTmp) / 2;
} else {
p1 = xTmp;
p2 = p2Tmp;
x = (p2Tmp + xTmp) / 2;
}
}
}
I'd would like to implement a check to see if a sudoku is valid in Java, and came across (http://leetcode.tgic.me/valid-sudoku/index.html).
I understand how it is validating rows and columns, but for the 3x3 grids validator:
34 for(x = 0; x < mx; x += 3){
35 for(y = 0; y < my; y += 3){
36
37 HashSet<Character> block = new HashSet<Character>();
38
39 for(int offset = 0; offset < 9; offset++){
40 int ox = offset % 3;
41 int oy = offset / 3;
42
43 char c = board[x + ox][y + oy];
44 if(c != '.'){
45 if(block.contains(c)) return false;
46
47 block.add(c);
48 }
49 }
50 }
51 }
What is offset and how does it help to check every cell in the 3x3 grid? I brute forced it and tried x=0, y=0, offset=0 and offset=1 first, but offset=1 gives int ox = 1%3 = 1; and int oy = 1/3, so the board[0 + 1][0+(1/3)] = board[1][1/3], and what does cell [1/3] represent and so on?
when you divide n by m, both are int's (either literals or variables) the result is also an int, so 1/3 -> 0
Hence when
offset == 0 => ox=0, oy=0
offset == 1 => ox=1, oy=0
offset == 2 => ox=2, oy=0
offset == 3 -> ox=0, oy=1
...
hence you will loop nicely of the 3 rows and 3 columns
Your HashSet approach looks quite good, but needs a little tweaking...
The assumption is: when the first block is duplication free and the same position in all blocks is duplication free too, then the sudoku is solved.
In you outer loop you should go trough the values of the first block only.
You should add the current value to the "first block check set" and check, that the all the blocks have a different number at the same position by an inner loop with its own "check set":
First iteration
1## 2## 3##
### ### ###
### ### ###
4## 5## 5##
### ### ###
### ### ###
7## 8## 9##
### ### ###
### ### ###
firstBlock: [1]
second iteration
#2# #3# #4#
### ### ###
### ### ###
#5# #6# #7#
### ### ###
### ### ###
#8# #9# #1#
### ### ###
### ### ###
firstBlock: [1,2]
The big trick is to avoid separate loops for x and y coordinates.
Since Java is an object oriented programming language I suggest to use objects to determine the coordinates. We could hold them in an Array (set a bookmark,I usually say "Collection" instead...) and iterate ofer it with a simple forech loop...
Also we have to deal with a fix number of objects we know in advance (there a 9 blocks with 9 positions in each...)
so I suggest using Java enums like this:
so you logic should look like this:
public class SudokuCheck {
enum SudokuPosition {
p11(0, 0), p12(0, 1), p13(0, 2),
p21(1, 0), p22(1, 1), p23(1, 2),
p31(2, 0), p32(2, 1), p33(2, 2);
private final int x;
private final int y;
SudokuPosition(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {return x;}
public int getY() {return y;}
}
boolean check(int[][] sudoku) {
Set<Integer> firstBlockUniqueNumbers = new HashSet<>();
for (SudokuPosition inBlock : SudokuPosition.values()) {
firstBlockUniqueNumbers.add(sudoku[inBlock.x][inBlock.y]);
Set<Integer> samePosInOtherBlocksUniqueNumbers = new HashSet<>();
for (SudokuPosition ofBlock : SudokuPosition.values()) {
int sameXinAll = inBlock.x + offset(ofBlock.x);
int sameYinAll = inBlock.y + offset(ofBlock.y);
samePosInOtherBlocksUniqueNumbers.add(sudoku[sameXinAll][sameYinAll]);
}
if (9 > samePosInOtherBlocksUniqueNumbers.size())
// numbers where not unique at current block position
// through all the blocks
return false;
}
return 9 == firstBlockUniqueNumbers.size();
}
private int offset(int xOrY) {
return xOrY * 3;
}
}
I hopefully demonstrated the usefulness of Java enums and how important good identifier names are.
I think this approach could be improved in 2 ways:
using the Java 8 Stream API may replace the forech loops
the names of the position elements somehow repeat their constructor values which may lead to nasty mistakes. The latter may be replaces by some clever calculation on the constant name which is available via name(), but for this demonstration it might be good enough as it is...
the most optimal answer I think will be :
public boolean isValidSudoku(char[][] board) {
if (board == null || board.length == 0) return false;
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
if (board[i][j] == '.') continue;
if (!isValid(board, i, j)) return false;
}
}
return true;
}
public boolean isValid(char[][] board, int row, int col) {
for (int i = 0; i < board.length; i++) {
if (i == row) continue;
if (board[i][col] == board[row][col]) return false;
}
for (int j = 0; j < board[0].length; j++) {
if (j == col) continue;
if (board[row][j] == board[row][col]) return false;
}
for (int i = (row / 3) * 3; i < (row / 3 + 1) * 3; i++) {
for (int j = (col / 3) * 3; j < (col / 3 + 1) * 3; j++) {
if (i == row && j == col) continue;
if (board[i][j] == board[row][col]) return false;
}
}
return true;
}
This program pulls two columns from the input.txt file where the first column indicates the value of the object, and the second column represents the weight. The values are imported and placed into two arrays: the value array and the weight array. The knapsack calculations are then made. There are 23 objects in total represented by the rows of the arrays. My code correctly calculates the total value that is being held in the knapsack, and will print out the correct IDs if the weight capacity entered is 5, but for any other weight the IDs being held in the id array are not correct, but the total value printed out is. Here is my code for both files, and if anyone is able to figure out how to correctly save and print the IDs being held in the knapsack please let me know . . .
input.txt file:
17 5
12 8
15 22
17 11
33 21
43 15
15 4
44 35
23 19
10 23
55 39
8 6
21 9
20 28
20 13
45 29
18 16
21 19
68 55
10 16
33 54
3 1
5 9
knapsack.java file:
//We did borrow concepts from:
//http://www.sanfoundry.com/java-program-solve-knapsack-problem-using-dp/
import java.util.Scanner;
import java.util.*;
import java.lang.*;
import java.io.*;
public class knapsack
{
static int max(int a, int b)
{
if(a > b)
{
//System.out.println(a);
return a;
}
else
//System.out.println(b);
return b;
}
static int knapSack(int maxCapacity, int weight[], int value[], int n)
{
int track = 0;
int i, w;
int foo1 = 0;
int foo2 = 0;
K = new int[n+1][maxCapacity+1];
// Build table K[][] in bottom up manner
for (i = 0; i <= n; i++)
{
for (w = 0; w <= maxCapacity; w++)
{
if (i==0 || w==0)
K[i][w] = 0;
else if (weight[i-1] <= w)
{
//K[i][w] = max(value[i-1] + K[i-1][w-weight[i-1]], K[i-1][w]);
if(value[i-1] + K[i-1][w-weight[i-1]] > K[i-1][w])
{
K[i][w] = value[i-1] + K[i-1][w-weight[i-1]];
//System.out.println("A: "+i);
}
else
{
K[i][w] = K[i-1][w];
id[track++] = i;
//System.out.println("B: "+i);
}
}
else
{
K[i][w] = K[i-1][w];
}
}
//System.out.println(K[foo1][foo2]);
}
return K[n][maxCapacity];
}
public static void main(String args[])throws java.io.FileNotFoundException
{
Scanner sc = new Scanner(System.in);
int n = 23;
File file = new File("input.txt");
Scanner scanner = new Scanner(file);
id = new Integer [n];
//knapval = new int[n];
//knapweight = new int [n];
int []value = new int[n];
int []weight = new int[n];
for(int i=0; i<n; i++)
{
value[i] = scanner.nextInt();
weight[i] = scanner.nextInt();
}
System.out.println("Enter the maximum capacity: ");
int maxCapacity = sc.nextInt();
System.out.println("The maximum value that can be put in a knapsack with a weight capacity of "+maxCapacity+" is: " + knapSack(maxCapacity, weight, value, n));
System.out.println();
System.out.println("IDs Of Objects Held In Knapsack: ");
//System.out.println();
for(int z = 0; z < n && id[z] != null; z++)
{
System.out.println(id[z]);
}
if(id[0] == null)
System.out.println("All objects are too heavy, knapsack is empty.");
sc.close();
scanner.close();
}
protected static Integer [] id;
protected static int [][]K;
}
Your way of recording your solution in the id array is flawed. At the time you do id[track++] = i;, you don’t yet know whether i will be in your final solution. Because of the nested loops you may even add i more than once. This in turn may lead to overflowing the array with a java.lang.ArrayIndexOutOfBoundsException: 23 (this happens for max capacity 12 and above).
I suggest instead of using id, after your solution is complete you track your way backward through the K array (by Java naming conventions, it should be a small k). It holds all the information you need to find out which objects were included in the maximum value.
private static void printKnapsack(int maxCapacity, int weight[], int value[], int n) {
if (K[n][maxCapacity] == 0) {
System.out.println("No objects in knapsack");
} else {
int w = maxCapacity;
for (int i = n; i > 0; i--) {
if (K[i][w] > K[i - 1][w]) { // increased value from object i - 1
System.out.format("ID %2d value %2d weight %2d%n", i, value[i - 1], weight[i - 1]);
// check that value in K agrees with value[i - 1]
assert K[i - 1][w - weight[i - 1]] + value[i - 1] == K[i][w];
w -= weight[i - 1];
}
}
}
}
The above prints the objects backward. Example run:
Enter the maximum capacity:
13
The maximum value that can be put in a knapsack with a weight capacity of 13 is: 36
ID 13 value 21 weight 9
ID 7 value 15 weight 4
If you want the objects in forward order, inside the for loop put them into a list (you may for instance use id from your old attempt), and then print the items from the list in opposite order.
Here is a reference implementation of Line object, my confusion is from line 40 to line 43, the question is, if two lines are different, but the OR results of slope/intercept happens to be the same, will it have any issues (e.g. treat different lines the same because of the same hash values)? Since I think same hash value means the same Line.
If the current implementation for hash value do have the issue I mentioned, appreciate if anyone could help to provide some insights what are good implementation for hash value in my case.
1 public static Line findBestLine(GraphPoint[] points) {
2 Line bestLine = null;
3 HashMap<Line, Integer> line_count = new HashMap<Line, Integer>();
4 for (int i = 0; i < points.length; i++) {
5 for (int j = i + 1; j < points.length; j++) {
6 Line line = new Line(points[i], points[j]);
7 if (!line_count.containsKey(line)) {
8 line_count.put(line, 0);
9 }
10 line_count.put(line, line_count.get(line) + 1);
11 if (bestLine == null ||
12 line_count.get(line) > line_count.get(bestLine)) {
13 bestLine = line;
14 }
15 }
16 }
17 return bestLine;
18 }
19
20 public class Line {
21 private static double epsilon = .0001;
22 public double slope;
23 public double intercept;
24 private boolean infinite_slope = false;
25 public Line(GraphPoint p, GraphPoint q) {
26 if (Math.abs(p.x - q.x) > epsilon) { // if x’s are different
27 slope = (p.y - q.y) / (p.x - q.x); // compute slope
28 intercept = p.y - slope * p.x; // y intercept from y=mx+b
29 } else {
30 infinite_slope = true;
31 intercept = p.x; // x-intercept, since slope is infinite
32 }
33 }
34
35 public boolean isEqual(double a, double b) {
36 return (Math.abs(a - b) < epsilon);
37 }
38
39 #Override
40 public int hashCode() {
41 int sl = (int)(slope * 1000);
42 int in = (int)(intercept * 1000);
43 return sl | in;
44 }
45
46 #Override
47 public boolean equals(Object o) {
48 Line l = (Line) o;
49 if (isEqual(l.slope, slope) && isEqual(l.intercept, intercept)
50 && (infinite_slope == l.infinite_slope)) {
51 return true;
52 }
53 return false;
54 }
55 }
Since I think same hash value means the same Line.
No, it doesn't. This is a common misconception. If two objects have the same hash code, they may be equal - but they don't have to be. You should never treat equal hash codes as proof that two objects are equal.
The hash code used here is definitely poor in various ways, but it is at least valid.
As an extreme example, it's always valid (but almost always unhelpful) to write:
public override int hashCode() {
return 5;
}
That guarantees that objects which are equal will have the same hash code, which is all that's required for correctness. Beyond correctness, ensuring that non-equal objects have different hash codes is a matter of making it efficient to use the type in a hash-based lookup.
I tried to find all possible longest increasing subsequence using recursion. When I tried an input array {10,22,9,33,21,50,41,40,60,55}, it worked and the output was:
10 22 33 40 55 /
10 22 33 41 55 /
10 22 33 50 55 /
10 22 33 40 60 /
10 22 33 41 60 /
10 22 33 50 60 /
But when I tried an input array {2,-3,4,90,-2,-1,-10,-9,-8}, I got an output:
-3 4 90 /
-3 -2 -1 /
-10 -9 -8 /
In this case I didn't get 2 4 90. What should I change in my code to make it word for this case?
public class Main {
public static void main(String[] args) {
int arr[]={10,22,9,33,21,50,41,40,60,55};
int lis[]=new int[arr.length];
for(int i=0;i<arr.length;i++){
lis[i]=1;
}
for(int i=1;i<arr.length;i++){
for(int j=0;j<i;j++){
if(arr[i]>arr[j]&&lis[i]<lis[j]+1){
lis[i]=lis[j]+1;
}
}
}
int max=0;
for(int i=0;i<arr.length;i++){
if(max<lis[i])
max=lis[i];
}
//**************Recursive Print LIS****************
int rIndex=-1;
for(int i=arr.length-1;i>=0;i--){
if(lis[i]==max){
rIndex=i;
break;
}
}
int res[]=new int[max];
printLISRecursive(arr,rIndex,lis,res,max,max);
}
private static void printLISRecursive(int[] arr, int maxIndex, int[] lis, int[] res, int i, int max) {
if(maxIndex<0)return;
if(max==1&&lis[maxIndex]==1&&i==1){
res[i-1]=arr[maxIndex];
// System.out.println("Using Print Recursion:");
for(int j=0;j<res.length;j++){
System.out.print(res[j]+" ");
}
System.out.println();
return;
}
if(lis[maxIndex]==max){
res[i-1]=arr[maxIndex];
printLISRecursive(arr, maxIndex-1, lis, res, i-1, max-1);
}
printLISRecursive(arr, maxIndex-1, lis, res, i, max);
}
}
public static String lcs(String a, String b){
int aLen = a.length();
int bLen = b.length();
if(aLen == 0 || bLen == 0){
return "";
}else if(a.charAt(aLen-1) == b.charAt(bLen-1)){
return lcs(a.substring(0,aLen-1),b.substring(0,bLen-1))
+ a.charAt(aLen-1);
}else{
String x = lcs(a, b.substring(0,bLen-1));
String y = lcs(a.substring(0,aLen-1), b);
return (x.length() > y.length()) ? x : y;
}
}
public static int lcsrec(String x, String y) {
// If one of the strings has one character, search for that character
// in the other string and return the appropriate answer.
if (x.length() == 1)
return find(x.charAt(0), y);
if (y.length() == 1)
return find(y.charAt(0), x);
// Solve the problem recursively.
// Corresponding beginning characters match.
if (x.charAt(0) == y.charAt(0))
return 1+lcsrec(x.substring(1), y.substring(1));
// Corresponding characters do not match.
else
return max(lcsrec(x,y.substring(1)), lcsrec(x.substring(1),y));
}