算法入门六:字符串:

算法入门六:字符串:

引言:

​ 在小组的安排下,这个暑假我们统一学习三个星期的算法,在这里让我感觉最大的感受是,前面有人引你入门真的好,可以少走很多的冤枉路,可以快速增长自己的能力和水平,但后续就要求自己自主的学习,因为别人的路线毕竟是别人的,不可能完全的适合自己的,但入门系列是每一个程序员或爱好算法的同学的必经之路,入门系列就是基础阶段,只有将基础打好,后面才能走的更远更好。在完成入门系列专项训练之后,我将自己做的题和做题过程中遇到的问题及解题思路总结成笔记。

​ 记得上数据结构的时候老师说过,数据结构好比是武林高手的内功,往往刚修炼的时候内功比较的弱,但当我们持之以恒的练习,我们终将练就一身内功成就宗师。加油!

字符串:

​ 计算机并不仅仅能够处理数学问题,还可以用来处理文字,比如写文章、处理代码、记录信息等等……如果需要将各种语句记录在计算机中,就要用到字符串或者字符数组。

我们已经在最开始的地方尝试输出过"I love Luogu" 的字符串,也介绍过单个字符和数字对应的 ASCII 编码。在这一章会介绍字符串的存储和处理的方法。同时也初步接触了 STL,这使得可以“站在前人的肩膀上”完成程序,简化编程的难度。

1.洛谷 p5733 Java 自动修正

image-20220127145036249

AC代码:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str = sc.next();//输入一串字符串
        char[] array = str.toCharArray();//将输入的字符串变成数组

        //遍历字符串数组,最每一个元素进行判断
        for (int i = 0; i < array.length; i++) {
            if (array[i] >= 'a' && array[i] <='z'){
                array[i] = (char)(array[i] -('a' - 'A'));//'a' - 'A':获得字母大写和小写之间的差值。ASCALL
            }
        }
        for (int i = 0; i < array.length; i++) {//遍历输出数据
            System.out.print(array[i]);
        }
    }
}

本题重点:

  • 将输入的字符串转换为字符数组(char)
  • char类型和int之间的相互转换,int转char需要强转实现。
  • 了解ASCALL表

2.洛谷 p1914 Java 小书童–凯撒密码

image-20220127193714762

AC代码:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        String str = sc.next();//输入字符串

        char[] array = str.toCharArray();//将字符串变成char类型的字符数组
        for (int i = 0; i < array.length; i++) {//遍历整个字符数组
            for (int j = 0; j < n; j++) {//让每一数自增n次
                array[i]++;
                if (array[i] > 'z'){//若自增后元素大于‘z’,则从‘a'开始
                    array[i] = 'a';
                }
            }
        }
        for (int i = 0; i < array.length; i++) {
            System.out.print(array[i]);
        }
    }
}

本题重点:

  • 当一个字母向后移动的距离超过“z”之后,需要从a开始
  • char型字符自增还是字符型,不用转型

3.洛谷 p5015 Java 标题统计

image-20220127194619361

AC代码:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();//使用键盘输入,包含了空格和换行等
        int count = 0;

        char[] array = new char[str.length()+1];
        //将字符串中的每个字符单独的存在array数组中
        for (int i = 0; i < str.length(); i++) {
            array[i] = str.charAt(i);
        }

        //遍历数组,判断字符是否时英文字母带小写,数字0-9;
        for (int i = 0; i < array.length; i++) {
            if ((array[i] >= 'a' && array[i] <= 'z')
                    || (array[i] >= 'A' && array[i] <= 'Z')
                    || (array[i] >= 48 && array[i] <= 57)
            ) {
                count++;//符合的累加
            }
        }
        System.out.println(count);
    }
}

本题重点:

  • 获得字符串内的每一个数组
  • 判断数组内的每一个字符是否符合要求,注意char类型的0-9ASCALL对应的是 48 - 57
  • 大家可以多看看ASCALL表中数字0-9,小写字母a-z,大写字母A-Z;

4.洛谷 p5734 Java 文字处理软件(可以多理解代码中的方法)

image-20220127195341628

AC代码:


