Многоколонный анализ файла с Kotlin - PullRequest
1 голос
/ 31 мая 2019

У меня есть текстовый файл из четырех столбцов, и я хочу создать с ним два вектора. Я намерен использовать первый и второй столбцы в качестве смешанного индекса. Таким образом, первый и второй столбцы являются целыми числами, а 3 и 4 - двойными В Фортране это будет:

10 READ("4Column_file.txt",*,END=20)N,M,T1,T2
   IG=(N*(N+1))/2+M+1
   CC(IG)=T1
   CS(IG)=T2
   GOTO 10 
20 CONTINUE

Как мне это сделать с Kotlin или Java?

Ввод в форме:

5   5  -0.244048470535508183D+00  -0.129800076712784507D+01
6   0  -0.468652527040705080D+01   0.000000000000000000D+00 

На выходе будут загружены векторы CC [IG] и CS [IG].

Например, в первой строке: IG=(5*(5+1))/2+5+1=21 поэтому CC [21] = - 0,244048470535508183D + 00 и CS [21] = - 0,129800076712784507D + 01.

Во второй строке: IG=(6*(6+1))/2+5+1=27 поэтому CC [27] = - 0,468652527040705080D + 01 и CS [27] = 0,000000000000000000D + 00

Ответы [ 2 ]

1 голос
/ 01 июня 2019

Вы можете использовать такую ​​библиотеку, как univocity-parsers .Существует руководство по анализу файлов, разделенных табуляцией:

https://www.univocity.com/pages/univocity_parsers_tsv.html#working-with-tsv

Поскольку Kotlin работает на JVM и 100% совместим с Java , вы можете просто включить анализаторы однозначности jar как зависимость вместо того, чтобы кодировать их самостоятельно - здесь координаты Maven:

<dependency>
  <groupId>com.univocity</groupId>
  <artifactId>univocity-parsers</artifactId>
  <version>2.8.2</version>
</dependency>
1 голос
/ 01 июня 2019

Вы можете сделать это в Kotlin:

val length = 20 // Some default length
val cc = arrayOfNulls<String>(length)
val cs = arrayOfNulls<String>(length)

val lineRegex = "\\s+".toRegex()

File("4Column_file.txt").useLines { lineSequence ->
    for (line in lineSequence) {
        val (n, m, t1, t2) = line.split(lineRegex)
        val nInt = n.toInt()
        val mInt = m.toInt()

        val ig = (nInt * (nInt + 1)) / 2 + mInt + 1
        cc[ig] = t1
        cs[ig] = t2
    }
}

Если вы заранее не знаете длину, вам нужно сначала прочитать все строки в некотором классе данных.Затем вам нужно найти максимальное значение ig и создать массивы этого размера.Что-то вроде:

data class Row(val n: Int, val m: Int, val t1: String, val t2: String) {
    val ig: Int = (n * (n + 1)) / 2 + m + 1
}

// rowList is List<Row> after parsing
val maxIdx = rowList.maxBy { it.ig } ?: -1

val cc = arrayOfNulls<String>(maxIdx + 1)
val cs = arrayOfNulls<String>(maxIdx + 1)

for (row in rowList) {
    cc[row.ig] = row.t1
    cs[row.ig] = row.t2
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...