[英]Read data as arrays from a Text File in Java
我有一個包含一堆 arrays 的文本文件,我必須在數組中找到一個特定的數字。 文本文件如下所示:
(8) {1, 4, 6, 8, 12, 22}
(50) {2, 5, 6, 7, 10, 11, 24, 50, 65}
(1) {1}
(33) {1, 2, 5, 6, 11, 12, 13, 21, 25, 26, 30, 33, 60, 88, 99}
(1) {1, 2, 3, 4, 8, 9, 100}
(1) {2, 3, 5, 6, 11, 12, 13, 21, 25, 26, 30, 33, 60, 88, 99}
其中括號內的數字是我必須使用二進制搜索找到的數字。 rest 是實際陣列。 我不知道如何從文本文件中獲取該數組並能夠將其作為實際數組讀取。 [這是我之前參加的編碼比賽的一個問題,正在復習這些問題]
我已經有了一種方法來進行二進制搜索,並且我使用掃描儀來讀取文件,如下所示:
Scanner sc = new Scanner(new File("search_race.dat"));
並使用了一個while循環來遍歷文件並讀取它。
但是我被困在如何讓 java 知道花括號中的東西是一個數組,而括號中的東西是它必須在所述數組上使用二進制搜索才能找到的東西。
您可以逐行讀取文件中的字符串,然后在每行上使用正則表達式將字符串分成組。
下面的正則表達式應該適合匹配該行
\((\d+)\) \{([\d, ]+)\}
然后 group(1) 將給出括號內的數字(作為字符串), group(2) 將給出大括號內的字符串,您可以使用它進行拆分,以及空格(假設每個逗號后面都有一個空格)並得到一個數組數字(再次作為字符串)
希望這可以幫助!
TL;DR:您必須逐個字符檢查它是花括號還是括號還是數字
長答案:
首先,使用字段int numberToFind
和ArrayList<Integer> listOfNumbers
創建一個 POJO(我們稱之為AlgoContainer
,但可以使用任何你喜歡的名稱)。
然后,閱讀@ManojBanik 在評論中提到的文件
現在創建一個ArrayList<AlgoContainer>
(它的大小應該與逐行讀取文件時獲得的ArrayList<String>
相同)
然后循環遍歷上述步驟中的ArrayList<String>
並執行以下操作:
創建並實例化一個AlgoContainer
object 實例(我們稱之為tempAlgoContainer
)。
檢查第一個字符是否是左括號-> 是嗎? 創建一個空的臨時String
-> 檢查下一個字符是否是數字 -> 是嗎? -> append 將其轉換為空String
並重復此操作,直到找到右括號。
找到左括號? 將 temp String
解析為int
並將tempAlgoContainer
的numberToFind
字段設置為該數字。
接下來是花括號的東西:找到花括號了嗎? 創建一個新的空臨時String
-> 檢查下一個字符是否為數字 -> 是嗎? append 然后 append 到空String
,就像在步驟 2 中一樣,直到找到逗號或右花括號。
String
解析為 int,然后將其添加到tempAlgoContainer
的listOfNumbers
(這是一個字段)中 -> 再次使臨時String
為空。 此外,最好有一個成員 function 或 AlgoContainer 的實例方法( AlgoContainer
調用它)來執行二進制搜索,以便您可以簡單地循環遍歷ArrayList<AlgoContainer>
並在其上調用 BS function(不 -雙關語)
要讀取文件,可以使用Files.readAllLines()
要實際解析每一行,您可以使用類似這樣的東西。
首先,為了使事情更容易,從行中刪除所有空格。
line.replaceAll("\\s+", "");
這基本上會將(8) {1, 4, 6, 8, 12, 22}
轉換為(8){1,4,6,8,12,22}
。
接下來,使用正則表達式來驗證該行。 如果該行不匹配,則不需要進一步的操作。
表達式: \([0-9]*\)\{[0-9]*(,[0-9]*)*}
\([0-9]*\)
與(8)
相關(上例)\{[0-9]*(,[0-9]*)*}
與{1,4,6,8,12,22}
相關如果你不明白這個表達,請到這里。
最后,我們可以將字符串解析為它的兩個組成部分:要搜索的數字和帶有實際值的int[]
。
// start from index one to skip the first bracket
int targetEnd = trimmed.indexOf(')', 1);
String searchString = trimmed.substring(1, targetEnd);
// parsing wont throw an exception, since we checked with the regex its a number
int numberToFind = Integer.parseInt(searchString);
// skip ')' and '{', align to the first value, skip the last '}'
String valuesString = trimmed.substring(targetEnd + 2, trimmed.length() - 1);
// split the array at ',' to get each value as string
int[] values = Arrays.stream(valuesString.split(","))
.mapToInt(Integer::parseInt).toArray();
解析完這兩個組件后,您可以自己進行二進制搜索。
示例代碼作為GitHub 上的 Gist
您可以簡單地解析每一行(要查找的數字和數組),如下所示:
while (sc.hasNext()) {
int numberToFind = Integer.parseInt(sc.next("\\(\\d+\\)").replaceAll("[()]", ""));
int[] arrayToFindIn = Arrays.stream(sc.nextLine().split("[ ,{}]"))
.filter(x->!x.isEmpty())
.mapToInt(Integer::parseInt)
.toArray();
// Apply your binary search ! Craft it by yourself or use a std one like below :
// int positionInArray = Arrays.binarySearch(arrayToFindIn, numberToFind);
}
如果您不喜歡 replaceAll,可以將循環中的第一行替換為以下兩行:
String toFindGroup = sc.next("\\(\\d+\\)");
int numberToFind = Integer.parseInt(toFindGroup.substring(1, toFindGroup.length()-1));
干杯!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.