java - 检查数组

时间:2015-10-29 01:08:20

标签: java arrays algorithm

今晚我写了一个代码,该代码以.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两周..提前感谢并阅读直到这里:)

1 个答案:

答案 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方法,它很简单,可以自行解决。希望这会有所帮助。