今晚我写了一个代码,该代码以.txt文件提供,该文件名称来自命令行参数。它将文本文件的每个字符放在一个数组中。 这是这些文本文件的样本
7 11
###########
# # #
# ### #
# # #
# K ### #
# # #
###########
我想检查K是否有可能走过每一个" ","#"是墙壁。因此,如果我在这里检查这个lvl,它应该打印为false,因为右边有一面墙,而这里
5 8
########
# K #
# ### #
# #
########
应该是真的。这是我得到了多少(抱歉德国变量名称和评论):
import java.io.*;
public class unbenannt {
public static void main (String args[]) throws IOException {
FileReader fr = new FileReader(args[0]); //Dateipfad wird übergeben als Kommandozeilenarg.
BufferedReader br = new BufferedReader(fr);
String zeile1 = br.readLine(); //Zeile1 wird gelesen für x und y
String[] xypos = zeile1.split(" ");
int hoehe = Integer.parseInt(xypos[0]); //String=>int
int laenge = Integer.parseInt(xypos[1]);
String[][] spielfeld = new String[hoehe][laenge]; //0. Dim wird Anzahl Zeilen, 1. Dim wird die Länge d. Zeilen aber beides 0-basiert(!)
//Zeile einlesen.
String zeile = "";
int j = 0; //aktuelle zeile
while (zeile != null) {
zeile = br.readLine();
if(zeile != null) {
//System.out.print(j);
for(int i=0;i<laenge;i++){ //2. Schleife für Zeile ist j
spielfeld[j][i] = String.valueOf(zeile.charAt(i));
}
}
j = j +1;
}
//array ist definiert
//algorythmus: wenn an feld 2 weiße = true; ausgenommen wandnähe
String weissfeld = " ";
String schwarzfeld = "#";
String kassiofeld = "K";
//2basiert weil wandproblem:
//Y-Achse invertiert => -1 in höhe für Norden:
for(int posy = 2;posy < hoehe-1;posy = posy+1){
for(int posx = 2;posx < laenge-1;posx = posx+1){
if(false == schwarzfeld.equals(spielfeld[posy][posx])){
boolean resultN = schwarzfeld.equals(spielfeld[posy][posx-1]);
boolean resultO = schwarzfeld.equals(spielfeld[posy+1][posx]);
boolean resultS = schwarzfeld.equals(spielfeld[posy][posx+1]);
boolean resultW = schwarzfeld.equals(spielfeld[posy-1][posx]);
int fehlerzahl = 0;
if(resultN==true){
fehlerzahl = fehlerzahl+1; //fehlerzahl+1
}
if(resultO==true){
fehlerzahl = fehlerzahl+1; //fehlerzahl+1
}
if(resultS==true){
fehlerzahl = fehlerzahl+1; //fehlerzahl+1
}
if(resultW==true){
fehlerzahl = fehlerzahl+1; //fehlerzahl+1
}
if(fehlerzahl > 2){
System.out.println("Not all white spaces reachable.");
break; //
}
}
}
}
System.out.println("No error means success. Script finished.");
br.close();
}
}
我的解决方案是,如果每个步行空间在东北南或西部附近有2个其他可步行空间,则所有空间都可以进入。但是我必须对外墙上的所有空间进行例外处理,因为有一个连接到空间的字段就足够了,例如
5 7
#######
#K #
# # # #
# # # #
#######
这应该是真的,但这不是因为下半部分的字段只是连接到墙但仍然可以访问..在我的脚本中我不检查索引[0] [n]和[1]的数组[n]以及不检查[n] [0]&amp;&amp; [n] [1]所以我没有得到这个错误,但我想......也是我的算法无法工作的情况:
8 11
###########
# #
# ###### #
# #K # #
# # # #
# ###### #
# #
###########
也许你有一些关于如何改进代码的想法..我是一个初学者,只讲java两周..提前感谢并阅读直到这里:)
答案 0 :(得分:0)
有几种方法可以实现这一点,对于我的回答,我将使用广度优先遍历网格。
char [][] grid;
Deque<Point> queue = new ArrayDeque<>();
HashSet<Point> visited = new HashSet<>();
int kx; // x coordinate of k
int ky; // y coordinate of k
Point start = new Point(kx, ky);
queue.add(start);
int [] dx = {0, 0, 1, -1, -1, 1, 1, -1};
int [] dy = {1, -1, 0, 0, -1, 1, -1, 1};
while (!queue.isEmpty()) {
Point p = queue.poll();
if (visited.contains(p)) {
continue;
}
visited.add(p);
for (int i = 0; i < dx.length; i++) {
int nx = (int)p.getX()+dx[i];
int ny = (int)p.getY()+dy[i];
if (validCoordinates(nx, ny) && grid[nx][ny] == ' ')) {
queue.add(new Point(nx, ny));
}
}
}
boolean allReachable = true;
outer: for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == ' ' && !visited.contains(new Point(i, j))) {
allReachable = false;
break outer;
}
}
}
System.out.println(allReachable ? "All white spaces are reachable" : "Not all white spaces are reachable");
我们的想法是从k所在的位置开始,访问所有打开的相邻单元格,然后递归执行。每次访问打开的单元格时,都会将其添加到集合中。在您访问可能的单元格之后,循环遍历网格,并为每个打开的单元格检查它是否在访问集合中。如果访问集中至少有一个未打开的单元格,则表示您无法从起始位置访问所有打开的单元格。
顺便说一下,我没有在实现中包含validCoordinates
方法,它很简单,可以自行解决。希望这会有所帮助。