【数据结构】串

一.串的定义

1. 串是由零个或多个字符串组成的有限序列,又叫字符串;
2. 一般记为:s=“a1a2a3…an”(n>=0)。

其中s为串的名称,双引号中的字符序列为串值,ai[1,n],i是该字符在串中的位置,n为串长

3. 其他概念

(1)空格串:只包含空格的串。区别于空串,它是有长度的,而且可以有多个空格
(2)子串与主串:串中任意个数的连续字符组成的子序列称为该主串的子串

二.串的比较

1. 串的比较通过组成串的字符之间的编码来进行的,而字符的编码指该字符对应字符集的序号
2. 比较两个串是否相等,要比较其长度和对应位编码号是否相等。
3. 不相等字符串比较大小:

两个字符串,如果一个串是另一个字符串的子串,则子串小于主串;如果从第i位开始不相等,则比较第i位的编码值,编码值大的串大。
实例应用:英语词典

三.串的存储结构

1. 顺序存储结构

用一组地址连续的存储单元来存储字符序列,一般用定长数组来定义

2.链式存储结构

(1)与线性表相似,但每个节点存放1/多个字符。
对于单节点多字符,最后一个节点若未被占满则用默认值补全,所以节点存储字符长度影响着串处理效率,需要根据实际情况做出选择。
(2)性能评价:串的链式存储结构除了在连接串与串操作时方便外,总体性能不如顺序存储好

四.字符串匹配算法

0.将一字符串与目标字符串比较,看其是否是目标串的子串,并确定匹配位置
1. 普通/暴力匹配算法

从第一位开始匹配,出错后子串整体后移一位,效率极低

2.KMP算法

(1)实现步骤:

  • 求前缀子串
  • 取不等于本身的最长相等前后缀值
  • 得出前缀表
  • 两串进行比较,出现错误时,将子串出错位处【前缀值对应的序列号】移动到目标串出错位处,并向后继续比较

(2)代码:

public class StringKmp {
 
	/**
	 * 用于计算匹配的位置(从头到尾)
	 * 
	 * @param str
	 * @param sub
	 * @return
	 */
	public static int kmp(String str, String sub) {
		if (str == null || sub == null || str.length() == 0 || sub.length() == 0) {
			throw new IllegalArgumentException("str或者sub不能为空");
		}
 
		int j = 0;
		int[] n = next(sub);
		for (int i = 0; i < str.length(); i++) {
			while (j > 0 && str.charAt(i) != sub.charAt(j)) {
				j = n[j - 1];
			}
 
			if (str.charAt(i) == sub.charAt(j)) {
				j++;
			}
 
			if (sub.length() == j) {
				int index = i - j + 1;
				return index;
			}
		}
 
		return -1;
	}
 
	/**
	 * 用于生成部分匹配表
	 * 
	 * @param sub
	 * @return
	 */
	private static int[] next(String sub) {
		int[] n = new int[sub.length()];
		int x = 0;
		for (int i = 1; i < sub.length(); i++) {
			while (x > 0 && sub.charAt(x) != sub.charAt(x)) {
				x = n[x - 1];
			}
 
			if (sub.charAt(i) == sub.charAt(x)) {
				x++;
			}
 
			n[i] = x;
		}
		return n;
	}
 
	public static void main(String[] args) {
 
		String str = "BBCABCDABABCDABCDABDE";
		String sub = "ABCDAB";
 
		int index = StringKmp.kmp(str, sub);
		System.out.println("index-->" + index);
	}
}
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值