Comparing two files by the content in their lines in Scala

1.9k Views Asked by At

I have two files in .dimacs format, eg:

 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

and,

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

I want to compare file example_01.cnf with example_02.cnf such that, to extract only those lines from file example_01.cnf that have a similar value (in any of the lines) from file example_02.cnf, and to save the result in a new file e.g., example_result.cnf.

In this case, the example_result.cnf will look like:

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 

Eg., the lines 1 0, -5 1 0 and -6 1 0 are not in the resulting file because none of the numbers 1, 5, and 6 are in the example_02.cnf.

My current code is:

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()
      }

In this code I am not using the second file example_02.cnf yet. How I can compare these two files?

2

There are 2 best solutions below

8
On BEST ANSWER

Well, if you want to save lines form source1 that contains a number in any line of source2 this should work:

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
}

Not sure about what the nrVariables represents, but it should be easy to calculate from the linesToSave.

0
On

Conceptually it should be smth like following:

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

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