02数组+字符串+滑动窗口+前缀和与差分+双指针(D2_字符串(D1_基础学习))

目录

讲解一:复盘 JavaSE

--------------------------------

讲解二:基础知识

一、字符串的定义

二、字符串的实现

1. 基本介绍

2. 实现

2.1. 定长顺序存储方式实现

2.2. 堆分配存储方式实现

2.3. 块链存储方式实现

三、字符串匹配算法

1. 基本介绍

2. 常见算法

2.1. BF

1> 基本介绍

2> 算法思想

3> 代码实现

2.2. KMP

1> 基本介绍

2> 代码实现

2.3. BM

1> 基本介绍

2> 什么是坏字符(bad character)

3> 什么是好后缀(good suffix)

4> 代码实现

2.4. Sunday

1> 基本介绍

2> 代码实现

2.5. RK

1> 基本介绍

2> 代码实现

2.6. Shift-and/or

1> 基本介绍

2> 代码实现

2.7. AC 自动机

--------------------------------

讲解三:简单题目

一、模拟一个trim方法,去除字符串两端的空格

二、将一个字符串进行反转。将字符串中指定部分进行反转。比如“abcdefg”反 转为”abfedcg”

三、获取一个字符串在另一个字符串中出现的次数。 比如:获取“ ab”在 “abkkcadkabkebfkabkskab” 中出现的次数

四、获取两个字符串中最大相同子串

五、对字符串中字符进行自然顺序排序

六、求一个字符串的所有排列

七、判断一个字符串是否包含重复字符

八、如何判断两个字符串是否为换位字符串

九、整数反转

十、字符串中第一个唯一字符

十一、有效的字母异位词

十二、验证回文串

十三、最长公共前缀

--------------------------------

讲解四:简单问题

1. 怎样比较字符串?用”==”还是用equals()?

2. 为什么对于安全性敏感的信息char[]要优于String?

3. 我们能不能在switch语句中使用String?

4. 怎样把字符串转换为整数?

5. 怎样分解一个有空白字符的字符串?

6. substring()方法真正做了什么?

7. String vs StringBuilder vs StringBuffer

8. 怎样重复一个字符串?

9. 怎样把字符串转换为日期?

10. 怎样统计一个字符在字符串中出现的次数?

11. Java String 值转化为boolean值

--------------------------------

讲解五:常用方法

一、字符串的构造

1. 使用常量进行直接赋值构造

2. 使用new String对象

3. 使用字符数组进行构造

二、字符串的比较

1. ==

2. equals

3. compareTo

4. compareToIgnoreCase(String str)

三、字符串的查找

1. charAt(int index)

2. indexOf(String str)

四、字符串类型与其它类型的相互转化

1. 字符串转数字

2. 字符串转数组

五、字符串替换

六、字符串拆分

七、字符串截取

八、大小写转换

九、字符串去空格

trim()

十、字符串拼接

+号连接

join


讲解一:复盘 JavaSE

--------------------------------

讲解二:基础知识

一、字符串的定义

  1. 字符串是一种最常用的非数值类型。
  2. 它是由零个或多个字符组成的有限序列,字符串的逻辑结构与线性表相似,只是数据对象约束为字符集合,字符串的操作中数据元素操作不像线性表那样单个元素操作,而是通常作为一个整体进行操作。

二、字符串的实现

1. 基本介绍

  1. 串的常用定长顺序存储、堆分配存储和块链存储三种方法实现。
  2. 串相等:如果两个串的串值相等(相同),称这两个串相等。

换言之,只有当两个串的长度相等,且各个对应位置的字符都相同时才相等。

2. 实现

2.1. 定长顺序存储方式实现

类似于线性表的顺序结构存储,用一组地址连续的存储单元存储串值的字符序列。

在串定长顺序存储结构中,为每个串变量分配一个固定长度的存储区,即定长数组。

代码实现:

public class FixedLengthString {
 
    private final char[] data; // 定长数组存储字符串
 
    public FixedLengthString(int size) {
        data = new char[size];
    }
 
