KMP算法:主串模式匹配优化技术

版权申诉
0 下载量 143 浏览量 更新于2024-10-16 收藏 56KB ZIP 举报
资源摘要信息:"KMP算法详细解析" KMP(Knuth-Morris-Pratt)算法是一种高效的字符串匹配算法,由Donald Knuth、Vaughan Pratt和James H. Morris共同发明。其核心思想是当出现不匹配的情况时,能利用已经匹配的部分信息,将模式串向右滑动尽可能远的距离,继续进行比较,从而避免从主串的下一个字符重新开始匹配,有效减少比较的次数。 首先,了解KMP算法的背景和意义是必要的。在字符串处理领域,尤其是文本编辑器、搜索引擎、生物信息学等领域,字符串匹配是一个基础且重要的任务。在传统的朴素匹配方法中,一旦出现不匹配,就需要回溯到模式串和主串的起始位置,时间复杂度较高。KMP算法通过预处理模式串,构造部分匹配表(也称为失败函数或next数组),减少了不必要的回溯,提高了匹配效率。 KMP算法的核心在于构造部分匹配表。该表记录了模式串中每个位置之前的子串中,有多大长度的相同前缀后缀。具体来说,对于模式串T的每一个位置i,部分匹配表记录了T的前i个字符组成的子串中,最长的相同前缀和后缀的长度。当在匹配过程中,模式串T中的字符与主串S中的字符不匹配时,可以根据部分匹配表来决定模式串T应该向右滑动多远。 具体实现中,KMP算法分为两个部分:第一部分是部分匹配表的构造;第二部分是利用部分匹配表进行字符串匹配。构造部分匹配表是一个从左到右遍历模式串,同时计算每一位置的最长相同前后缀长度的过程。在实现匹配阶段,当主串和模式串不匹配时,就根据部分匹配表来移动模式串,而不是回溯主串的索引。 KMP算法的优点在于其时间复杂度较低,为O(n+m),其中n是主串的长度,m是模式串的长度。相比于朴素的字符串匹配算法,KMP算法避免了大量的无效比较,尤其在处理长字符串时效率更为显著。此外,KMP算法只依赖于部分匹配表,且这个表可以在模式串的匹配开始之前就预先计算好,这样在实际匹配过程中就不需要再次计算,保证了算法的高效性。 在实际应用中,理解KMP算法的关键在于深入掌握部分匹配表的构造方法和如何使用这个表来指导模式串的滑动。部分匹配表的构造利用了之前已比较成功的部分,因此算法可以在确保不漏掉任何可能匹配的位置的同时,最大程度地减少不必要的比较。 总之,KMP算法是处理字符串匹配问题的一种高效算法,它通过巧妙地利用已经完成的匹配信息,减少了匹配过程中的时间开销,非常适合处理需要重复进行字符串匹配的场景。掌握KMP算法的原理和实现,对于从事相关领域工作的IT专业人士来说是十分重要的。

import numpy import numpy as np import matplotlib.pyplot as plt import math import torch from torch import nn from torch.utils.data import DataLoader, Dataset import os os.environ['KMP_DUPLICATE_LIB_OK']='True' dataset = [] for data in np.arange(0, 3, .01): data = math.sin(data * math.pi) dataset.append(data) dataset = np.array(dataset) dataset = dataset.astype('float32') max_value = np.max(dataset) min_value = np.min(dataset) scalar = max_value - min_value print(scalar) dataset = list(map(lambda x: x / scalar, dataset)) def create_dataset(dataset, look_back=3): dataX, dataY = [], [] for i in range(len(dataset) - look_back): a = dataset[i:(i + look_back)] dataX.append(a) dataY.append(dataset[i + look_back]) return np.array(dataX), np.array(dataY) data_X, data_Y = create_dataset(dataset) train_X, train_Y = data_X[:int(0.8 * len(data_X))], data_Y[:int(0.8 * len(data_Y))] test_X, test_Y = data_Y[int(0.8 * len(data_X)):], data_Y[int(0.8 * len(data_Y)):] train_X = train_X.reshape(-1, 1, 3).astype('float32') train_Y = train_Y.reshape(-1, 1, 3).astype('float32') test_X = test_X.reshape(-1, 1, 3).astype('float32') train_X = torch.from_numpy(train_X) train_Y = torch.from_numpy(train_Y) test_X = torch.from_numpy(test_X) class RNN(nn.Module): def __init__(self, input_size, hidden_size, output_size=1, num_layer=2): super(RNN, self).__init__() self.input_size = input_size self.hidden_size = hidden_size self.output_size = output_size self.num_layer = num_layer self.rnn = nn.RNN(input_size, hidden_size, batch_first=True) self.linear = nn.Linear(hidden_size, output_size) def forward(self, x): out, h = self.rnn(x) out = self.linear(out[0]) return out net = RNN(3, 20) criterion = nn.MSELoss(reduction='mean') optimizer = torch.optim.Adam(net.parameters(), lr=1e-2) train_loss = [] test_loss = [] for e in range(1000): pred = net(train_X) loss = criterion(pred, train_Y) optimizer.zero_grad() # 反向传播 loss.backward() optimizer.step() if (e + 1) % 100 == 0: print('Epoch:{},loss:{:.10f}'.format(e + 1, loss.data.item())) train_loss.append(loss.item()) plt.plot(train_loss, label='train_loss') plt.legend() plt.show()请适当修改代码,并写出预测值和真实值的代码

2023-06-09 上传