【问题标题】:Comparing two files by the content in their lines in Scala通过 Scala 中的行中的内容比较两个文件
【发布时间】:2017-01-25 09:41:04
【问题描述】:

我有两个.dimacs 格式的文件,例如:

 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.cnfexample_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 行不在结果文件中,因为156 中没有一个数字在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。如何比较这两个文件?

【问题讨论】:

    标签: scala file comparison file-comparison filecompare


    【解决方案1】:

    好吧,如果你想保存来自 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 计算出来。

    【讨论】:

    • 我正在尝试使用这种过滤方法,但我不知道为什么我会再次获得相同的文件 1。看起来exists(nr =&gt; nrsSource2.contains(nr)) 总是会变成真的! :( 顺便说一句,我检查了 nrsSource2 包含的内容,它看起来一切正常。你有什么线索吗,为什么?
    • @user4712458 我认为它是 forAll 而不是存在。检查我的更新答案
    • 方法forall() 似乎可以解决一个问题:当source 中找不到来自nrSource2 的数字时,它会在这些行中删除/(不检查):/ 它在检查来自nrSource2 的其他值之前消除行。
    • @user4712458 可能我没看懂问题,为什么1 0不在example_result.cnf中? 0 出现在 source2 行中。我应该只检查每行的第一个数字吗?还是每行的前 2 个数字?
    • 我只需要选择第一个文件example_01.cnf 中包含第二个文件example_02.cnf 中的至少一个值/数字的那些行。所以,对不起,如果我解释得不够清楚,但是尽管文件example_01.cnf 中的哪一行和什么位置,文件example_02.cnf 的值是,应该选择并保存 whole 行在文件example_result.cnf.
    【解决方案2】:

    从概念上讲,它应该如下所示:

    val file1: List[String] = // read file and getLines
    val file2: List[String] = // read file and getLines
    
    val result = file1.filter { line => 
      file2.contains(line)
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-30
      • 2018-03-14
      • 1970-01-01
      相关资源
      最近更新 更多