import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = Integer.parseInt(sc.nextLine());
        text = sc.nextLine();
        String[] result = new String[n];
        for (int i = 0; i < n; i++) {
            result[i] = getResult(sc.nextLine());
        }
        for (String s : result) {
            System.out.println(s);
        }
    }
    //定义一个初始的字符串 全局的;
    private static String text = "";

    //条件一:后接插入,在文档后面插入字符串 str,并输出文档的字符串。
    private static void append(String append_doc) {
        text = text + append_doc;
    }

    //条件二:截取文档部分
    private static void cut(int from, int range) {
        text = text.substring(from, from+range);
    }

    //条件三:插入片段
    private static void insert(int from, String insert_doc) {
        String head = text.substring(0, from);
        String rear = text.substring(from);
        text = head + insert_doc + rear;
    }

    //条件四:查找子串
    private static int search(String search_key) {
        return text.indexOf(search_key);
    }

    //条件判断:
    private static String getResult(String command) {
        String[] arr = command.split(" ");//以空格为界限分割;
        if (command.startsWith("1")) {//startsWith :判断字符串以什么开头。
            append(arr[1]);
            return text;
        } else if (command.startsWith("2")) {
            cut(Integer.parseInt(arr[1]), Integer.parseInt(arr[2]));
            return text;
        } else if (command.startsWith("3")) {
            insert(Integer.parseInt(arr[1]), arr[2]);
            return text;
        } else {
            return Integer.toString(search(arr[1]));
        }
    }
}

本题重点:

  • 本题稍微复杂一点,但是我们按照题意一步一步的走就可以解决此题
  • 代码中涉及到的java方法较多,可以多理解学习

5.洛谷 p1765 java 手机

image-20220127200104353

AC代码:(非常暴力的解法)

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String a = sc.nextLine();
        char[] str = a.toCharArray();//将字符串转换成数组,本题使用了nextLine:所以包括空格,空格也要按一下。
        int count = 0;
        for (int i = 0; i < str.length; i++) {
            if (str[i] == ' ') {
                count ++;
            }
            if (str[i] == 'a') {
                count ++;
            }
            if (str[i] == 'b') {
                count += 2;
            }
            if (str[i] == 'c') {
                count += 3;
            }
            if (str[i] == 'd') {
                count ++;
            }
            if (str[i] == 'e') {
                count += 2;
            }
            if (str[i] == 'f') {
                count += 3;
            }
            if (str[i] == 'g') {
                count ++;
            }
            if (str[i] == 'h') {
                count += 2;
            }
            if (str[i] == 'i') {
                count += 3;
            }
            if (str[i] == 'j') {
                count ++;
            }
            if (str[i] == 'k') {
                count += 2;
            }
            if (str[i] == 'l') {
                count += 3;
            }
            if (str[i] == 'm') {
                count ++;
            }
            if (str[i] == 'n') {
                count += 2;
            }
            if (str[i] == 'o') {
                count += 3;
            }
            if (str[i] == 'p') {
                count ++;
            }
            if (str[i] == 'q') {
                count += 2;
            }
            if (str[i] == 'r') {
                count += 3;
            }
            if (str[i] == 's') {
                count += 4;
            }
            if (str[i] == 't') {
                count ++;
            }
            if (str[i] == 'u') {
                count += 2;
            }
            if (str[i] == 'v') {
                count += 3;
            }
            if (str[i] == 'w') {
                count ++;
            }
            if (str[i] == 'x') {
                count += 2;
            }
            if (str[i] == 'y') {
                count += 3;
            }
            if (str[i] == 'z') {
                count += 4;
            }
        }
        System.out.print(count + " ");
    }
}

本题重点:

  • 将所有的可能罗列出来进行计算。
  • 如果使用next();输入字符串的时候,遇到空格就结束,所以使用nextLine();使用toCharArray()将字符串转为数组。

6.洛谷 p3741 java honoka的键盘

image-20220127200809421

AC代码:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int sum = 0;
        String str = sc.next();//输入字符串
        while(str.contains("VK")){//使用contains方法看字符串中是否包含VK,若有累加,并且将其置换成其他的数据
           //replaceFirst() 方法使用给定的参数 replacement 替换字符串第一个匹配给定的正则表达式的子字符串。
            //循环操作,将所有的vk都进行计数和置换,
            str = str.replaceFirst("VK","CC");
            sum++;
        }
        //前面循环之后,剩下的v和k是组成不了vk的,担忧vv和kk,只能改变一个,若有置换一个就行了。
        if (str.contains("VV") || str.contains("KK")){
            sum++;
        }
        System.out.println(sum);
    }
}

