0

我有一个来自数据库的实例列表,并且我正在考虑一些实例。我正在编写一个程序,它会给我尚未计算的实例数量;通过彼此“减去”列表来做到这一点。我看到一些实例出现在完整的数据库列表中,占列表中,并且仍然出现在错过的列表中,这对我来说意味着代码的减法部分是错误的。

此外,数据库有大约 31000 个元素,除了 300 之外几乎所有元素都被计算在内,只有大约 8 个被重复计算,这似乎很奇怪。这是我的减法过程,它从 2 个文件中读取并写入另一个文件。

这是代码:

proc checkDif {} {
    set fp [open "accounted_db.tcl" r]
    set file_data_accounted [read $fp]
    close $fp

    set fp [open "innovus_db.tcl" r]
    set file_data_db [read $fp]
    close $fp

    foreach elem $file_data_db {dict set y $elem 1}
    foreach elem $file_data_accounted {dict unset y $elem}
    set res [dict keys $y]

    set fileName "missed_db.tcl"
    set fileId [open $fileName "w"]
    foreach inst $res {
        puts $fileId $inst
    }
    close $fileId

    return [llength $res]
}
4

1 回答 1

0

如果您的数据是每行一个键(因为它在您的输出中)并且可能包含空格但不包含换行符(在键中),那么您应该更改输入代码以执行以下操作:

set fp [open "accounted_db.tcl" r]
set file_data_accounted [split [read $fp] "\n"]
close $fp

set fp [open "innovus_db.tcl" r]
set file_data_db [split [read $fp] "\n"]
close $fp

事实上,最好把这个小代码序列分解出来:

proc readLines {filename} {
    set fp [open $filename]
    set lines [split [read $fp] "\n"]
    close $fp
    return $lines
}

# Might as well factor out an efficient reverse operation at the same time
proc writeLines {filename lines} {
    set fp [open $filename "w"]
    puts $fp [join $lines "\n"]
    close $fp
}

proc checkDif {} {
    set file_data_accounted [readLines "accounted_db.tcl"]
    set file_data_db [readLines "innovus_db.tcl"]

    set y {};  # In case file_data_db is empty; unlikely, but paranoia is good…
    foreach elem $file_data_db {
        dict set y $elem 1
    }
    foreach elem $file_data_accounted {
        dict unset y $elem
    }

    set res [dict keys $y]
    writeLines "missed_db.tcl" $res
    return [llength $res]
}

如果不这样做split,您从一开始就依赖数据是真正的 Tcl 列表。可能是......但只有当你生成它并且只是希望一切正常不是推荐的方法(在大规模代码中)。通过显式拆分(实际上非​​常快),您可以避免数据中的空格、反斜杠和大括号等问题;根据我的经验,它们通常不会出现在测试数据中,但更常出现在生产数据中……</p>

于 2019-09-14T11:54:24.717 回答