日撸Java三百行(day19:字符串匹配)

目录

一、字符串的一些基础知识

二、代码实现

1.字符类的创建

2.字符类的遍历

3.字符串匹配

4.字符串截取

5.数据测试

6.完整的程序代码

总结


一、字符串的一些基础知识

字符串(String)是用一对双引号括起来的零个或多个字符组成的有限序列,在java中,字符串是被作为对象来处理的。常用的字符串可以分为以下两大类:

  • String类:创建之后不允许再做修改的字符串常量
  • StringBuffer类:创建之后允许再做修改的字符串变量

毫无疑问,字符串是计算机处理信息的基础,毕竟我们向计算机输入的信息本质上都是字符串,而计算机所谓的“打印”实际上也是以字符串的形式显示出来的。所以,要想学好计算机,学会并熟练使用字符串以及字符串的各种操作(比如拼接、比较、截取、查找和替换等)是必不可少的。下面,我们就来进行一些基础的字符串操作,话不多说,上代码!

二、代码实现

其实字符串也是一种线性表,它和之前的栈、队列一样,有顺序存储结构、链式存储结构这两种存储方式,今天我们采用的是顺序存储结构,即以顺序表(数组)为底层进行模拟。

1.字符类的创建

相信经过这几天的学习,大家对类的创建已经差不多熟练了,这里就不过多阐述了。 

public class MyString {/*** The maximal length.*/public static final int MAX_LENGTH = 10;/*** The actual length.*/int length;/*** The data.*/char[] data;/************************ Construct an empty char array.**********************/public MyString() {length = 0;data = new char[MAX_LENGTH];}// Of the first constructor/************************ Construct using a system defined string.* * @param paraString* The given string. Its length should not exceed MAX_LENGTH - 1.**********************/public MyString(String paraString) {data = new char[MAX_LENGTH];length = paraString.length();// Copy data.for (int i = 0; i < length; i++) {data[i] = paraString.charAt(i);} // Of for i} // Of the second constructor

注意,为了后续操作方便,这里我们使用了charAt()方法+for循环,从而将字符串paraString复制到之前定义的数组data中。

2.字符类的遍历