本题重点:

  • 使用contains()方法,查看字符串中是否包含某些东西。
  • 使用replaceFirst() 方法使用给定的参数 replacement 替换字符串第一个匹配给定的正则表达式的子字符串。

7.洛谷 p1321 java 单词覆盖还原

image-20220127201641664

AC代码:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();

        int boy = 0,girl = 0;//分别累加boy和girl出现的次数
        char[] a = new char[300];
        for (int i = 0; i < str.length(); i++) {
            a[i] = str.charAt(i);//获得字符串中的每一个字符并赋值给数组
        }
        for (int i = 0; i <= str.length(); i++) {//遍历字符串中的每一个字符
            if (a[i]=='b'||a[i+1]=='o'||a[i+2]=='y')//判断连着的三个字母是否为b、o、y
                boy++;//boy计数器加一
            if (a[i]=='g'||a[i+1]=='i'||a[i+2]=='r'||a[i+3]=='l')//判断连着的三个字母是否为g、i、r、l
                girl++;//girl计数器加一
        }
        System.out.println(boy+"\n"+girl);
    }
}

本题重点:

  • 判断字母是boy和girl并累计他们的个数。
  • 获得字符串中的每一个字符,使用charAt();

8.洛谷 p1200 java 你的飞碟在这儿

image-20220127205744448

AC代码:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str1 = sc.next();
        String str2 = sc.next();

        char[] a = str1.toCharArray();
        char[] b = str2.toCharArray();

        int sum1 =1, sum2 = 1;//sum1 :彗星的累乘变量  sum2:队伍的累乘变量
        for (int i = 0; i < str1.length(); i++) {//累乘彗星数值
            sum1 *= (a[i] - 64);//char类型转int型
        }
        for (int i = 0; i < str2.length(); i++) {//同上
            sum2 *= (b[i] - 64);
        }

        int n = sum1 % 47,m = sum2 % 47;//各自得到余数比较
        if(n == m){
            System.out.println("GO");
        }else{
            System.out.println("STAY");
        }
    }
}

本题重点:

  • 掌握几个方法:求余,char类型转int类型,将字符串转换成数组等

9.洛谷 p1597 java 语句解析

image-20220127211532955

AC代码:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();

        int a = 0,b =0,c = 0;
        char[] arr = str.toCharArray();
        for (int i = 0; i < str.length(); i+= 5) {
            //当被复制的字符为‘a’时及四种可能
            if (arr[i] == 'a'){
                if(arr[i+3]=='a')
                    a = a;
                else if(arr[i+3]=='b')
                    a=b;
                else if(arr[i+3]=='c'){
                    a=c;
                } else{
                    a=arr[i+3]-'0';//char类型转int类型
                }
            }
             //当被复制的字符为‘b’时及四种可能
            if(arr[i]=='b') {
                if(arr[i+3]=='b')
                    b = b;
               else if(arr[i+3]=='a'){
                    b=a;
                } else if(arr[i+3]=='c'){
                    b=c;
                }
                else {
                    b = arr[i + 3] - '0';
                }
            }
             //当被复制的字符为‘c’时及四种可能
            if(arr[i]=='c') {
                if(arr[i+3]=='c')
                    c = c;
               else if(arr[i+3]=='a'){
                    c=a;
                } else if(arr[i+3]=='b'){
                    c=b;
                } else{
                    c=arr[i+3]-'0';
                }
            }
        }
        System.out.println(a + " " + b + " " + c);
    }
}

本题重点:

  • 各种可能的判断,char类型与int类型之间的转换,数组的使用,将字符串变成数组。

10.洛谷 p1125 Java 苯小猴

image-20220128085543128

AC代码:

import java.util.Arrays;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc =new Scanner(System.in);
        String str = sc.nextLine();
        int[] count = new int[26];//数组的范围是26;对应26为英文字母

        for (char c: str.toCharArray()) {//遍历字符串,让每一个字符-‘a’,在数组中对应的位置自增。
            count[c - 'a'] ++;
        }
        Arrays.sort(count);//通过数组的升序方法升序。

        int maxn = 0;
        for (int i = 0; i < 26; i++) {//遍历获得最大的那个差值
            if (count[i] != 0){
                maxn = count[25] - count[i];
                break;
            }
        }
        if (maxn == 0 || maxn == 1) {//特殊情况事先判断一下。
            System.out.println("No Answer\n0");
            return;
        }
        for (int i = 2; i < maxn; i++) {//判断差值是否是是质数
            if (maxn % i == 0) {
                System.out.println("No Answer\n0");
                return;
            }
        }
        System.out.println("Lucky Word");
        System.out.println(maxn);
    }
}

