Bläddra i källkod

公式相关:优化识别率

yangyj 2 år sedan
förälder
incheckning
82f9828813

+ 91 - 0
blade-service/blade-manager/src/main/java/com/mixsmart/utils/AhoCorasickFilter.java

@@ -0,0 +1,91 @@
+package com.mixsmart.utils;
+
+import java.util.*;
+/**
+ * @author yangyj
+ * @Date 2023/4/26 10:15
+ * @description 删除无效词汇
+ */
+public class AhoCorasickFilter {
+    private final TrieNode root;
+    private final char replaceChar;
+
+    public AhoCorasickFilter(String[] sensitiveWords, char replaceChar) {
+        this.root = new TrieNode();
+        this.replaceChar = replaceChar;
+        buildTrie(sensitiveWords);
+        buildFailPath();
+    }
+
+    public String filter(String text) {
+        StringBuilder sb = new StringBuilder(text);
+        TrieNode cur = root;
+        for (int i = 0; i < sb.length(); i++) {
+            char ch = sb.charAt(i);
+            while (cur != root && !cur.next.containsKey(ch)) {
+                cur = cur.fail;
+            }
+            if (cur.next.containsKey(ch)) {
+                cur = cur.next.get(ch);
+                if (cur.isEnd) {
+                    for (int j = i - cur.length + 1; j <= i; j++) {
+                        sb.setCharAt(j, replaceChar);
+                    }
+                    cur = root;
+                }
+            }
+        }
+        return sb.toString().replace("*","");
+    }
+
+    private void buildTrie(String[] sensitiveWords) {
+        for (String word : sensitiveWords) {
+            TrieNode cur = root;
+            for (char ch : word.toCharArray()) {
+                if (!cur.next.containsKey(ch)) {
+                    cur.next.put(ch, new TrieNode());
+                }
+                cur = cur.next.get(ch);
+            }
+            cur.isEnd = true;
+            cur.length = word.length();
+        }
+    }
+
+    private void buildFailPath() {
+        Queue<TrieNode> queue = new LinkedList<>();
+        for (TrieNode child : root.next.values()) {
+            queue.offer(child);
+            child.fail = root;
+        }
+        while (!queue.isEmpty()) {
+            TrieNode cur = queue.poll();
+            for (char ch : cur.next.keySet()) {
+                TrieNode next = cur.next.get(ch);
+                queue.offer(next);
+                TrieNode failNode = cur.fail;
+                while (failNode != root && !failNode.next.containsKey(ch)) {
+                    failNode = failNode.fail;
+                }
+                if (failNode.next.containsKey(ch)) {
+                    failNode = failNode.next.get(ch);
+                }
+                next.fail = failNode;
+            }
+        }
+    }
+
+    private static class TrieNode {
+        Map<Character, TrieNode> next;
+        TrieNode fail;
+        boolean isEnd;
+        int length;
+
+        public TrieNode() {
+            this.next = new HashMap<>();
+            this.fail = null;
+            this.isEnd = false;
+            this.length = 0;
+        }
+    }
+}

+ 40 - 4
blade-service/blade-manager/src/main/java/com/mixsmart/utils/FormulaUtils.java

@@ -12,11 +12,19 @@ import org.springblade.manager.dto.ElementData;
 import org.springblade.manager.dto.FormData;
 import org.springblade.manager.entity.Formula;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
 import java.math.BigDecimal;
+import java.nio.charset.StandardCharsets;
 import java.util.*;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