    // 获取定长字符串的长度
    public int length() {
        int length = 0;
        while (length < data.length && data[length] != '\0') {
            length++;
        }
        return length;
    }
 
    // 获取定长字符串的字符
    public char charAt(int index) {
        if (index >= 0 && index < data.length) {
            return data[index];
        }
        throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + data.length);
    }
 
    // 设置定长字符串的字符
    public void setCharAt(int index, char ch) {
        if (index >= 0 && index < data.length) {
            data[index] = ch;
        } else {
            throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + data.length);
        }
    }
 
    // 将字符串转换为常规字符串输出
    @Override
    public String toString() {
        return new String(data, 0, length());
    }
 
    // 示例用法
    public static void main(String[] args) {
        FixedLengthString fixedStr = new FixedLengthString(10);
        fixedStr.setCharAt(0, 'H');
        fixedStr.setCharAt(1, 'e');
        fixedStr.setCharAt(2, 'l');
        fixedStr.setCharAt(3, 'l');
        fixedStr.setCharAt(4, 'o');
 
        System.out.println(fixedStr.toString()); // 输出 "Hello"
        System.out.println(fixedStr.length()); // 输出 5
        System.out.println(fixedStr.charAt(2)); // 输出 'l'
    }
}

这段代码定义了一个 FixedLengthString 类,它使用定长的 char 数组来存储字符串。类中包含了获取字符串

长度、获取指定位置的字符以及设置指定位置的字符的方法。同时,重写了 toString 方法以便于将定长字符串

转换成常规字符串输出。最后,提供了一个 main 方法来演示如何使用这个类。

这里为什么字符串以 \0 结束,这是根据 C 编译器在处理字符数组时会自动为字符串字面量添加一个 \0。

例如,当我们声明 char str[] = "Hello"; 时,编译器会分配6个字节的内存,其中包括 H, e, l, l, o, \0。

这种方式允许字符串可以在数组中占据任何长度,并且 \0 可以出现在任何位置,定义字符串的终止。

这样设计不仅节省了存储空间,也减少了额外的计算开销,因为程序只需要遍历到 \0 即可。

运行结果图如下:

2.2. 堆分配存储方式实现

使用堆存储数据的方式已经学过很多了,线性表在堆中分配空间时分配比较大的一块空间,之后有一个表

示线性表内元素个数的变量控制线性表的操作。

字符串的堆分配存储方式是按照字符串长度分配堆空间,不会额外多分配空间,如果字符串为空,堆中不

分配空间。

在Java中,字符串是用类 String 表示的,而这个类的底层是通过字符数组 char[] 实现的。

Java中的字符串是不可变的,这意味着一旦创建了一个字符串,就不能更改它。

字符串在Java中是用堆分配存储的。

以下是创建和使用字符串的几种方式:

  1. 直接使用双引号创建字符串:
String str = "Hello, World!";
  1. 使用 new 关键字和构造函数创建字符串:
String str = new String("Hello, World!");
  1. 字符数组创建字符串:
char[] charArray = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!'};
String str = new String(charArray);
  1. 字符串连接:
String str1 = "Hello, ";
String str2 = "World!";
String str3 = str1 + str2; // 使用+运算符进行字符串连接
  1. 字符串长度:
String str = "Hello, World!";
int length = str.length(); // 获取字符串长度
  1. 字符串比较:
String str1 = "Hello";
String str2 = "World";
boolean isEqual = str1.equals(str2); // 检查两个字符串是否相等
  1. 字符串搜索:
String str = "Hello, World!";
boolean contains = str.contains("World"); // 检查字符串是否包含子字符串
  1. 字符串替换:
String str = "Hello, World!";
String replaced = str.replace("World", "Java"); // 替换字符串中的子串

以上代码展示了创建字符串、使用字符串、字符串操作和字符串属性的基本方法。

在Java中,字符串是不可变的,这意味着一旦创建了字符串,就不能更改它。