本题重点:

  • 统计字母出现的次数并求取出现次数最大的数和出现次数最小的数的差值。
  • 质数判断
  • 注意0和1特殊情况

11.洛谷 p1957 Java 口算练习题

image-20220128091047950

AC代码:

import java.util.Scanner;

public class Main {
        public static void main(String[] args){
            Scanner sc = new Scanner(System.in);
            int n = Integer.parseInt(sc.nextLine());//这个就是输入i值,只是想用其他的方法实现
            String text = "";//中间变量text
            for (int i = 0; i < n; i++) {//遍历每一条数据
                String a = sc.nextLine(),count = "";//输入每一行的数据
                String[] b= a.split(" ");//使用split(“ ”)将输入的字符串按照空格分成数组
                int f , g;
                if (a.startsWith("a")) {//使用startWith来判断当前行是否是a开头
                    text = "a";//若是,将text赋值为a
                    f = Integer.parseInt(b[1]);
                    g = Integer.parseInt(b[2]);
                } else if (a.startsWith("b")) {//同上
                    text = "b";
                    f = Integer.parseInt(b[1]);
                    g = Integer.parseInt(b[2]);
                } else if (a.startsWith("c")) {//同上
                    text = "c";
                    f = Integer.parseInt(b[1]);
                    g = Integer.parseInt(b[2]);
                } else {//若都不是,不用赋值,会自动使用上一次的text
                    f = Integer.parseInt(b[0]);
                    g = Integer.parseInt(b[1]);
                }
                switch (text) {//判断是那种可能,让后输出对应的输出格式
                    case "a":
                        count = f + "+" + g + "=" + (f+g);
                        break;
                    case "b":
                        count = f + "-" + g + "=" + (f-g);
                        break;
                    case "c" :
                        count = f + "*" + g +"=" + (f*g);
                        break;
                }
                System.out.println(count + "\n" + count.length());
            }
        }
    }

本题重点:

  • 使用中间变量,让没有a,b,c开头的数据使用上一次的数据
  • 使用switch来输出不同格式的语句
  • 使用到了startWith()和split()方法

12.洛谷 p1308 Java 统计单词数

image-20220128092101268

AC代码:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String a = sc.nextLine().toLowerCase();//不区分大小写,所以使用toLowerCase()方法输入的单词变成小写
        String b = sc.nextLine().toLowerCase();//将文章语句全部变成小写
        String[] c= b.split(" ");

        int count = 0,index = 0;//
        boolean flag = true;
        for (int i = 0; i < c.length; i++) {
            if (c[i].equals(a)){
                count++;
                flag = false;
            }
            if (flag){
                index += c[i].length() + 1;
            }
        }

        if (count > 0){
            System.out.println(count +" "+ index);
        }else{
            System.out.println(-1);
        }
    }
}

本题重点:

  • 使用Java自带的toLowerCase()将所有的单词字母变成小写的。
  • 空格也要计算上,所以累加各个单词字符时加一个1;

13.洛谷 p1553 Java 数字反转

image-20220128102703247

AC代码:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();
        String[] a = new String[2];
        String symbol = "";
        //判断输入的字符串是那种数
        if(str.contains(".")){
            symbol = ".";//小数
        }else if(str.contains("/")){
            symbol = "/";//分数
        }else if(str.contains("%")){
            symbol = "%";//百分数
        }else{
            symbol=null;//整数
        }
        //判断是什么数然后反转
        if(symbol == null){//判断数据包含的符号,然后根据符号来计算不同的反转
            character(str); 
        }else if(symbol.equals("%")){//根据 % 来分割字符串
            character(str.substring(0,str.length()-1));
            System.out.print("%");
        }else if(symbol.equals("/")){
            a = str.split("/");//根据 / 来分割字符串
            character(a[0]);
            System.out.print("/");
            character(a[1]);
        }else{
            a = str.split("\\.");//根据.来分割字符串
            character(a[0]);
            System.out.print(".");
            character(a[1]);
        }
    }
    public static void character(String str){

        int front = -1,back = -1;
        //获得非零的首坐标
        for (int i = 0; i < str.length(); i++) {
            if(str.charAt(i)!='0'){
                front=i;
                break;
            }
        }
        //获得非零的尾坐标
        for(int i=str.length()-1;i>=0;i--){
            if(str.charAt(i)!='0'){
                back=i;
                break;
            }
        }
        //如果都是零的话直接输出零
        if(front==-1){
            System.out.print("0");
            return;
        }
        //获得反转后的数字
        for (int i = back; i >= front; i--) {
            System.out.print(str.charAt(i));
        }
    }
}