+import java.util.zip.Deflater;
+import java.util.zip.DeflaterOutputStream;
+import java.util.zip.Inflater;
+import java.util.zip.InflaterInputStream;
 
 /**
  * @author yangyj
@@ -317,17 +325,40 @@ public class FormulaUtils {
     /**从元素名称中解析项目名称*/
     public static final  Set<String> EX_WORD=new HashSet<String>(){{add("或");}};
     public static  String parseItemName(String eName){
-        String[] candidate= StringUtils.handleNull(eName).replaceAll("[\\t\\n\\s+]","").split("[((].+[))]|_");
+        String[] candidate= StringUtils.handleNull(eName).replaceAll("[\\t\\n\\s+]","").split("[((_]");
         if(candidate.length>0){
-            return Arrays.stream(candidate).map(s->s.replaceAll("[^\\u4e00-\\u9fa5]+","").replaceAll("(总数|抽测|实测|偏差|设计|合格)[率值]?","")).filter(s->!EX_WORD.contains(s)&&StringUtils.isNotEmpty(s)).collect(Collectors.joining());
+            return Arrays.stream(candidate).map(s->s.replaceAll("[^\\u4e00-\\u9fa5]+","").replaceAll("(在合格标准内|满足设计要求|质量评定|评定|判定|项目|总数|抽测|实测|偏差|设计|合格)[率值]?","")).filter(s->!EX_WORD.contains(s)&&StringUtils.isNotEmpty(s)).collect(Collectors.joining());
         }
         return eName;
     }
 
+    public static byte[] compress(String data) throws IOException {
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        DeflaterOutputStream dos = new DeflaterOutputStream(bos, new Deflater(Deflater.BEST_COMPRESSION));
+        dos.write(data.getBytes(StandardCharsets.UTF_8));
+        dos.close();
+        return bos.toByteArray();
+    }
+
+    public static String decompress(byte[] data) throws IOException {
+        ByteArrayInputStream bis = new ByteArrayInputStream(data);
+        InflaterInputStream iis = new InflaterInputStream(bis, new Inflater());
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        byte[] buffer = new byte[1024];
+        int len;
+        while ((len = iis.read(buffer)) > 0) {
+            bos.write(buffer, 0, len);
+        }
+        iis.close();
+        bos.close();
+        return new String(bos.toByteArray(), StandardCharsets.UTF_8);
+    }
+
 
 //    public static void main(String[] args) {
 //        List<String> list =Arrays.asList(
-//                "压 实 度 (%)下路床 特重、极重交通荷载等级 设计值"
+//                ""
+//                ,"压 实 度 (%)下路床 特重、极重交通荷载等级 设计值"
 //                ,"1△_压 实 度 (%)_下路床_轻、中及重交通 荷载等级_0.3m~0.8m_≧96_≧95_≧94_实测值或实测偏差值"
 //                ,"1△_压 实 度 (%)_下路提_轻、中及重交通 荷载等级_&gt;1.5m_≧93_≧92_≧90_实测值或实测偏差值"
 //                ,"1△_压 实 度 (%)_上路提_轻、中及重交通 荷载等级_0.8m~1.5m_≧94_≧94_≧93_实测值或实测偏差值"