    /************************ Overrides the method claimed in Object, the superclass of any class.**********************/public String toString() {String resultString = "";for (int i = 0; i < length; i++) {resultString += data[i];} // Of for ireturn resultString;} // Of toString

 同样的,我们重写toString()方法来实现字符串遍历。

3.字符串匹配

进行代码模拟之前,我们先来了解一下什么是字符串匹配。所谓“字符串匹配”,就是给定一个模式字符串(相当于原字符串的子串),判断其是否存在于主字符串(即原字符串)中,如果存在,确定该模式串出现的位置。显然,模式串的长度(patternLength) ≤ 主串的长度(mainLength)。

具体操作的方法为:将模式串的元素逐个与主串一一比对,直到在主串中找到某一段连续的部分与模式串完全匹配,此时模式串中第一个元素的下标即为该模式串出现的位置。

为了更好地理解字符串匹配的过程,我们用图来说明:

每次匹配,都是将模式串中的元素逐个(即从头到尾)与主串中的对应元素进行比对,若全部相同则匹配成功;若匹配过程中出现模式串的某个元素与对应元素不一样则立即停止,直接移动模式串进行下一次匹配。此外,由上图可以看出,最多需要进行mainLength - patternLength + 1次匹配。

理解字符串匹配的原理后,我们就可以开始代码实现了,如下:

    /************************ Locate the position of a substring.* * @param paraString The given substring.* @return The first position. -1 for no matching.**********************/public int locate(MyString paraMyString) {boolean tempMatch = false;for (int i = 0; i < length - paraMyString.length + 1; i++) {// Initialize.tempMatch = true;for (int j = 0; j < paraMyString.length; j++) {if (data[i + j] != paraMyString.data[j]) {tempMatch = false;break;} // Of if} // Of for jif (tempMatch) {return i;} // Of if} // Of for ireturn -1;} // Of locate

这里我们用到的是两层for循环,外层for-i循环是控制匹配次数的循环,因为最多匹配mainLength - patternLength + 1次且i的初始值为0,所以循环控制条件即为i < mainLength - patternLength + 1;而内层for-j循环则控制每次匹配时对模式串元素从头到尾进行比对,相当于对模式串进行一次遍历操作。注意,每次匹配时一旦出现比对失败就立即停止,马上进行下一次匹配,所以我们这里增加了一个if判断语句+break语句。

如果某次匹配全部比对成功,则执行完for-j循环后tempMatch仍为true,所以直接返回i,因为此时的i恰好就是模式串第一个元素当前所处的位置。

4.字符串截取

 所谓“字符串截取”,顾名思义,就是从原字符串中截取某一部分的内容,有以下两种方法:

  • 给定截取内容的开头下标以及整个截取内容的长度
  • 给定截取内容的开头下标和结尾下标

通常我们用的是第一种方法,代码如下:

    /************************ Get a substring* * @param paraString The given substring.* @param paraStartPosition The start position in the original string.* @param paraLength The length of the new string.* @return The first position. -1 for no matching.**********************/public MyString substring(int paraStartPosition, int paraLength) {if (paraStartPosition + paraLength > length) {System.out.println("The bound is exceeded.");return null;} // Of ifMyString resultMyString = new MyString();resultMyString.length = paraLength;for (int i = 0; i < paraLength; i++) {resultMyString.data[i] = data[paraStartPosition + i];} // Of for ireturn resultMyString;} // Of substring

当然,在进行字符串截取之前,还需要提前判断我们想要截取的内容是否超出了原字符串的范围。这里我们通过if语句进行判断,当paraStartPosition + paraLength > length(即截取内容已超出原字符串的范围)时,输出" The bound is exceeded.",并返回null。如果没有超出范围,则从截取内容的开头下标开始遍历,将内容copy到结果字符串中。

5.数据测试

 接着,我们进行如下的数据测试(注意,空格、标点符号等也算一个字符):

  • 测试一:在字符串" I like ik. "中,进行模式串" ik "的匹配,可以预测结果应该为3(以首次匹配成功为准)
  • 测试二:在字符串" I like ik. "中,进行模式串" ki "的匹配,原字符串中不存在模式串" ki ",所以应该返回-1
  • 测试三:在字符串" I like ik. "中,截取开头下标为1,内容长度为2的字符串,预测结果为" l"
  • 测试四:在字符串" I like ik. "中,截取开头下标为5,内容长度为5的字符串,可以预测结果为"e ik."
  • 测试五:在字符串" I like ik. "中,截取开头下标为5,内容长度为6的字符串,显然此时已经超出范围,所以输出"The bound is exceeded."
    /************************ The entrance of the program.* * @param args Not used now.**********************/public static void main(String args[]) {MyString tempFirstString = new MyString("I like ik.");MyString tempSecondString = new MyString("ik");int tempPosition = tempFirstString.locate(tempSecondString);System.out.println("The position of \"" + tempSecondString + "\" in \"" + tempFirstString+ "\" is: " + tempPosition);MyString tempThirdString = new MyString("ki");tempPosition = tempFirstString.locate(tempThirdString);System.out.println("The position of \"" + tempThirdString + "\" in \"" + tempFirstString+ "\" is: " + tempPosition);tempThirdString = tempFirstString.substring(1, 2);System.out.println("The substring is: \"" + tempThirdString + "\"");tempThirdString = tempFirstString.substring(5, 5);System.out.println("The substring is: \"" + tempThirdString + "\"");tempThirdString = tempFirstString.substring(5, 6);System.out.println("The substring is: \"" + tempThirdString + "\"");} // Of main

6.完整的程序代码

package datastructure;/*** My string. String is a class provided by the language, so I use another name.* It is essentially a sequential list with char type elements.**@auther Xin Lin 3101540094@qq.com.*/public class MyString {/*** The maximal length.*/public static final int MAX_LENGTH = 10;/*** The actual length.*/int length;/*** The data.*/char[] data;/************************ Construct an empty char array.**********************/public MyString() {length = 0;data = new char[MAX_LENGTH];}// Of the first constructor/************************ Construct using a system defined string.* * @param paraString* The given string. Its length should not exceed MAX_LENGTH - 1.**********************/public MyString(String paraString) {data = new char[MAX_LENGTH];length = paraString.length();// Copy data.for (int i = 0; i < length; i++) {data[i] = paraString.charAt(i);} // Of for i} // Of the second constructor/************************ Overrides the method claimed in Object, the superclass of any class.**********************/public String toString() {String resultString = "";for (int i = 0; i < length; i++) {resultString += data[i];} // Of for ireturn resultString;} // Of toString/************************ Locate the position of a substring.* * @param paraString The given substring.* @return The first position. -1 for no matching.**********************/public int locate(MyString paraMyString) {boolean tempMatch = false;for (int i = 0; i < length - paraMyString.length + 1; i++) {// Initialize.tempMatch = true;for (int j = 0; j < paraMyString.length; j++) {if (data[i + j] != paraMyString.data[j]) {tempMatch = false;break;} // Of if} // Of for jif (tempMatch) {return i;} // Of if} // Of for ireturn -1;} // Of locate/************************ Get a substring* * @param paraString The given substring.* @param paraStartPosition The start position in the original string.* @param paraLength The length of the new string.* @return The first position. -1 for no matching.**********************/public MyString substring(int paraStartPosition, int paraLength) {if (paraStartPosition + paraLength > length) {System.out.println("The bound is exceeded.");return null;} // Of ifMyString resultMyString = new MyString();resultMyString.length = paraLength;for (int i = 0; i < paraLength; i++) {resultMyString.data[i] = data[paraStartPosition + i];} // Of for ireturn resultMyString;} // Of substring/************************ The entrance of the program.* * @param args Not used now.**********************/public static void main(String args[]) {MyString tempFirstString = new MyString("I like ik.");MyString tempSecondString = new MyString("ik");int tempPosition = tempFirstString.locate(tempSecondString);System.out.println("The position of \"" + tempSecondString + "\" in \"" + tempFirstString+ "\" is: " + tempPosition);MyString tempThirdString = new MyString("ki");tempPosition = tempFirstString.locate(tempThirdString);System.out.println("The position of \"" + tempThirdString + "\" in \"" + tempFirstString+ "\" is: " + tempPosition);tempThirdString = tempFirstString.substring(1, 2);System.out.println("The substring is: \"" + tempThirdString + "\"");tempThirdString = tempFirstString.substring(5, 5);System.out.println("The substring is: \"" + tempThirdString + "\"");tempThirdString = tempFirstString.substring(5, 6);System.out.println("The substring is: \"" + tempThirdString + "\"");} // Of main
} // Of class MyString

运行结果

显然,运行结果与预测结果保持一致。

总结

总的来说,字符串不仅是计算机处理信息的基础,还涉及到很多应用程序的核心功能,所以掌握字符串及其相关操作对编程学习是非常重要的。此外,对于今天的字符串匹配操作,我们采用的是BF暴力算法,但其实还有KMP算法、Rabin-Karp算法、Boyer-Moore算法等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/396911.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

简单的docker学习 第13章 CI/CD与Jenkins(上)

第13章 CI/CD 与 Jenkins 13.1 平台登录页面 13.1.1 GitLab-8098-root 13.1.2 Jenkins-8080-zhangsan 13.1.3 SonarQube-9000-admin 13.1.4 harbor-80-admin 13.2 CI/CD 与 DevOps 13.2.1 CI/CD 简介 CI > Continuous Integration&#xff0c;持续集成。即将持续不断更新…

如何在linux系统上部署nginx

1&#xff09;首先去 nginx.org/download 官网下载你所需要的版本 我这里是下载的 nginx-1-23-3.tar.gz 2&#xff09;然后执行 yum -y install lrzsz 安装文件上传软件 执行 rz 选择你下载nginx的位置进行上传 yum -y install lrzsz 3&#xff09;执行 tar -zxvf nginx-1.23…

数据可视化(爬取豆瓣网站)

目录 1 绪论 1.1 研究背景 1.2 研究目的和意义 1.3 研究内容和方法 2. 需求分析 2.1 系统功能描述 2.2 数据采集与预处理 2.2.1 数据采集 2.2.2 数据清洗 2.2.3 数据处理 2.3 功能需求 2.3.1 登录模块 2.3.2 数据展示模块 3 系统设计 3.1 系统功能结构设计 3.2 …

Pycharm中重命名项目之后切换虚拟环境

Pycharm中重命名项目之后切换虚拟环境 场景 在Pycharm里面Rename Project/Directory之后&#xff0c;通常需要切换虚拟环境。 步骤 # 退出当前虚拟环境 deactivate # 删除旧的虚拟环境 .venv # 新建新的虚拟环境 python -m venv .venv # 切换到新的工程目录 cd E:\Bigdata\…

排序算法——插入排序

一、插入排序概念 直接插入排序&#xff08;Insertion Sort&#xff09;是一种简单的排序算法&#xff0c;它的工作原理类似于人们手动排序卡片的方式。该算法通过构建有序序列&#xff0c;对于未排序数据&#xff0c;在已排序序列中从后向前扫描&#xff0c;找到相应位置并插…

二叉树相关的算法题

二叉树相关的算法题 单值二叉树 如果二叉树每个节点都具有相同的值&#xff0c;那么该二叉树就是单值二叉树。 只有给定的树是单值二叉树时&#xff0c;才返回 true&#xff1b;否则返回 false。 示例 1&#xff1a; 输入&#xff1a;[1,1,1,1,1,null,1] 输出&#xff1a;t…

初阶数据结构5 排序

排序 1. 排序概念及运用1.1 概念1.2运用1.3 常见排序算法 2. 实现常⻅排序算法2.1 插⼊排序2.1.1 直接插⼊排序2.1.2 希尔排序2.1.2.1 希尔排序的时间复杂度计算 2.2 选择排序2.2.1 直接选择排序2.2.2 堆排序 2.3 交换排序2.3.1冒泡排序2.3.2 快速排序2.3.2.1 hoare版本2.3.2.2…

【云服务器系列】基于华为云OBS实现Picgo和Typora的完美融合

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

STM32-IIC协议详解

一、IIC简介 IC&#xff08;Inter-Integrated Circuit&#xff09;协议由飞利浦公司于1980年代开发&#xff0c;是一种用于集成电路间短距离通信的串行协议。它设计用于连接低速外围设备&#xff0c;特别适合于需要简单数据交换的场景。IC协议使用两根信号线&#xff1a;SCL&am…

Python数值计算(23)——modified akima插值

1. 数学原理 在前面的Akima插值中&#xff0c;计算斜率使用如下公式&#xff1a; 如果记&#xff1a; 在出现分母分子同时为零的情况时&#xff0c;会出现NaN的计算结果&#xff0c;Akima他自己也意识到这种问题&#xff0c;因此&#xff0c;在原来的算法上做了修订&#xff0…

Python | Leetcode Python题解之第330题按要求补齐数组

题目&#xff1a; 题解&#xff1a; class Solution:def minPatches(self, nums: List[int], n: int) -> int:patches, x 0, 1length, index len(nums), 0while x < n:if index < length and nums[index] < x:x nums[index]index 1else:x << 1patches …

【线性代数】第2章 矩阵及其运算,矩阵的定义,矩阵的加法,矩阵的乘法(同济大学)

目录 1 矩阵 一、矩阵概念的引入 二、矩阵的定义 三、特殊的矩阵 同型矩阵与矩阵相等的概念 四、矩阵与线性变换 例 例 例 2 矩阵的运算 例 一、矩阵的加法 二、数与矩阵相乘 例&#xff08;续&#xff09; 三、矩阵与矩阵相乘 1 矩阵 一、矩阵概…

NVIDIA Triton系列11-模型类别与调度器-1

NVIDIA Triton系列11-模型类别与调度器-1 B站&#xff1a;肆十二-的个人空间-肆十二-个人主页-哔哩哔哩视频 (bilibili.com) 博客&#xff1a;肆十二-CSDN博客 问答&#xff1a;(10 封私信 / 72 条消息) 肆十二 - 知乎 (zhihu.com) 在 Triton 推理服务器的使用中&#xff0c;模…

数据科学 - 数据可视化(持续更新)

1. 前言​​​​​​​ 数据可视化能够将复杂的数据集转化为易于理解的图形、图表或图像。这种直观的表现形式使得人们能够更快地理解数据的分布、趋势、异常值以及数据之间的关系&#xff0c;从而更深入地洞察数据背后的信息。 数据可视化在数据分析和决策制定过程中具有不可…

C++的7种设计模式原则

一、设计模式前言 设计模式&#xff08;Design Patterns&#xff09;的“模式”指的是一种在软件设计中经过验证的、解决特定问题的方案。它们不是具体的代码&#xff0c;而是解决常见设计问题的抽象方案或模板。设计模式提供了一种标准的方式来组织代码&#xff0c;以提高代码…

为JetBrains IDE设置自定义TODO筛选器(筛选指定的关键字)和Live Templates

为JetBrains IDE设置自定义TODO筛选器&#xff08;筛选指定的关键字&#xff09;和Live Templates 以下内容以搜索关键字 // TODO Zzz 为例&#xff0c;不区分大小写&#xff0c;可以将模板中的 Zzz 换成其他内容。 设置自定义TODO筛选器 在IDE设置中找到TODO选项&#xff0…

AWS注册是否必须使用美元银行卡

亚马逊网络服务(AWS)作为全球领先的云计算平台,吸引了众多企业和个人用户。然而,不少人在注册AWS账户时会产生疑问:是否必须使用美元银行卡?实际上,这种说法并不准确。虽然AWS的主要结算货币是美元,但用户在注册和使用过程中有多种支付方式可供选择。我们结合九河云的分析来告…

程序员前端开发者的AI绘画副业之路:在裁员危机中寻找新机遇

正文&#xff1a; 在这个充满变数的时代&#xff0c;作为一名前端开发者&#xff0c;我经历了行业的起伏&#xff0c;见证了裁员危机和中年失业危机的残酷。在这样的背景下&#xff0c;我开始了利用AI绘画作为副业的探索&#xff0c;不仅为了寻求经济上的稳定&#xff0c;更是为…

DLMS/COSEM中的信息安全:安全密钥(下)

2.5组件B终端实体证书类型要由DLMS/COSEM服务器支持 每个DLMS/COSEM服务器应使用X.509 v3格式&#xff0c;并包含以下任一项&#xff1a; ——具有P-256或P-384 ECDSA功能的签名密钥&#xff1b;或 ——具有P-256或P-384 ECDSA功能的密钥协商密钥。 每张证书均应使用ECDSA进行签…

lvs(linux virtual server)实例

一.lvs概述 1.1什么是lvs LVS&#xff08;Linux Virtual Server&#xff09;是一个基于Linux操作系统的虚拟服务器技术&#xff0c;用于实现负载均衡和高可用性。LVS通过将客户端的请求分发到多台后端服务器上&#xff0c;从而提高整体服务的处理能力和可靠性。LVS主要有两个组…