本题重点:

  • 本题的数据量较大,需耐心处理,注意细节部分
  • 反转数字的时候,注意开始和结束包含有零的部分
  • split(),contains()的使用

14.洛谷 p1603 Java 斯洛登的密码

image-20220128103723149

AC代码:

/*
* 这道题自己琢磨了好久没有做出来,所以在网上找解解题方法,偶然间看到一篇题解,过程虽然简洁,但java方法的运用和思想挺好的
* 1.先将所有的英文数字和阿拉伯数字的平方求余对应,这时候用到了map的键值对
* 2.将输入的字符串通过trim()去掉首尾的空格,然后再使用split("\\s+")通过空格等为边界将字符串变成想要的单词数组。
* 3.在通过containsKey这个函数来检验输入的数据中是否有题中提到的那些单词,如果有就将对应的数据加到list链表中。
* 4.定义一个StringBuffer的字符串,这个字符串是可以通过append追加的。最后通过toString变成String类型
* */
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc =new Scanner(System.in);
        String[] words = sc.nextLine().trim().split("\\s+");

        //直接将对应的英文数字对应的数字平方根在求余。10和20求余后为零省略
        Map<String,String> map = new HashMap<>(25);
        map.put("one",       "01");
        map.put("another",   "01");
        map.put("two",       "04");
        map.put("three",     "09");
        map.put("four",      "16");
        map.put("five",      "25");
        map.put("six",       "36");
        map.put("seven",     "49");
        map.put("eight",     "64");
        map.put("nine",      "81");
        map.put("eleven",    "21");
        map.put("twelve",    "44");
        map.put("thirteen",  "69");
        map.put("fourteen",  "96");
        map.put("fifteen",   "25");
        map.put("sixteen",   "56");
        map.put("seventeen", "89");
        map.put("eighteen",  "24");
        map.put("nineteen",  "61");
        map.put("a",         "01");
        map.put("both",      "04");
        map.put("first",     "01");
        map.put("third",     "09");
        map.put("second",    "04");
        List<String> list = new ArrayList<>();

        for (String i: words) {
            if (map.containsKey(i)) {
                list.add(map.get(i));
            }
        }
        if (list.isEmpty()) {
            System.out.println(0);
        }
        //StringBuilder:可以追加字符的字符串,有线程保护,还有一个没有线程保护的时StringBuffer;
        StringBuilder str = new StringBuilder();
        //给链表中的数据进行自然的排序
        list.sort(Comparator.naturalOrder());//将集合内部进行排序;
        for (String i : list) {//遍历集合,将所有的字符累加在str上组成最小的数字
            str.append(i);
        }
        String result = str.toString();
        if (result.startsWith("0")) {//把这些两位数按数位排成一行,组成一个新数,如果开头为 0,就去 0。
            result = result.substring(1);
        }
        System.out.println(result);
    }
}

本题重点:

  • 将所有的数据实现存入map集合中,然后将符合要求的数字存入另外的集合中,判断此集合是否为空。为空的话直接输出0,不为空的话使用list.sort(Comparator.naturalOrder());//将集合内部进行排序;在判断拼接的字符串头部是否含有0;有的话去掉。
  • 这道题涉及很多的方法的使用,需要大家的注意:
    • list.sort(Comparator.naturalOrder());//将集合内部进行排序;
    • String[] words = sc.nextLine().trim().split("\s+");将输入的字符串按照空格换行等分成一个字符串的标准写法。
    • map.containsKey(i):判断集合中是否包含某些元素;
    • StringBuffer和StringBuolder:可定义可拼接的字符串。
    • startsWith():判断字符串的开头是否含有括号类数据
    • substring() 方法返回字符串的子字符串。

15.洛谷 p1598 Java 垂直柱状图

image-20220128105417262

