I am trying to know and understand as many algorithms as I can and I stumbled across a strange algorithm in a contest packet that finds the minimum number of steps to solve a maze (shortest path). I understand it 100%, but I don't know what algorithm it is and the packet did not state the name of it. I would really like to know the name of this algorithm (if it has a name) so I can do more research on it.
import java.io.File;
import java.util.Scanner;
class spot {
char type;
int distance;
spot closest;
public spot() {
type = '.';
distance = Integer.MAX_VALUE;
closest = null;
}
}
public class myalg {
public static void main(String args[]) throws Exception {
int moves = 0;
Scanner keyb = new Scanner(new File("src/mar2014/maze2.txt"));
int rows = keyb.nextInt();
int cols = keyb.nextInt();
spot mat[][] = new spot[rows][cols];
keyb.nextLine();
spot startSpot = null;
spot endSpot = null;
for (int i = 0; i < mat.length; i++) {
String line = keyb.nextLine();
for (int j = 0; j < mat[i].length; j++) {
mat[i][j] = new spot();
mat[i][j].type = line.charAt(j);
if (mat[i][j].type == 'S') {
startSpot = mat[i][j];
startSpot.distance = 0;
startSpot.type = ' ';
}
if (mat[i][j].type == 'E') {
endSpot = mat[i][j];
endSpot.type = ' ';
}
}
}
boolean changeMade = true;
while (changeMade) {
changeMade = false;
for (int i = 0; i < mat.length; i++) {
for (int j = 0; j < mat[i].length; j++) {
spot thisSpot = mat[i][j];
spot adjacentSpots[] = {null, null, null, null};
if (i > 0) {
adjacentSpots[0] = mat[i - 1][j];
}
if (i < cols - 1) {
adjacentSpots[1] = mat[i + 1][j];
}
if (j > 0) {
adjacentSpots[2] = mat[i][j - 1];
}
if (j < rows - 1) {
adjacentSpots[3] = mat[i][j + 1];
}
if (thisSpot.type == ' ') {
for (int k = 0; k < 4; k++) {
if (adjacentSpots[k] != null && adjacentSpots[k].distance < (thisSpot.distance - 1)) {
thisSpot.distance = adjacentSpots[k].distance + 1;
thisSpot.closest = adjacentSpots[k];
changeMade = true;
}
}
}
}
}
}
spot spot = endSpot;
while(spot != startSpot) {
moves++;
spot.type = '.';
spot = spot.closest;
}
System.out.println(moves);
}
}
Breadth-first search with backtracking.
Related
I'm currently working through Cracking the Coding Interview and I'm looking for some advice on what I can do to correct this algorithm. It appears to be working with some test cases, but it does not work with the test case ['a','a','a','b','b','b] as input. Any ideas what I'm doing wrong? Thanks!
Result expected = ['a','b']
Actual result = ['a']
/**
* Removes duplicate chars
*
* #param str
*/
public static void removeDuplicates(char[] str) {
if (str.length < 2) {
return;
}
for (int i = 0; i < str.length; i++) {
for (int j = 0; j < str.length; j++) {
if ((str[i] == str[j]) && (i != j)) {
str[j] = 0;
}
}
}
}
Try doing this:
public static void removeDuplicates(char[] str) {
if (str.length < 2) {
return;
}
for (int i = 0; i < str.length; i++) {
for (int j = 0; j < str.length; j++) {
System.out.println(i + "-" + j + " = " + str[j]); //added this line
if ((str[i] == str[j]) && (i != j)) {
str[j] = 0;
}
}
}
}
Why am I showing you this? This will show you what the removal process looks like as it goes along, and will help you better understand the problem. It actually works correctly.
I don't know how you got a result, because there is no print statement, and no return statement. But I did find a way to do it without using another char array(or any array for that matter). It simply reconstructs str. Check it out:
public static void main(String[] args) {
char[] chr = {'a','a','b','c','b','a','b','c'};
System.out.println(removeDuplicates(chr));
}
public static char[] removeDuplicates(char[] str) {
if (str.length < 2) {
return null;
}
for (int i = 0; i < str.length; i++) {
for (int j = 0; j < str.length; j++) {
if ((str[i] == str[j]) && (i != j)) {
str[j] = 0;
}
if (i == (str.length-1)) {
str[i] = str[j];
}
}
}
return str;
}
This example gives the output:
abc
Consider the next (pseudo) code:
if (str.length < 2) {
return;
}
good = 1; //current number of unique items
for (int i = 1; i < str.length; i++) {
success = 1;
//scan only unique items
for (int j = 0; j < good; j++) {
if ((str[i] == str[j]) {
success = 0;
break;
}
}
//new unique - copy at the final place
if (success) {
s[good] = str[i];
good++;
}
}
if (good<length)
str[good] = 0;
This is my first code with java .when I tested it on Ideone. It showed:
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:862)
at java.util.Scanner.next(Scanner.java:1485)
at java.util.Scanner.nextInt(Scanner.java:2117)
at java.util.Scanner.nextInt(Scanner.java:2076)
at Hw2_p4.main(Main.java:22)
I searched for answers but I didn't get the problem cause or how to fix it.
the code runs on eclipse normally
Here is the code
import java.util.Scanner;
class Hw2_p4 {
static void swap(String[] A, int a, int b) {
String temp = A[a];
A[a] = A[b];
A[b] = temp;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(), m = sc.nextInt();
int i, j, k, l, counter = 0;
String[] name = new String[16];
String[][] notalong = new String[120][2];
String[] temp = new String[120];
boolean[][] A = new boolean[120][2];
for (i = 0; i < n; i++) {
name[i] = sc.next();
}
for (i = 0; i < m; i++) {
for (j = 0; j < 2; j++) {
notalong[i][j] = sc.next();
}
}
int flag = 0;
for (i = 0; i < m; i++) {
for (j = 0; j < 2; j++) {
flag = 0;
for (k = i + 1; k < m; k++) {
for (l = 0; l < 2; l++) {
if (notalong[i][j].compareToIgnoreCase(notalong[k][l]) == 0 && A[i][j] == false && A[k][l] == false) {
A[k][l] = true;
flag = 1;
}
}
}
if (flag == 1) {
A[i][j] = true;
counter++;
} else if (flag == 0 && A[i][0] == false && A[i][1] == false) {
A[i][j] = true;
counter++;
}
}
}
System.out.println(n - counter);
int x = 0;
for (i = 0; i < m; i++) {
for (j = 0; j < 2; j++) {
if (A[i][j] == false) {
temp[x++] = notalong[i][j];
A[i][j] = true;
for (k = i + 1; k < m; k++) {
for (l = 0; l < 2; l++) {
if (notalong[i][j].compareToIgnoreCase(notalong[k][l]) == 0 && A[k][l] == false) {
A[k][l] = true;
}
}
}
}
}
}
//compare not along with names
int found = 1;
for (i = 0; i < n; i++) {
found = 0;
for (j = 0; j < m; j++) {
for (k = 0; k < 2; k++) {
if (name[i].compareToIgnoreCase(notalong[j][k]) == 0) {
found = 1;
}
}
}
if (found == 0) {
temp[x++] = name[i];
}
}
//sorting lexicographically
boolean swapp = true;
for (i = 0; i < x && swapp; i++) {
swapp = false;
for (j = 0; j < x - i - 1; j++) {
if (temp[j].compareToIgnoreCase(temp[j + 1]) > 0) {
swap(temp, j, j + 1);
swapp = true;
}
}
}
for (i = 0; i < x; i++) {
System.out.println(temp[i]);
}
}
}
Ideone is not interactive. You have to click on Specify input and enter all of your input in there before you run the application. What you are seeing is an exception because System.in has an "end of file" status.
You ought to protect sc.next() with cs.hasNext():
while (!sc.hasNext()) {
Thread.sleep(100);
}
int n = sc.nextInt();
However since you read the input in many location throughout your code try using Scanner.nextLine() preferably printing to the console, what is the input you are expecting next. nextLine() will read all the input until the user presses ENTER, which is a nicer 'user journey' than simply constantly reading keyboard and passing it to System.in.
System.out.print("Please enter your favourite number : "); //NB print and space is last
String input = sc.nextLine();
int favNumber = Double.parseDouble(input);
the way that Ideone gives input to your code is different from the way your IDE(or you)gives input.
so you should probably figure out how does Ideone gives input and then fix your code to that way of inputs.
Solving this Arbitage problem of UVA http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=40 but I am stuck with finding the negative cycle of shortest length(length here is number of vertices).Here is my code that successfully detects the negative cycle
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
public class _104 {
public static void main(String[] args) throws NumberFormatException,
IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(
System.in));
String input;
while ((input = reader.readLine()) != null) {
int n = Integer.parseInt(input);
double[][] cost = new double[n + 1][n + 1];
double[] spEstimate = new double[n + 1];
int parent[] = new int[n + 1];
for (int i = 0; i < n + 1; i++) {
spEstimate[i] = Double.MAX_VALUE;
cost[0][i] = 0;
cost[i][0] = Double.MAX_VALUE;
parent[i] = Integer.MAX_VALUE;
}
spEstimate[0] = 0.0;
parent[0] = 0;
for (int i = 1; i < n + 1; i++) {
String[] line = reader.readLine().split("\\s+");
for (int j = 1; j < n + 1; j++) {
if (i == j) {
cost[i][j] = 0;
} else if (i < j) {
cost[i][j] = -(Math
.log(Double.parseDouble(line[j - 2])) / Math
.log(2));
} else {
cost[i][j] = -(Math
.log(Double.parseDouble(line[j - 1])) / Math
.log(2));
}
}
}
int save = 1, s = 1;
boolean flag = BellmanFord(n, cost, spEstimate, parent);
display(cost);
// Relax all edges once more
boolean brk = true;
for (int i = 0; i < cost.length && brk; i++) {
for (int j = 0; j < cost.length && brk; j++) {
//relax(i, j, spEstimate, cost[i][j], parent);
}
}
ArrayList<Integer> path = new ArrayList<Integer>();
while (parent[save] != s) {
path.add(save);
save = parent[save];
}
if (flag) {
System.out.println("no arbitrage sequence exists");
} else {
path.add(0, path.get(path.size() - 1));
for (int i = path.size() - 1; i >= 0; --i) {
System.out.println(path.get(i));
}
}
}
reader.close();
}
public static boolean BellmanFord(int n, double[][] cost, double[] sp,
int[] parent) {
for (int k = 0; k < n - 1; k++) {
for (int i = 0; i < cost.length; i++) {
for (int j = 0; j < cost.length; j++) {
relax(i, j, sp, cost[i][j], parent);
}
}
}
// Relax all edges once more to detect cycle
for (int i = 0; i < cost.length; i++) {
for (int j = 0; j < cost.length; j++) {
if (sp[j] > (sp[i] + cost[i][j])) {
return false;
}
}
}
return true;
}
static void relax(int i, int j, double[] sp, double cij, int[] parent) {
if (sp[j] > (sp[i] + cij)) {
sp[j] = sp[i] + cij;
System.out.println("relaxed " + i + " " + j + " " + cij + " "
+ sp[i] + " " + sp[j]);
parent[j] = i;
}
}
static void display(double[][] cost) {
System.out.println("Display Cost");
for (int i = 0; i < cost.length; i++) {
for (int j = 0; j < cost.length; j++) {
System.out.print(cost[i][j] + "\t");
}
System.out.println();
}
}
static void display(double[] sp) {
for (int i = 0; i < sp.length; i++) {
System.out.println(sp[i]);
}
}
}
You can do it like that:
Fix the start vertex of the cycle(let's call it v).
Run Ford-Bellman algorithm assuming that dist[i] = 0 if i = v and INF otherwise.
If there is a negative cycle that contains v, after k iterations of the outer loop in Ford-Bellman algorithm dist[v] will become negative. So you can easily find such smallest k by simply checking if dist[v] is still non-negative or not after each iteration.
The smallest k among all v is the answer.
It is possible to solve this problem by considering cycles of increasing length as opposed to finding negative cycles as described by kraskevich. The worst case complexity for both approaches is O(n^4). This approach resembles Floyd-Warshall where you consider increasing lengths instead of intermediate vertices.
You can find a detailed explanation that includes diagrams and code here.
Here's my code: http://pastebin.com/umy0FPvB (LG)
and here's the teacher's code: http://pastebin.com/y5wU0Zpx (LCI)
It's telling me I'm wrong on line 41 of the teacher's code when the LCI is trying to read from the matrix passed from the LG [world()].
I've been sitting on this for a while but I can't seem to figure out what's wrong.
Exception in thread "main" java.lang.NullPointerException
at Console.printWorld(Console.java:41)
at Console.playLife(Console.java:56)
at Console.main(Console.java:30)
--
/**
* The Life game
* #author Noah Kissinger
* #date 2012.2.13
*/
import java.util.Random;
public class Life {
private static boolean[][] matrix;
private static int bL, bH, lL, lH, r, c;
private static long rSeed;
public Life(long seed, int rows, int columns, int birthLow, int birthHigh,
int liveLow, int liveHigh) {
rSeed = seed;
bL = birthLow;
bH = birthHigh;
lL = liveLow;
lH = liveHigh;
r = rows;
c = columns;
createMatrix();
}
public void update() {
updateMatrix();
}
public boolean[][] world() {
return matrix;
}
public static void createMatrix() {
Random seedBool = new Random(rSeed);
boolean[][] matrix = new boolean[r][c];
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
matrix[i][j] = false;
}
}
for (int i = 1; i < matrix.length - 1; i++) {
for (int j = 1; j < matrix[i].length - 1; j++) {
matrix[i][j] = seedBool.nextBoolean();
}
}
}
public static void updateMatrix() {
Random seedBool = new Random(rSeed);
boolean[][] matrixCopy = matrix.clone();
for (int i = 0; i < matrix.length; i++)
matrixCopy[i] = matrix[i].clone();
int count = 0;
for (int i = 1; i < matrix.length - 1; i++) {
for (int j = 1; j < matrix[i].length - 1; j++) {
if (matrix[i][j] == false) {
if (matrixCopy[i - 1][j - 1] == true)
count++;
if (matrixCopy[i - 1][j] == true)
count++;
if (matrixCopy[i - 1][j + 1] == true)
count++;
if (matrixCopy[i][j - 1] == true)
count++;
if (matrixCopy[i][j + 1] == true)
count++;
if (matrixCopy[i + 1][j - 1] == true)
count++;
if (matrixCopy[i + 1][j] == true)
count++;
if (matrixCopy[i + 1][j + 1] == true)
count++;
if (count >= bL && count <= bH) {
matrix[i][j] = true;
for (int i1 = 0; i1 < matrix.length; i1++) {
for (int j1 = 0; j1 < matrix[i1].length; j1++) {
matrix[i1][j1] = false;
}
}
for (int i1 = 1; i1 < matrix.length - 1; i1++) {
for (int j1 = 1; j1 < matrix[i1].length - 1; j1++) {
matrix[i1][j1] = seedBool.nextBoolean();
}
}
} else
matrix[i][j] = false;
count = 0;
}
else {
if (matrixCopy[i - 1][j - 1] == true)
count++;
if (matrixCopy[i - 1][j] == true)
count++;
if (matrixCopy[i - 1][j + 1] == true)
count++;
if (matrixCopy[i][j - 1] == true)
count++;
if (matrixCopy[i][j + 1] == true)
count++;
if (matrixCopy[i + 1][j - 1] == true)
count++;
if (matrixCopy[i + 1][j] == true)
count++;
if (matrixCopy[i + 1][j + 1] == true)
count++;
if (count >= lL && count <= lH)
matrix[i][j] = true;
else
matrix[i][j] = false;
count = 0;
}
}
}
}
}
--
/**
* The Console class is a console interface to the Life game.
* #author DH
* #date Sept. 2008
*/
import java.util.Scanner;
public class Console {
/**
* #param args unused
*/
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("Please enter the size of the matrix(rows, columns) :");
int rows = in.nextInt();
int columns = in.nextInt();
System.out.println("Please enter random seed: ");
long seed = in.nextLong();
System.out.println("Please enter birth range (low, high) :");
int birthLow = in.nextInt();
int birthHigh = in.nextInt();
System.out.println("Please enter live range (low, high): ");
int liveLow = in.nextInt();
int liveHigh = in.nextInt();
try {
Life game = new Life(seed, rows, columns, birthLow, birthHigh, liveLow, liveHigh);
playLife(game);
} catch (IllegalArgumentException e) {
System.out.println("Inappropriate values: " + e.getMessage());
}
}
/**
* Print a boolean matrix
* #param world is a boolean matrix to be printed with # for true and - for false.
*/
public static void printWorld(boolean[][] matrix) {
for (int r=0; r<matrix.length; r++) {
for (int c=0; c<matrix[0].length; c++) {
System.out.print(matrix[r][c] ? " # " : " - ");
}
System.out.println();
}
System.out.println();
}
/**
* Play the game of Life starting with a given state
* #param game is the Life object that provides the current state of Life
*/
public static void playLife(Life game) {
printWorld(game.world());
for (int i=0; i<10; i++) {
game.update();
printWorld(game.world());
}
}
}
Here's your problem. In your createMatrix() method you define a local variable matrix when you really want to modify the field matrix.
You may find it useful to access fields with this, e.g. this.matrix. It makes a clear distinction in the code. However, most IDEs will auto highlight fields and local variables so some people find it unnecessary, it's a question of style and not overly important.
I haven't checked the rest of your program, there may be other errors.
public static void createMatrix() {
Random seedBool = new Random(rSeed);
this.matrix = new boolean[r][c];
for (int i = 0; i < this.matrix.length; i++) {
for (int j = 0; j < this.matrix[i].length; j++) {
this.matrix[i][j] = false;
}
}
for (int i = 1; i < this.matrix.length - 1; i++) {
for (int j = 1; j < this.matrix[i].length - 1; j++) {
this.matrix[i][j] = seedBool.nextBoolean();
}
}
}
boolean[][] matrix = new boolean[r][c];
This line creates a 2-dimensional array of boolean and stores it in a loca variable in the createMatrix method.
So, the static field matrix in the Life class still be null.
This field is read and passed through the world method into the playLife method.
And, next, the call of printLife method trigger NPE.
BTW, why did you implemented the game of life using many static fields and methods?
What is the best(fastest) way to sort an array of Strings (using Java 1.3).
You can use this code for sort the string values,
public Vector sort(String[] e) {
Vector v = new Vector();
for(int count = 0; count < e.length; count++) {
String s = e[count];
int i = 0;
for (i = 0; i < v.size(); i++) {
int c = s.compareTo((String) v.elementAt(i));
if (c < 0) {
v.insertElementAt(s, i);
break;
} else if (c == 0) {
break;
}
}
if (i >= v.size()) {
v.addElement(s);
}
}
return v;
}
Also see this sample code for using bubble sort,
static void bubbleSort(String[] p_array) throws Exception {
boolean anyCellSorted;
int length = p_array.length;
String tmp;
for (int i = length; --i >= 0;) {
anyCellSorted = false;
for (int j = 0; j < i; j++) {
if (p_array[j].compareTo(p_array[j + 1]) > 0) {
tmp = p_array[j];
p_array[j] = p_array[j + 1];
p_array[j + 1] = tmp;
anyCellSorted = true;
}
}
if (anyCellSorted == false) {
return;
}
}
}
Use java.util.Arrays.sort.
If it's not possible for some reason due to limitations of the platform, you can get ideas from its source.