Aplicación ampliada del algoritmo KMP

Este artículo presenta la aplicación ampliada del algoritmo clásico de coincidencia de cadenas KMP

Agregue la menor cantidad de caracteres después de la cadena original para generar una cadena larga de modo que la cadena larga contenga dos cadenas originales

Complejidad de tiempo: O (N)

/*
    @Author: lwl2020
	@Date: 2020-5-29
	@Description: 在原始串的后面添加最少的字符生成一个长字符串,使长字符串包含两个原始串
*/

#include <iostream>
#include <string>
#include <vector>
using namespace std;

/*
    思路:
	    获取字符串的next数组,这里的next数组多计算一个整个串的最长前缀和最长后缀,
		将整个串的最长前缀后面的部分添加到原始串后面,即可得到包含两倍原始串的字符串
*/

class CAddChToTwice {
    
    
public:
	void addChToTwice(string& str) {
    
    
		if (str.empty()) {
    
    
			return;
		}
		vector<int> next(str.length() + 1, -1);
		getNextArr(str, next);
		string subStr = str.substr(next.at(str.length()), str.length() - next.at(str.length()));
		str.append(subStr);
	}

private:
	void getNextArr(string& str, vector<int>& next) {
    
    
		if (str.length() == 1) {
    
    
			return;
		}
		next.at(1) = 0;
		int index = 2;
		int cn = 0;
		while (index <= str.length()) {
    
    
			if (str.at(index - 1) == str.at(cn)) {
    
    
				next.at(index++) = ++cn;
			}
			else if (cn == 0) {
    
    
				next.at(index++) = 0;
			}
			else {
    
    
				cn = next.at(cn);
			}
		}
	}
};

int main() {
    
    
	string str("aba");
	cout << str << endl;
	CAddChToTwice().addChToTwice(str);
	cout << str << endl;

	system("pause");
	return 0;
}

Dos árboles binarios T1 y T2, determinan si el subárbol de T1 contiene la misma estructura que T2

Complejidad de tiempo: O (N)

/*
  @Author: lwl2020
  @Date: 2020-5-30
  @Description: 两棵二叉树T1、T2,判断T1的子树是否包含与T2相同的结构
*/

#include <iostream>
#include <string>
#include <vector>
using namespace std;

struct Node {
    
    
  Node* left;
  Node* right;
  int val;
  Node(int value) :
    val(value), left(nullptr), right(nullptr)
  {
    
     }
};

class CKMP {
    
    
public:
  int kmp(string& str1, string& str2) {
    
    
    if (str1.length() < str2.length() || str1.length() == 0 || str2.length() == 0) {
    
    
      return -1;
    }
    vector<int> next(str2.length(), -1);
    getNextArr(str2, next);
    int i1 = 0;
    int i2 = 0;
    while (i1 < str1.length() && i2 < str2.length()) {
    
    
      if (str1.at(i1) == str2.at(i2)) {
    
    
        i1++;
        i2++;
      }
      else if (i2 == 0) {
    
    
        i1++;
      }
      else {
    
    
        i2 = next.at(i2);
      }
    }
    return i2 == str2.length() ? i1 - i2 : -1;
  }

private:
  void getNextArr(string& str2, vector<int>& next) {
    
    
    if (str2.length() == 1) {
    
    
      return;
    }
    next.at(1) = 0;
    int index = 2;
    int cn = 0;
    while (index < str2.length()) {
    
    
      if (str2.at(index - 1) == str2.at(cn)) {
    
    
        next.at(index++) = ++cn;
      }
      else if (cn == 0) {
    
    
        next.at(index++) = 0;
      }
      else {
    
    
        cn = next.at(cn);
      }
    }
  }
};

/*
  思路:
    先将两棵树序列化
    然后用KMP算法判断是否包含
*/

class CT1ContainT2 {
    
    
public:
  bool isT1ContainT2() {
    
    
    Node* t1 = generateTree1();
    string str1;
    serialize(t1, str1);
    deleteTree(t1);

    Node* t2 = generateTree2();
    string str2;
    serialize(t2, str2);
    deleteTree(t2);

    return CKMP().kmp(str1, str2) != -1 ? true : false;
  }

private:
  void serialize(Node* t, string& str) {
    
    
    if (t == nullptr) {
    
    
      str.append("#");
      return;
    }
    str.append(to_string(t->val) + "#");
    serialize(t->left, str);
    serialize(t->right, str);
  }

  Node* generateTree1() {
    
    
    Node* root = new Node(1);
    root->left = new Node(1);
    root->left->left = new Node(1);
    root->left->right = new Node(1);
    root->right = new Node(1);
    root->right->right = new Node(1);
    
    return root;
  }

  Node* generateTree2() {
    
    
    Node* root = new Node(1);
    root->right = new Node(1);

    return root;
  }

  void deleteTree(Node* root) {
    
    
    if (root == nullptr) {
    
    
      return;
    }
    deleteTree(root->left);
    deleteTree(root->right);
    delete root;
  }
};

int main() {
    
    
  cout << (CT1ContainT2().isT1ContainT2() ? "contain" : "no contain") << endl;

  system("pause");
  return 0;
}

Si hay alguna infracción, comuníquese para eliminarla. Si hay un error, corríjame, gracias

Supongo que te gusta

Origin blog.csdn.net/xiao_ma_nong_last/article/details/106433274
Recomendado
Clasificación