@@ -341,7 +372,12 @@ public class FormulaUtils {
 //               ,"受力钢筋间距 (mm)同排 梁、板、拱肋及拱上建筑	合格率"
 //               ," 箍筋、构造钢筋、螺旋筋间距(mm)	设计值"
 //               ,"箍筋、构造钢筋、螺旋筋间距(mm)	合格率"
-//
+//                ,"实测项目_桩位 (mm)_群桩_≤100_质量评定_合格判定"
+//                 ,"实测项目_桩位 (mm)_群桩_≤100_实测值或实测偏差值"
+//                ,"实测项目_桩位 (mm)_排架桩_实测值或实测偏差值"
+//                ,"实测项目_桩位 (mm)_排架桩_质量评定_合格判定"
+//                ,"实测项目_桩位 (mm)_群桩_≤100_质量评定_合格率(%)"
+//                ,"实测项目_桩位 (mm)_排架桩_质量评定_合格率(%)"
 //        );
 //        list.stream().map(FormulaUtils::parseItemName).forEach(System.out::println);
 //    }

+ 21 - 25
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java

@@ -209,41 +209,37 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
     public void assessmentForm(){
         if(tec.getTableAll().stream().anyMatch(e->StringUtils.isEquals(e.getTableType(),5))){
             /*评定节点*/
-//            AppWbsTreeContractVO one =tec.getTableAll().get(0);
-//            List<String> ancestor=new ArrayList<>(Arrays.asList(one.getAncestors().split(",")));
-//            Collections.reverse(ancestor);
-//            FormulaDataBlock fdb = this.formulaDataBlockService.queryOption(Long.parseLong(one.getContractId()),Long.parseLong(ancestor.get(1)),0);
             FormulaDataBlock fdb = findFdb();
-            if(StringUtils.isEquals("[]",fdb.getVal())){
+            if(!StringUtils.isEquals("[]",fdb.getVal())){
                 List<ElementBlock> elementBlockList =JSON.parseArray(fdb.getVal(),ElementBlock.class);
                 Map<String, Measurement> itemsMap = new HashMap<>();
                 this.formDataMap.values().forEach(e->{
                     String eName=e.getEName();
-                    if(eName.contains("实测")&&!eName.contains("平均")){
+                    if(eName.contains("实测")&&!eName.contains("平均")&&!eName.contains("率")&&!eName.contains("判")){
                         String point  =FormulaUtils.parseItemName(eName);
                         Measurement measurement = itemsMap.computeIfAbsent(point,k->new Measurement(point));
-                        if(eName.contains("偏差")){
-                            measurement.setValue(e);
-                        }else if(eName.contains("率")){
-                            measurement.setPass(e);
-                        }else if(eName.contains("判")){
-                            measurement.setJudge(e);
-                        }
+                        measurement.setValue(e);
                     }
                 });
                 if(itemsMap.size()>0){
-                    itemsMap.values().forEach(i->{
-                        FormData vf=i.getValue();
-                        if(vf!=null){
-                            if(i.getPass()==null){
-                               i.setPass(tec.getFormDataMap().values().stream().filter(v->v.getTableName().equals(vf.getTableName())&&!v.getCode().equals(vf.getCode())).filter(v->v.getEName().contains(i.getPoint())&&v.getEName().contains("率")).findAny().orElse(null));
-                            }
-                            if(i.getJudge()==null){
-                                i.setJudge(tec.getFormDataMap().values().stream().filter(v->v.getTableName().equals(vf.getTableName())&&!v.getCode().equals(vf.getCode())).filter(v->v.getEName().contains(i.getPoint())&&v.getEName().contains("判")).findAny().orElse(null));
-                            }
-                        }
+                    tec.getFormDataMap().values().stream()
+                            .filter(v -> v.getEName().contains("率") || v.getEName().contains("判"))
+                            .forEach(v -> {
+                                itemsMap.values().stream()
+                                        .filter(i -> i.getPass() == null || i.getJudge() == null)
+                                        .filter(i -> {
+                                            FormData vf = i.getValue();
+                                            return vf != null && vf.getTableName().equals(v.getTableName()) && !vf.getCode().equals(v.getCode())&&FormulaUtils.similarity(v.getEName(),vf.getEName())>0.75;
+                                        }).max(Comparator.comparingDouble((Measurement i)->FormulaUtils.similarity(v.getEName(),i.getValue().getEName())))
+                                        .ifPresent(i->{
+                                               if (v.getEName().contains("率") && i.getPass() == null) {
+                                                   i.setPass(v);
+                                               } else if (v.getEName().contains("判") && i.getJudge() == null) {
+                                                   i.setJudge(v);
+                                               }
+                                         });
+                            });
 
-                    });
                     AtomicBoolean update= new AtomicBoolean(false);
                     itemsMap.values().stream().filter(Measurement::isMatching).forEach(t->{
                         ElementBlock g=null;
@@ -256,7 +252,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                            }
                         }
                         if(g==null){
-                            Optional<ElementBlock> op=   elementBlockList.stream().filter(w->FormulaUtils.similarity(w.getEName(),t.getPoint())>0.6).reduce((a, b) -> Comparator.<Double>reverseOrder().compare(FormulaUtils.similarity(a.getEName(),t.getPoint()), FormulaUtils.similarity(b.getEName(),t.getPoint())) <= 0 ? a : b);
+                            Optional<ElementBlock> op= elementBlockList.stream().filter(w->FormulaUtils.similarity(w.getEName(),t.getPoint())>0.6).reduce((a, b) -> Comparator.<Double>reverseOrder().compare(FormulaUtils.similarity(a.getEName(),t.getPoint()), FormulaUtils.similarity(b.getEName(),t.getPoint())) <= 0 ? a : b);
                             if(op.isPresent()){
                                 g=op.get();
                             }