主页

题目要求统计abb字串格式。
输入:abcbcc
输出:8
输入:abbb
输出:3

下面是我做的对比,对于普通for循环和手写算法比较,输入5k个字符,手写算法用时为27ms,普通for循环用时43.773s,经测试,结果是一致的。
原理引入:ABABCB

第一次输入 A 当前map(字符计数器)中A为0
更新map表A个数=1,加入listMap(字符前个数)表索引A,并加入队列0,因为A前面没有字符。
 
第二次输入 B 当前map(字符计数器)中B为0
更新map表B个数=1,加入listMap(字符前个数)表索引B,并加入队列1,因为B前面有1个字符。
 
第三次输入 A 当前map(字符计数器)中A为1
更新map表A个数=2,遍历在listMap(字符前个数)表索引A队列,因为第一个A前面没有字符,所以也就不存在ABB格式。加入当前字符A前面除A以外的字符数【1】到listMap表A队列中.
 
第四次输入 B 当前map(字符计数器)中B为1
更新map表B个数=2,遍历在listMap(字符前个数)表索引B队列,因为第一个B前面有1个字符,所以也就存在1个ABB格式的子串,更新c(计数器)为1。再加入当前字符B前面除B以外的字符数【2】到listMap表B队列中.
 
第五次输入 C 当前map(字符计数器)中C为0
更新map表C个数=1,遍历在listMap(字符前个数)表索引C队列,因为C队列才开始,所以队列为0.再加入当前字符C前面除C以外的字符数【4】到listMap表C队列中.
 
第六次输入 B 当前map(字符计数器)中B为2
更新map表B个数=3,遍历在listMap(字符前个数)表索引B队列,因为第一个B前面有1个字符,第二个B字符前面有2个字符,所以也就存在【2+1】个ABB格式的子串,更新c(计数器)为4。再加入当前字符B前面除B以外的字符数【3】到listMap表B队列中.
 
 
所以最终ABB格式的子串个数为4.
A(第一个位置)B(第二个位置)B(第四个位置)
A(第一个位置)B(第二个位置)B(第六个位置)
A(第一个位置)B(第四个位置)B(第六个位置)
A(第三个位置)B(第四个位置)B(第六个位置)

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        String line = sc.next();
        long st=System.nanoTime();
        a3(line);
        long st1=System.nanoTime();
        a2(line);
        long st2=System.nanoTime();
        System.out.println("time compare:"+((st1-st)/1000000)+"ms|"+((st2-st1)/1000000)+"ms");
    }
    public static void a3(String a3){
        Map <Character,List<Integer>> listMap=new HashMap<>();//记录相同字符不同位置的前面非本字符的个数。
        Map<Character,Integer> map=new HashMap<>();//字符计数器
        int c=0;//ABB 统计
        for (int i = 0; i < a3.length(); i++) {
            char s=a3.charAt(i);                   //获取字符
            int count=map.getOrDefault(s,0)+1;     //获取表中存储得字符个数。
            map.put(s,count);                      //更新字符个数。
            List<Integer> t=listMap.get(s);        //获取该字符的队列
            if(t==null){t=new LinkedList<>();listMap.put(s,t);}//初始化队列

            if(t.size()>0){                        //如果该字符表里已经有1个了,就存在ABB。
                for (int k : t) {                  //遍历队列
                    c+=k;                          //计数器操作
                }
            }
            t.add((i+1)-count);                    //加入当前位置前面的字符个数并减去当前字符的个数。
        }
        System.out.println(c);                     //打印ABB的个数。
    }

    public static void a2(String line2){
        int t=0;
        for (int i = 0; i < line2.length()-2; i++) {
            for (int j = i+1; j < line2.length()-1; j++) {
                for (int k = j+1; k < line2.length(); k++) {
                    if(line2.charAt(i)!=line2.charAt(j) && 
                        line2.charAt(j)==line2.charAt(k)){
                        t++;
                    }
                }
            }
        }
        System.out.println(t);
    }
}

java算法 子串重复查找

版权属于:WANYL
作品采用:本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。
0

目录

来自 《Java ABB子串查找》
评论

WANYL

博主很懒,啥都没有
123 文章数
0 评论量
11 分类数
124 页面数
已在风雨中度过 3年289天15小时4分