2017-01-25 8 views
0

У меня есть два файла в формате .dimacs, например:Сравнение двух файлов по содержанию в их линии в Scala

c example_01.cnf 
p cnf 6 9 
    1 0 
-2 1 0 
-1 2 0 
-5 1 0 
-6 1 0 
-3 2 0 
-4 2 0 
-3 -4 0 
    3 4 -2 0 

и

c example_02.cnf 
p cnf 9 6 
-7 2 0 
7 -2 0 
-8 3 0 
8 -3 0 
-9 4 0 
9 -4 0 

Я хочу сравнить файл example_01.cnf с example_02.cnf таким образом, что , извлечения только те строки из файла example_01.cnf, которые имеют аналогичное значение (в любой строке) из файла example_02.cnf и сохранить результат в новом файле, например, example_result.cnf.

В этом случае example_result.cnf будет выглядеть следующим образом:.

c example_result.cnf 
p cnf 4 6 
-2 1 0 
-1 2 0 
-3 2 0 
-4 2 0 
-3 -4 0 
3 4 -2 0 

Например, линии 1 0, -5 1 0 и -6 1 0 не в результирующий файл, потому что ни один из номеров 1, 5 и 6 находятся в example_02.cnf.

Мой текущий код:

import scala.io.Source 

    object Example_01 { 

     val source = Source.fromFile("example_01.cnf") 
     val source2 = Source.fromFile("example_02.cnf") 
     val destination = new PrintWriter(new File("example_result.cnf")) 

     def main(args: Array[String]): Unit = { 

     var nrVariables: Int = 0 
     var nrLines: Int = 0 

     destination.write("c example_result.cnf \n") 
     destination.write("p cnf " + nrVariables + " " + nrLines + "\n") //not finished! 

     /* How I can compare the all the numbers from the second file 'source2' like in the 'if' statement below? */    
     for(line <- source.getLines()) ; if line.contains("2") & line.contains("0")) { 
      destination.write(line) 
      destination.write("\n") 
      nrLines += 1   
     } 
     source.close() 
     destination.close() 
     } 

В этом коде я не использую второй файл example_02.cnf еще. Как я могу сравнить эти два файла?

ответ

0

Ну, если вы хотите сохранить линии образуют source1, содержащий номер в любой строке source2 это должно работать:

object Example { 
    val source = Source.fromFile("example_01.cnf").getLines() 
    val source2 = Source.fromFile("example_02.cnf").getLines() 
    val nrsSource2 = source2.mkString(" ").split(" ").distinct.diff(Array("0")) 

    val linesToSave = source.drop(2).filter { 
    l => 
     l.split(" ").exists(nr => nrsSource2.contains(nr)) 
    } 

    val nrLines = linesToSave.length 
    val nrVariables = ??? //don't know what this is 

    //write linesToSave to a file 
} 

Не обязательно о том, что представляет nrVariables, но его должно быть легко вычислить из linesToSave.

+0

Я пытаюсь использовать этот метод фильтрации, и я не знаю, почему я снова получаю тот же файл 1. Он выглядит как 'exists (nr => nrsSource2.contains (nr))' становится истинным всегда! :(Btw, я проверил, что содержит 'nrsSource2', и на нем все выглядит нормально. У вас есть какая-то подсказка, почему? – user4712458

+0

@ user4712458 Я думаю, что это forAll, а не существует. Проверьте мой обновленный ответ – nmat

+0

метод' forall () ', похоже, работает с проблемой: когда число из' nrSource2' не найдено в 'source', то оно больше не удаляет/(не проверяет) в этих строках:/Оно исключает строки перед проверкой других значений из' nrSource2 ' – user4712458

0

Концептуально это должно быть чем-л, как следующее:

val file1: List[String] = // read file and getLines 
val file2: List[String] = // read file and getLines 

val result = file1.filter { line => 
    file2.contains(line) 
}