2015-10-29 33 views
0

今天晚上我写了一个代码,它获得一个.txt文件的名称,它从命令行参数中获取。它将文本文件的每个字符放入一个数组中。 这是这些TEXTFILESjava - 检查数组

7 11 
########### 
#  # # 
# ### # 
# #  # 
# K ### # 
#  # # 
########### 

我想检查是否有可能在K走过去每一个“”,“#”的是墙上的样品。所以,如果我在这里检查此拉特它应该打印假,因为那里有右侧墙壁上,而在这里

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个步行的空间附近的北东南或西的所有空格都accessable。但我将不得不在外壁破例对所有的空间直接,因为它连接到空间有一个领域是不够的,例如

5 7 
####### 
#K # 
# # # # 
# # # # 
####### 

这应该是真实的,但它不是,因为在该领域下半部分只是连接到墙上,但仍然可以访问..在我的脚本中我不检查数组在索引[0] [n]和[1] [n]以及不检查[n] [0] & & [ N] [1]所以我不得到这个错误,但我想..也是在我的算法难道不工作,将是这样一个情况:

8 11 
########### 
#   # 
# ###### # 
# #K # # 
# # # # 
# ###### # 
#   # 
########### 

也许你有这么我的想法如何改善代码..即时通讯初学者,只能说2周的Java ..预先感谢和阅读,直到下面:)

+2

你的代码不能用于像最后一个例子那样具有特定属性的迷宫。使用洪水填充(https://en.wikipedia.org/wiki/Flood_fill)来取得正确的结果 – Paul

+0

我怎样才能将它实现到代码中?有没有一个脚本可以导入或我必须自己做? – siryx

+0

填充填充是这类问题的一个众所周知的解决方案;在SO搜索框中输入“填充”会返回超过一百个问题;应该很容易找到一个可以帮助您在代码中执行下一步的程序。 – m69

回答

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方法,它很简单,可以自己弄清楚。希望这可以帮助。

+0

什么是validCoordinates方法?我很抱歉,我甚至不知道如何制作自己的函数......我一直使用public static void main(String args []):<我必须像使用java.io一样导入它。* ?不能在oracle java文档页上找到它:X – siryx

+0

所以我试着理解你的代码,但我已经开始有问题线Deque queue = new ArrayDeque <>(); ... :(我有你的想法,但我没有看到你如何制作代码。\ n我试图让你的代码工作通过 import java。*; 公共类解决方案{ \t公共静态无效的主要(字符串ARGS []){ \t} } 但它不工作 – siryx

+0

validCoordinates是,如果传递的参数是网格的边界之内都将返回true的方法。如果你还不知道如何定义你自己的方法,那么你可以用一个0 <= nx turingcomplete