[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[文本处理] [已解决]试题0.8相似度的题目去除重复?

我在各个网上面收集了很多试题,里面肯定有重复的,我想把重复的删除了。如果用论坛上面删除重复行的办法必须每一行完全一样才能删除。但是每个网站的排版又不尽相同,里面标点符号可能不同,发布的格式也有区别。

举例子:
315、发现火灾,应拨打哪个电话报警?(119)
402、发现火灾,应拨打哪个电话报警?(119)
412、发现火灾,应拨打哪个电话报警?(119)
414、发现火灾,应拨打哪个电话报警?(119)
1113、发现火灾,应拨打哪个电话报警?(119)
706、饮酒后驾驶机动车的,一次记(12)分。
1674、饮酒后驾驶机动车的,一次记___分。(12)
532、水上遇险求救电话号是(12395)。
326、水上遇险求救电话号是。(12395)
1268、水上遇险求救电话号是()(12395)
85、水上遇险求救电话号是(12395)

处理后就得到:

315、发现火灾,应拨打哪个电话报警?(119)
706、饮酒后驾驶机动车的,一次记(12)分。
532、水上遇险求救电话号是(12395)。




现在需要对以上合并出来的txt文档进行出来,最终只留下唯一的一行。(注:以上只是举例,真正复制回来试题的可能有上千条。)

http://www.bathome.net/viewthread.php?tid=29652&highlight=%CF%E0%CB%C6

和这个贴子相似,
以下为要处理的文件的一部分

最后引用crlf版主的代码了,函数部分是引用了别人的在原帖中有,运行用了2天时间,最后结果是4200行得出了1400行,与我手动排序后去得结果1700行,相差了300多行。
这个办法太慢,慎用
  1.     Const input = "输入.txt"
  2.     Const output = "输出.txt"
  3.     Const isDebug = False
  4.     Const length = 4
  5.     t=Timer
  6.     Set fso = CreateObject("Scripting.FileSystemObject")
  7.     Set ts = fso.OpenTextFile(input,1)
  8.     ar = Split(ts.ReadAll,vbCrLf)
  9.     For i=UBound(ar) To 1 Step -1
  10.     If Not test(ar,i) Then ar(i)=""
  11.     Next
  12.     Set ts = fso.CreateTextFile(output,1)
  13.     For Each a In ar
  14.     If Len(a) Then ts.WriteLine a
  15.     Next
  16.     If isDebug Then ts.WriteLine timer-t
  17.     Function test(ar,i)
  18.     Dim j,length
  19.    
  20.         For j=0 To i-1
  21.             length = Len(ar(i))
  22.             If Len(ar(j))>Len(ar(i)) Then length = Len(ar(j))
  23.             If GetLevenshteinDistince(ar(i), ar(j)) > Sin(2/(Sqr(length)+5)) Then
  24.              test = False
  25.     Exit Function
  26.             End If
  27.         Next
  28.         test = True
  29.     End Function
  30.     Function GetLevenshteinDistince(str1, str2)        '函数引用自:http://bbs.bathome.net/thread-27991-1-1.html
  31.             Dim x, y, A, B, C, K
  32.             Dim l1,l2
  33.             Dim Matrix()
  34.             l1 = l2 = 0
  35.             If Len(str2)>=length Then l1=Len(str2)-length+1
  36.             If Len(str1)>=length Then l2=Len(str1)-length+1
  37.             
  38.             ReDim Matrix(l2, l1)
  39.             
  40.             '初始化第一行和第一列
  41.             For x = 0 To UBound(Matrix, 1)
  42.                     Matrix(x, 0) = x
  43.             Next
  44.             For y = 0 To UBound(Matrix, 2)
  45.                     Matrix(0, y) = y
  46.             Next
  47.             '填充矩阵
  48.             For x = 1 To UBound(Matrix, 1)
  49.                     For y = 1 To UBound(Matrix, 2)
  50.                             If (Mid(str1, Matrix(0, y), 4) = Mid(str2, Matrix(x, 0), 4)) Then
  51.                                     C = Matrix(x -1 ,y - 1)
  52.                             Else
  53.                                     C = Matrix(x -1 ,y - 1) + 1
  54.                             End If
  55.                            
  56.                             A = Matrix(x - 1, y) + 1
  57.                             B = Matrix(x, y - 1) + 1
  58.                            
  59.                             If (A =< B and A =< C) Then Matrix(x, y) = A
  60.                             If (B =< C and B =< A) Then Matrix(x, y) = B
  61.                             If (C =< A and C =< B) Then Matrix(x, y) = C
  62.                     Next
  63.             Next
  64.             
  65.             '计算 LD 值
  66.             If (Len(str1) > Len(str2)) Then
  67.                     K = Len(str1)-length+1
  68.             Else
  69.                     K = Len(str2)-length+1
  70.             End If
  71.             GetLevenshteinDistince = 1 - (Matrix(l2, l1) / K)
  72.     End Function
复制代码

本帖最后由 zhangop9 于 2019-10-31 08:52 编辑

本人的系统旧,是winxp所以上面下载的tmp2.exe跑不起来

POWERSHELL也用不了,只能用最基本的dos或者vbs

TOP

本帖最后由 bailong360 于 2019-10-30 19:59 编辑

回复 12# bailong360

这个阈值感觉不好找, 除非先把文本按长度分类一下

可能根据公共子序列长度来判定相似度会更好一点

或者干脆不分词其实也行...

TOP

题库生成小程序,功能大致是:导入数据-整理剔重-生成拼音索引-生成数据文件.

TOP

简单写了一个
  1. use bk_tree::{BKTree, Metric};
  2. use jieba_rs::Jieba;
  3. use lazy_static::lazy_static;
  4. use regex::Regex;
  5. use simhash::simhash_stream;
  6. use std::borrow::Cow;
  7. use std::fs::File;
  8. use std::io::{self, BufRead, BufReader};
  9. struct Hamming;
  10. impl Metric<u64> for Hamming {
  11.     fn distance(&self, a: &u64, b: &u64) -> u64 {
  12.         (a ^ b).count_ones() as u64
  13.     }
  14. }
  15. fn strip(s: &str) -> Cow<str> {
  16.     lazy_static! {
  17.         static ref RE: Regex = Regex::new(r"[^\u4e00-\u9fa5]+").unwrap();
  18.     }
  19.     RE.replace_all(s, "")
  20. }
  21. fn strip_file(path: &str, tolerance: u64) -> Result<(), io::Error> {
  22.     let jieba = Jieba::new();
  23.     let mut bk_tree = BKTree::new(Hamming);
  24.     let file = BufReader::new(File::open(path)?);
  25.     for line in file.lines() {
  26.         let line = line?;
  27.         let stripped = strip(&line);
  28.         let words = jieba.cut(&stripped, false);
  29.         let hash = simhash_stream(words.into_iter());
  30.         if bk_tree.find(&hash, tolerance).count() == 0 {
  31.             println!("{}", line);
  32.             bk_tree.add(hash);
  33.         }
  34.     }
  35.     Ok(())
  36. }
  37. fn main() {
  38.     let args = std::env::args().collect::<Vec<String>>();
  39.     if args.len() != 3 {
  40.         println!("Usage: {} FILENAME TOLERANCE", args[0]);
  41.     } else {
  42.         match strip_file(&args[1], args[2].parse::<u64>().unwrap()) {
  43.             Err(e) => eprintln!("ERROR:\n{}", e),
  44.             _ => (),
  45.         }
  46.     }
  47. }
复制代码
binary 下载地址: https://send.firefox.com/downloa ... -VFiI0I4NP9Rh7rnnXg

用法举例 tmp2.exe test.txt 16
16 是最高能容忍的相似度, 最高 64

试了一下效果还行, 没去掉的一般都是省略了大段文字的缘故
举例
  1. 17、集成电路自1959年被发明以来,……如我国华为公司设计的手机芯片“麒麟980”就采用了(7)纳米的最新工艺。
  2. 371、集成电路自1959年被发明以来,其发展的总趋势是:在单位面积的芯片上集成的电子元件越来越多,而连接这些元器件的线宽却越来越窄。集成电路现在正在向更窄的线宽迈进。如我国华为公司设计的手机芯片“麒麟980”就采用了()纳米的最新工艺。(7)
复制代码
只支持 UTF-8 文件
1

评分人数

    • zhangop9: 用不了,还是谢老大了技术 + 1

TOP

回复 10# zhangop9


试试这样执行6楼的代码:
http://bbs.bathome.net/thread-31071-1-1.html

如果遇到问题,把你的测试用例、测试结果打包上传让他帮你再看看。
我帮忙写的代码不需要付钱。如果一定要给,请在微信群或QQ群发给大家吧。
【微信公众号、微信群、QQ群】http://bbs.bathome.net/thread-3473-1-1.html
【支持批处理之家,加入VIP会员!】http://bbs.bathome.net/thread-67716-1-1.html

TOP

我不会那种代码,所以没有试。
我引用的贴子那个vbs 版试过了,用了2天时间,4200行去重后,得1400,
实际情况我手动通过排序后去重,有1700行,相差了300行。

TOP

没完成可以回帖说一遍, 上面有人给了代码, 执行效果怎么样? 哪里需要改进?

什么都不说, 只标一句"还没有完成", 也太不礼貌了吧?

TOP

看标题还以为是真的通用相似文本的去重
深感样本的重要性

TOP

本帖最后由 zhangop9 于 2019-10-29 19:05 编辑

谢谢楼上老大

TOP

本帖最后由 ivor 于 2019-10-29 19:49 编辑

批处理中运行
  1. powershell "gc 输入.txt | group {([regex]::Matches($_,'[\u4e00-\u9fa5]+')).Value -join ''} | %{$_.Group[0]}"
复制代码
#&cls&@powershell "Invoke-Expression ([Io.File]::ReadAllText('%~0',[Text.Encoding]::UTF8))" &pause&exit

TOP

回复 3# zhangop9


    你这个问题比那个代码解决的问题复杂太多太多啦
我帮忙写的代码不需要付钱。如果一定要给,请在微信群或QQ群发给大家吧。
【微信公众号、微信群、QQ群】http://bbs.bathome.net/thread-3473-1-1.html
【支持批处理之家,加入VIP会员!】http://bbs.bathome.net/thread-67716-1-1.html

TOP

本帖最后由 zhangop9 于 2019-10-29 16:25 编辑

最好能用vbs,解决,dos看不懂,总行数4200用我引用的那个代码太慢了

TOP

一两段代码恐怕搞不定,这需要AI
我帮忙写的代码不需要付钱。如果一定要给,请在微信群或QQ群发给大家吧。
【微信公众号、微信群、QQ群】http://bbs.bathome.net/thread-3473-1-1.html
【支持批处理之家,加入VIP会员!】http://bbs.bathome.net/thread-67716-1-1.html

TOP

返回列表