AC代码:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int[] n = new int[26];
        String a;
        char b;

        //一共有4行数据
        for(int i=0;i<=3;i++) {
            a=sc.nextLine();  //输入一行字符串
            for(int j=0;j<a.length();j++) {
                b=a.charAt(j);
                if(b>='A'  && b<='Z') {
                    n[b-'A']++;  //记录A-Z的字符的个数
                }
            }
        }

        //获得最大的数;
        int o = getMax(n);

        //输出”*“
        for (int i = o; i > 0; i--) {//一共有max行.遍历每一行,判断是否有字符重复的次数达到当前行的大小
            for (int j = 0; j < 26; j++) {//一共26个字母
                if (n[j] == i){
                    System.out.print("* ");
                    n[j]--;
                }else{
                    System.out.print("  ");
                }
            }
            System.out.println();
        }
        System.out.print("A B C D E F G H I J K L M N O P Q R S T U V W X Y Z");//最下面对应的字符
    }
    public static int getMax(int []a){
        int b = 0;
        for (int i = 0; i < a.length; i++) {
            if (a[i] > b){
                b = a[i];
            }
        }
        return b;
    }
}

本题重点:

  • 统计每一位字符的出现的次数
  • 得到重复出现次数最多的字符,从这一层开始遍历
  • 注意细节
  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我会为您解答。首先,我们需要选择一个字符串模式匹配算法。这里我选择 KMP 算法,因为它的时间复杂度较低,可以快速地匹配字符串。 接下来,我们需要实现一个程序,让用户输入两个字符串或两个文件名,然后对它们进行分析和比较。下面是一个简单的 Java 代码示例: ```java import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; public class StringMatch { private static final int MAX_LENGTH = 1000000; // 最大长度 public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); System.out.println("请输入第一个字符串或文件名:"); String s1 = getString(br.readLine()); System.out.println("请输入第二个字符串或文件名:"); String s2 = getString(br.readLine()); int[][] matchResult = match(s1, s2); printMatchResult(matchResult, s1, s2); } // 将输入的字符串或文件内容读入 private static String getString(String str) throws IOException { if (str.endsWith(".txt")) { BufferedReader br = new BufferedReader(new FileReader(str)); StringBuilder sb = new StringBuilder(); String line; while ((line = br.readLine()) != null) { sb.append(line); } return sb.toString(); } else { return str; } } // 使用 KMP 算法进行字符串匹配 private static int[][] match(String s1, String s2) { int[][] matchResult = new int[s1.length()][s2.length()]; // 记录匹配结果 for (int i = 0; i < s1.length(); i++) { for (int j = 0; j < s2.length(); j++) { if (s1.charAt(i) == s2.charAt(j)) { if (i == 0 || j == 0) { matchResult[i][j] = 1; } else { matchResult[i][j] = matchResult[i-1][j-1] + 1; } } } } return matchResult; } // 输出匹配结果 private static void printMatchResult(int[][] matchResult, String s1, String s2) { int maxMatch = 0; // 最大匹配长度 int maxMatchI = 0; // 最大匹配长度的起始位置 int totalMatch = 0; // 总匹配长度 int i = 0; while (i < s1.length()) { int j = 0; while (j < s2.length()) { if (matchResult[i][j] > maxMatch) { maxMatch = matchResult[i][j]; maxMatchI = i - maxMatch + 1; } totalMatch += matchResult[i][j]; j++; } i++; } double matchRate = (double)totalMatch * 2 / (s1.length() + s2.length()); // 计算重复率 System.out.println("最大匹配长度:" + maxMatch); System.out.println("最大匹配起始位置:" + maxMatchI); System.out.println("总匹配长度:" + totalMatch); System.out.println("重复率:" + matchRate); } } ``` 这个程序可以读入用户输入的两个字符串或文件名,然后使用 KMP 算法进行字符串匹配,并输出匹配结果。其中,`matchResult` 数组记录了每个位置的匹配情况,`maxMatch` 和 `maxMatchI` 记录了最大匹配长度和起始位置,`totalMatch` 记录了总匹配长度,`matchRate` 计算了重复率。 需要注意的是,为了防止字符串过长导致程序崩溃,我们设置了一个最大长度为 1000000 的限制。如果您的字符串或文件长度超过了这个限制,可以根据需要进行调整。 另外,由于本程序是使用 Java 编写的,因此您需要先安装 JDK,并在命令行中运行该程序。如果您对 Java 不太熟悉,可以参考 Java 入门教程进行学习。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值