当执行字符串连接或其他可能看起来会“更改”字符串的操作时,实际上是创建了一个新的字符串。

这是堆分配存储的一个结果,因为新的字符串需要在堆上创建。

2.3. 块链存储方式实现

待更新(如果有谁能够提供帮助,希望能够将实现的代码私聊留言 - Java 版)

三、字符串匹配算法

1. 基本介绍

字符串匹配在文本处理的广泛领域中是一个非常重要的主题。

字符串匹配包括在文本中找到一个,或者更一般地说,所有字符串(通常来讲称其为模式)的出现。

该模式表示为p=p[0..m-1];它的长度等于m。

文本表示为t=t[0..n-1],它的长度等于n。两个字符串都建立在一个有限的字符集上。

一个比较常见的字符串匹配方法工作原理如下。在一个大小通常等于m的窗口帮助下扫描文本。

首先将窗口和文本的左端对齐,然后将窗口的字符与文本中的字符进行比较,这一特定的工作被称为尝

试,在完全匹配或不匹配之后,将窗口移到右侧。继续重复同样的过程,直到窗口的右端超过文本的右

端,一般称为滑动窗口机制。

2. 常见算法

2.1. BF

1> 基本介绍

BF算法,即暴力(Brute Force)算法,是普通的模式匹配算法,BF算法的思想就是将目标串S的第一个字符与模式

串T的第一个字符进行匹配,若相等,则继续比较S的第二个字符和 T的第二个字符;若不相等,则比较S的第二个

字符和T的第一个字符,依次比较下去,直到得出最后的匹配结果。BF算法是一种蛮力算法

2> 算法思想

首先S[1]和T[1]比较,若相等,则再比较S[2]和T[2],一直到T[M]为止;若S[1]和T[1]不等,则S向右移动一个字符

的位置,再依次进行比较。

如果存在k,1≤k≤N,且S[k+1…k+M]=T[1…M],则匹配成功;否则失败。

该算法最坏情况下要进行M*(N-M+1)次比较,时间复杂度为O(M*N)。

举例说明

  • S: ababcababa
  • T: ababa

BF算法匹配的步骤如下:

i=0, j=0

i=1, j=1

i=2,j=2

i=3, j=3

i=4, j=4(失败)

ababcababa

ababcababa

ababcababa

ababcababa

ababcababa

ababa

ababa

ababa

ababa

ababa

i=1,j=0(失败)

ababcababa

ababa

i=2,j=0

i=3,j=1

i=4,j=2(失败)

ababcababa

ababcababa

ababcababa

ababa

ababa

ababa

i=3,j=0(失败)

ababcababa

ababa

i=4,j=0(失败)

ababcababa

ababa

i=5,j=0

i=6,j=1

i=7,j=2

i=8,j=3

i=9,j=4(成功)

ababcababa

ababcababa

ababcababa

ababcababa

ababcababa

ababa

ababa

ababa

ababa

ababa

3> 代码实现
public class BFTest {

    public static int strMatch(String s, String p){
        int i = 0, j = 0;
        while(i < s.length() && j < p.length()){
            if(s.charAt(i) == p.charAt(j)){
                i++;
                j++;
            }else{
                i = i - j + 1;
                j = 0;
            }
            if (j == p.length()){
                return i - j;
            }
        }
        return -1;
    }

    public static void main(String[] args) {
        System.out.println( strMatch("ababcababa","ababa"));
    }
    
}

2.2. KMP

1> 基本介绍

KMP算法是三位学者在 Brute-Force算法的基础上同时提出的模式匹配的改进算法。Brute- Force算法在模式串

中有多个字符和主串中的若干个连续字符比较都相等,但最后一个字符比较不相等时,主串的比较位置需要回退。

KMP算法在上述情况下,主串位置不需要回退,从而可以大大提高效率 。

2> 代码实现
public class KMP {

    /**
     * 求出一个字符数组的next数组
     * @param t 字符数组
     * @return next数组
     */
    public static int[] getNextArray(char[] 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CodingW丨编程之路

你的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值