2015-10-29 32 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