#f#
#f#
Вопрос:
я использую F #. Я хочу решить какую-то проблему, которая требует от меня считывания входных данных из файла, но я не знаю, что делать. Первая строка в файле состоит из трех чисел, первые два числа — это x и y для отображения следующей строки. Пример файла:
5 5 10
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
значение 5 5 10 — это следующая строка с картой 5×5, а 10 — это всего лишь несколько чисел, которые мне нужны для решения проблемы, следующим до конца строки является содержимое карты, которую я должен решить, используя 10, и я хочу сохранить номера этой карты в 2-мерном массиве. Кто-нибудь может помочь мне написать код для сохранения всех чисел из файла, чтобы я мог его обработать?
* Извините, мой английский плохой, надеюсь, мой вопрос можно понять 🙂
Ответ на мой собственный вопрос: Спасибо за ответ от Даниэля и Анкура. Для своей собственной цели я смешиваю код от вас обоих:
let readMap2 (path:string) =
let lines = File.ReadAllLines path
let [|x; y; n|] = lines.[0].Split() |> Array.map int
let data =
[|
for l in (lines |> Array.toSeq |> Seq.skip 1) do
yield l.Split() |> Array.map int
|]
x,y,n,data
Большое спасибо: D
Ответ №1:
Вот несколько быстрых и грязных кодов. Он возвращает кортеж последнего числа в заголовке (в данном случае 10) и двумерный массив значений.
open System.IO
let readMap (path:string) =
use reader = new StreamReader(path)
match reader.ReadLine() with
| null -> failwith "empty file"
| line ->
match line.Split() with
| [|_; _; _|] as hdr ->
let [|x; y; n|] = hdr |> Array.map int
let vals = Array2D.zeroCreate y x
for i in 0..(y-1) do
match reader.ReadLine() with
| null -> failwith "unexpected end of file"
| line ->
let arr = line.Split() |> Array.map int
if arr.Length <> x then failwith "wrong number of fields"
else for j in 0..(x-1) do vals.[i, j] <- arr.[j]
n, vals
| _ -> failwith "bad header"
Комментарии:
1. ах да, спасибо, извините, я кое-что забыл, я хочу сохранить содержимое карты в 2-мерном массиве, вы можете мне помочь
2. Я использовал неровный массив, потому что они работают лучше, но я обновил его, чтобы использовать двумерный.
Ответ №2:
В случае, если файл такой большой (никаких дополнительных данных для обработки) и всегда в правильном формате (нет необходимости обрабатывать недостающие данные и т.д.), Тогда это было бы так просто, как:
let readMap (path:string) =
let lines = File.ReadAllLines path
let [|_; _; n|] = lines.[0].Split() |> Array.map int
[|
for l in (lines |> Array.toSeq |> Seq.skip 1) do
yield l.Split() |> Array.map int
|]