簡體   English   中英

在不使用索引的情況下有效地搜索 arrays?

[英]efficiently searching arrays without using index?

所以我正在為 class 制作一個基於文本的角色扮演游戲。目前該功能適用於一個房間,這正是我目前想要的。 但是我想要一種更有效的方法來做到這一點。 我想在沒有索引的情況下執行此操作。 我想打印文本文件中的元素列表,從 contains(3.a) 到 end.3 所在的位置。 你們中的任何獸醫都可以幫助我嗎? . 這是我第一次嘗試此類項目。 我這么早問的原因是因為這是項目的介紹,學期末的最終項目將是一個經過解析的 40 頁文本文件。

文本文件

1.a

Outside building
-------
WEST       2
UP         2
NORTH      3
IN         3

end.1

2.a

End of road
You are at the end of a road at the top of a small hill.
You can see a small building in the valley to the east.
------
EAST      1
DOWN      2

end.2

3.a

Inside building
You are inside a building, a well house for a large spring
-------
SOUTH    1
OUT      1

end.3

代碼

public static void main(String[] args)throws FileNotFoundException{ 
    
    
    int direction = 0;
    Scanner s = new Scanner(new File("C:\\Users\\Basil Sheppard\\eclipse-workspace\\software practice\\src\\software\\rooms.txt"));
    Scanner choice = new Scanner(System.in);
    ArrayList<String> listS = new ArrayList<String>();
    

    while ( s.hasNextLine()) 
        listS.add(s.nextLine());
    
    
    System.out.println("please enter 3 for testing");
    direction = choice.nextInt();

    switch (direction){

//tests for room 3  
    case 3: {
    boolean found = listS.contains("3.a");
    if(found) {
        for(int i = 22; i<27; i++) {
            System.out.println(listS.get(i));
        }
    }
                            
} 

您的方法看起來完全錯誤。

我會做什么:

  1. 使用以下內容創建一個 class MapLocation:
    1. 標題,字符串
    2. 描述,字符串[]
    3. 導航,MapNavi[]
  2. 使用以下內容創建另一個 class MapNavi:
    1. MapLoc, 整數
    2. 方向,字符串
  3. 讀取整個文件並將其解析為 MapLocation[]
  4. 處理輸入並遍歷 MapLocation[]

該文件的結構似乎是:

(#.a

Title
Description Lines*
-------
MapNavi+

end.#)+

所以你可以構建一個解析器來處理上面的文件,這很簡單。 您還可以使用純 RegEx 解析整個文件。

示例解析器:

try (BufferedReader br = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream(_FILE_NAME))))
{
    String line;
    int state = 0;
    MapLocation currSegment = null;
    while ((line = br.readLine()) != null)
    {
        switch (state)
        {
        case 0:
           if (line.endsWith(".a"))
           {
               String segId = line.substring(0, line.indexOf(".a"));
               currSegment = new MapLocation(Integer.parseInt(segId));
               state++;
           }
           break;
        case 1:
           if (line.length() != 0)
           {
               currSegment.setTitle(line);
               state++;
           }
        case 2:
           if ("-------".equals(line))
           {
               state++;
           } else if (line.length() > 0)
           {
               currSegment.addDescription(line);
           }
        case 3:
           if (line.equals("end." + currSegment.getSegId()))
           {
               mapLocations.put(currSegment.getSegId(), currSegment);
               currSegment = null;
               state = 0;
           } else if (line.length() > 0)
           {
               String[] nav = line.split("\t");
               Integer mapLoc = Integer.parseInt(nav[1]);
               currSegment.addNavi(mapLoc, nav[0]);
           }
        }
    }
}

一旦文件被解析到 mapLocations 容器中,您就可以處理輸入了:

try (Scanner in = new Scanner(System.in))
{
    MapLocation currLoc = // startLocation;
    while (!quitSignal.equals(line = in.nextLine()))
    {
        int mapLoc = Integer.parseInt(line);
        if (currLoc.validateNav(mapLoc))
        {
            currLoc = mapLocations.get(mapLoc);
            System.out.println("You travel to " + currLoc.getTitle());
            System.out.println(currLoc.toString());
        }
        else
        {
            System.out.println("You cannot travel to location '" + line + "' from here.  Please re-select your destination.");
        }
    }
}

您應該考慮將路徑存儲為 xml 文件。 Java 有一些很酷的閱讀方式,它可以理解列表中的元素。 您甚至可以寫信給 xml 以便更輕松地構建您的游戲:查看如何讀取 xml: https://stackoverflow.com/a/428091/9789673

試試這個。

try (Scanner s = new Scanner(new File("C:\\Users\\Basil Sheppard\\eclipse-workspace\\software practice\\src\\software\\rooms.txt"))) {
    Scanner choice = new Scanner(System.in);
    ArrayList<String> listS = new ArrayList<String>();

    while (s.hasNextLine())
        listS.add(s.nextLine());

     System.out.println("please enter 3 for testing");
    int direction = choice.nextInt();

    listS.stream()
        .dropWhile(x -> !x.equals(direction + ".a"))
        .takeWhile(x -> !x.equals("end." + direction))
        .forEach(System.out::println);
    System.out.println("end." + direction);
}

output

3.a

Inside building
You are inside a building, a well house for a large spring
-------
SOUTH    1
OUT      1

end.3

請注意.takeWhile(x ->.x.equals("end." + direction))丟棄end.3本身。

我認為你需要考慮兩個主要問題:

  • 構建文件,使其行具有易於解析的相當一致的結構。
  • 想一想如何組織代碼以便只掃描文件一次,在第一次閱讀文件時創建類以有組織的方式將數據存儲在 memory 中。 (是的,從某種意義上說,這是一個“索引”,但你不能同時擁有它:要么在第一次掃描文件時從文件中存儲/索引信息,要么丟棄信息並必須掃描在下一個查詢中再次通過它,這本質上是低效的。)

例如,您可以像這樣構建文件:

BEGIN:LOCATION:1
BEGIN:DESCRIPTION:
A house.
END:DESCRIPTION
BEGIN:DIRECTIONS
NORTH:3
SOUTH:4
END:DIRECTIONS
END:LOCATION

換句話說,這些行通常由 'command':'subcommand' 組成,並且給定文件中的一行,很容易將其拆分為其組件(查看 String.indexOf()、String.substring()。如果可以,請查看正則表達式 API:查看 Pattern 和 Matcher 類。(理論上,當您嘗試同時掃描同一行/文本以查找多個不同的模式/子字符串時,這會帶來一些效率,並且是如果您正在掃描大量文本以查找更復雜的模式/命令,則通常會使用這種方法。出於您的目的,您也可以使用簡單的字符串方法——indexOf()、substring() 等——如果你發現這些更容易掌握。)

其他人提到了 XML:這是一種您也可以考慮的結構化格式,並且具有內置於 Java 平台中的標准解析例程的優勢。 但是,只要它是一致的並且很容易編寫例程來解析它,您設計的格式的純舊文本文件就沒有本質上的錯誤......

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM