Java 字符串匹配算法道路匹配

1.标准格式为 街道名称,起始门牌号,结束门牌号,单双号
客户输入名称 例:南苏州路1400号
结果:匹配到标准信息
可能出现情况,输入信息中有多个街道名称等 南苏州路xx路路口1400号
在这里插入图片描述

    @Override
    public boolean gather() {
       //list 客户输入信息集
       //mapList 道路信息集
       //TT 信息实体类
        List<TT> newlist = ppjd(list, mapList);
        }

 private List<TT> ppjd(List<tt> list, List<Map> mapList) {
        List<TT> newlist = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            //将地址  拆分成 汉字和数字
            String verify = list.get(i);
            verify.replace(" ", "");
            //全部拆开
            List<String> lists = Stream.iterate(0, n -> ++n).limit(verify.length())
                    .map(n -> "" + verify.charAt(n))
                    .collect(Collectors.toList());
            //用来进行判断数字的
            String strNumbers = "0123456789";
            int length = 0;//定义索引下标
            String[] strs = new String[verify.length()];//再新建个数组,用来存放 当是连续数字时,把那个连续的数据当成一个数组
            boolean bool = true;
            //遍历拆开的字符串
            for (String str : lists) {
                int index = strNumbers.indexOf(str);
                if (index == -1) {//表示当前值不是数字
                    strs[length] = str;//直接把当前的值 赋值 给  数组
                    length++;//索引下标 自增
                    bool = true; // 锁开启
                } else {//表示当前值是数字
                    if (bool) {
                        strs[length] = str;
                        length++;
//                        sumInteter++;
                        bool = false;//锁关闭,使锁关闭的原因是当下一个字符是 也数字是运行下面else的操作
                    } else {  //当前值和前一个值也是数字, 就运行这步
                        //因为之前的索引自增了, 索引必须要-1  ,使用concat把数字链接到前一个值的尾部
                        strs[length - 1] = strs[length - 1].concat(str);
                    }
                }
            }
            //存放门牌号
            int mp = -1;
            for (String str : strs) {
                if (str != null) {
                    if (str.matches("\\d+")) {//纯数字
                        mp = Integer.parseInt(str);
                        break;
                    }
                }
            }
            //拆解 手写地址,和标准地址 进行比对
            //存放包含的 标准地址对象
            List<Map> mapList1 = new ArrayList<>();
//            //存放不包含的 数据对象
//            List<TT> ttlist2 = new ArrayList<>();
            //是否匹配到社区
            boolean ppd = false;
            //是否匹配成功Ftt
            boolean ppcg = false;
            for (int j = 0; j < mapList.size(); j++) {
                //将街道拆开
                String jd = mapList.get(j).get("街道名称").toString();
                jd.replace(" ", "");
                List<String> jdList = Stream.iterate(0, n -> ++n).limit(jd.length())
                        .map(n -> "" + jd.charAt(n))
                        .collect(Collectors.toList());
                //会出现一个地址中 有两个地址字段  例:新闸路石门二路口地面停车场内
                if (lists.containsAll(jdList)) {
                    mapList1.add(mapList.get(j));
                    ppd = true;
                }
            }
            //匹配到 社区
            if (ppd) {
                for (Map map : mapList1) {
                    map.get("");
                    //手写数据门牌号单双
//                    单号
                    if (mp != -1 && mp % 2 != 0 && "0".equals(map.get("单双号").toString())) {
                        if (Integer.parseInt(map.get("起始门牌号").toString()) <= mp && mp <= Integer.parseInt(map.get("结束门牌号").toString())) {
                            list.get(i).setCommitteeId(map.get("居委会ID").toString());
                            list.get(i).setRoadId(map.get("街道ID").toString());
                            newlist.add(list.get(i));
                            ppcg = true;
                            break;
                        }
                    }

                }
                //没有门牌号 或者匹配失败,就确定居委会
                if (!ppcg) {
                    //重名截取前四个进行比对  新闸路成都北路口   匹配成功跳出
                    for (int cs = 0; cs < verify.length() - 4; cs++) {
                        boolean cc = false;
                        for (Map map : mapList1) {
                            if (verify.substring(cs, cs+4).indexOf(map.get("街道名称").toString().replace(" ", "")) != -1) {
                                if (StringUtils.isNotEmpty(map.get("居委会ID").toString()) && StringUtils.isNotEmpty(map.get("街道ID").toString())) {
                                    list.get(i).setCommitteeId(map.get("居委会ID").toString());
                                    list.get(i).setRoadId(map.get("街道ID").toString());
                                    newlist.add(list.get(i));
                                    cc = true;
                                    break;
                                }
                            }
                        }
                        if(cc){
                            break;
                        }
                    }

//                    list.get(i).setCommitteeId(mapList1.get(0).get("居委会ID").toString());
//                    list.get(i).setRoadId(mapList1.get(0).get("街道ID").toString());
//                    newlist.add(list.get(i));
                }
//                return newlist;
            } else {
                for (int cs = 0; cs < verify.length() - 4; cs++) {
                    TT tt = cfpp(list.get(i), mapList, verify, newlist, cs, mp);
                    if (StringUtils.isNotEmpty(tt.getRoadId()) ) {
                        newlist.add(tt);
                        break;
                    }
                }

            }
        }
        return newlist;
    }

    private TT cfpp(TT tt, List<Map> mapList, String verify, List<TT> newlist, int cs, int mp) {
        // 1.截取0-4直接判断 改地址中 是否包含标准地址库地址
        //存放居委会能匹配到的数据
        List<Map> newlistmap = new ArrayList<>();
        boolean cg = false;
        for (int j = 0; j < mapList.size(); j++) {
            String jd = mapList.get(j).get("街道名称").toString();
            if (verify.substring(cs, cs + 4).indexOf(jd) != -1) {
                //包含 是否包含门牌
                //有门牌
                if (mp != -1 && Integer.parseInt(mapList.get(j).get("起始门牌号").toString()) <= mp && mp <= Integer.parseInt(mapList.get(j).get("结束门牌号").toString())) {
                    tt.setCommitteeId(mapList.get(j).get("居委会ID").toString());
                    tt.setRoadId(mapList.get(j).get("街道ID").toString());
                    break;
                }
                newlistmap.add(mapList.get(j));
            }
        }
        //没有门牌号能匹配到居委会   (都匹配不到就舍弃)
        if (!cg && newlistmap.size() > 0) {
            tt.setCommitteeId(newlistmap.get(0).get("居委会ID").toString());
            tt.setRoadId(newlistmap.get(0).get("街道ID").toString());
        }
        return tt;
    }



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
为了匹配字符串,可以使用经典的 KMP(Knuth-Morris-Pratt)算法。其基本思想是,在匹配过程中,如果出现不匹配的情况,我们应该避免回溯已经匹配的部分,而是利用已经匹配的信息快速地跳过一些无法匹配的字符。 以下是一个 Java 实现的示例代码: ```java public class KMPSubstringSearch { public static int search(String text, String pattern) { int N = text.length(); int M = pattern.length(); // 构造最长公共前后缀 lps 数组 int[] lps = new int[M]; int i = 1; int len = 0; while (i < M) { if (pattern.charAt(i) == pattern.charAt(len)) { lps[i++] = ++len; } else { if (len == 0) { lps[i++] = 0; } else { len = lps[len - 1]; } } } // 在文本中查找匹配 int j = 0; i = 0; while (i < N) { if (text.charAt(i) == pattern.charAt(j)) { i++; j++; } if (j == M) { return i - M; } else if (i < N && text.charAt(i) != pattern.charAt(j)) { if (j == 0) { i++; } else { j = lps[j - 1]; } } } return -1; } } ``` 在这个示例代码中,我们首先构造了一个最长公共前后缀 lps 数组,然后使用这个数组进行匹配。具体来说,我们维护两个索引 i 和 j,分别指向文本和模式字符串的当前位置,然后不断比较这两个位置上的字符。如果匹配成功,两个索引都向前移动一位;如果不匹配,我们应该尽量不回溯已经匹配的部分,而是通过 lps 数组快速地跳过一些字符。如果最终 j 能够到达模式字符串的末尾,说明匹配成功。否则,返回 -1 表示没有找到匹配的子串。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值