优化后的KMP算法实现与应用解析

版权申诉
0 下载量 141 浏览量 更新于2024-11-07 收藏 1KB RAR 举报
资源摘要信息: "KMP算法(Knuth-Morris-Pratt)是一种高效的字符串匹配算法,其主要特点是利用已经部分匹配的有效信息,保持主串不变,通过修改模式串的位移量来避免重新匹配,大大提高了搜索效率。KMP算法的核心在于一个叫做next数组(也有称作前缀函数)的数据结构,它能够在不匹配时告诉算法应该将模式串向右移动多远。而改进的KMP算法通常指的是对next数组进行优化,生成nextval数组,进一步减少不必要的比较。 在标准的KMP算法中,next数组记录了模式串中每个字符之前的子串(不包括该字符本身)的最长相等前后缀的长度。如果在匹配过程中遇到不匹配的情况,可以根据next数组值将模式串进行滑动,这样就不需要每次都从头开始匹配。 而改进的KMP算法,也就是生成nextval数组的算法,主要解决的是标准KMP算法中可能存在的问题,即在模式串中出现相同字符导致的冗余滑动。nextval数组在next数组的基础上进一步优化,通过对模式串中的字符进行区分,避免在发生不匹配时,模式串向右滑动到了一个新的不匹配位置,却仍然使用了相同的字符进行比较。 具体来说,在生成nextval数组时,会检查当前字符是否与它即将跳转到的位置的字符相同。如果不同,则nextval值等于next值;如果相同,则需要继续向前检查,直到找到一个不同的字符或者到达字符串的开始。这样做的好处是,当发生不匹配时,可以直接跳过那些即使进行了比较也不会成功的情况。 在实际编程实现中,我们通常会写一个函数来计算next或nextval数组,然后使用这个数组来指导匹配过程。在C++实现中,通常会看到一个名为computeNext或computeNextval的函数,该函数负责计算next数组或nextval数组,并返回一个包含这些值的数组。然后主函数会使用这个数组来进行实际的字符串匹配。 在本例中,提供的文件名称“改进的KMP算法.cpp”表明,文件内容包含了改进KMP算法的C++实现代码。代码中会包含计算nextval数组的函数,以及使用这个数组进行匹配的主函数。如果主串和模式串匹配成功,程序会输出匹配的起始位置。 整个改进的KMP算法的流程大致如下: 1. 初始化模式串和主串。 2. 计算模式串的nextval数组。 3. 使用nextval数组在主串中匹配模式串。 4. 如果匹配成功,输出匹配的起始位置;否则输出匹配失败的信息。 5. 根据nextval数组的特性,提高匹配过程的效率,减少不必要的比较次数。 了解改进的KMP算法对于字符串处理和模式匹配问题非常有帮助,特别是在需要高效率进行文本搜索的场合,如文本编辑器的查找功能、搜索引擎的索引机制等领域。通过减少计算量和优化匹配策略,改进的KMP算法提供了比传统暴力匹配更好的性能和用户体验。"

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 上传