C++面试:字符串处理专题(二)

【IV】LCS最长公共子串(连续) http://blog.csdn.net/arhaiyun/article/details/11718111

/* [4].LCS 最长公共子串
* const char* LongestCommonString(const char* strLeft, const char* strRight)
* @author arhaiyun
**/
const char* LCS(const char* strLeft, const char* strRight)
{
	if(strLeft == NULL || strRight == NULL)
		return NULL;
	int lenLeft = strlen(strLeft);
	int lenRight = strlen(strRight);
	
	vector<int> prevLine(lenRight);
	vector<int> nextLine(prevLine);
	
	int maxLen = 0;
	int pos = -1;
	
	prevLine.assign(lenRight, 0);
	
	for(int i = 0; i < lenLeft; i++)
	{
		nextLine.assign(lenRight, 0);
		for(int j = 0; j < lenRight; j++)
		{
			if(strLeft[i] == strRight[j])
			{
				if(j == 0)
				{
					nextLine[j] = 1;
					if(nextLine[j] > maxLen)
					{
						maxLen = nextLine[j];
					}
					pos = j;
				}
				else
				{
					nextLine[j] = prevLine[j - 1] + 1;
					if(nextLine[j] > maxLen)
					{
						maxLen = nextLine[j];
						pos = j;
					}
				}
			}
			else
			{
				nextLine[j] = prevLine[j];
			}
		}
		prevLine.assign(nextLine.begin(), nextLine.end());
	}

	char *lcs = new char[maxLen + 1];
	int startPos = pos - maxLen + 1;
	for(int i = 0; i < maxLen; i++)	
	{
		lcs[i] = strRight[startPos + i];
	}
	lcs[maxLen] = '\0';
	
	return lcs;
}

【V】LCS最长公共子序列(可以不连续)

/*[5]. Longest Common SubSequence
* const char* LCSubString(const char* strLeft, const char* strRight)
* @author arhaiyun
**/
[5].Longest Common SubSequence 最长公共子序列的两种实现方法(注意同上的区别)
str1: haiyun loves xiaoyan
str2: yun lovess yan
output: yun loves yan

//[1].实现方法一
#include <stdio.h>
#include <string.h>
#define MAXLEN 100

void LCSLength(char *x, char *y, int m, int n, int c[][MAXLEN], int b[][MAXLEN])
{
   int i, j;
   for(i = 0; i <= m; i++)
       c[i][0] = 0;
   for(j = 1; j <= n; j++)
       c[0][j] = 0;
	for(i = 1; i<= m; i++)
	{
		for(j = 1; j <= n; j++)
        {
		if(x[i-1] == y[j-1])
            {
                c[i][j] = c[i-1][j-1] + 1;
                b[i][j] = 0;
            }
            else if(c[i-1][j] >= c[i][j-1])
            {
                c[i][j] = c[i-1][j];
                b[i][j] = 1;
            }
            else
            {
                c[i][j] = c[i][j-1];
                b[i][j] = -1;
            }
        }
    }
}

void PrintLCS(int b[][MAXLEN], char *x, int i, int j)
{	
	if(i == 0 || j == 0)
		return;
	if(b[i][j] == 0)
	{
		PrintLCS(b, x, i-1, j-1);
		printf("%c", x[i-1]);
	}
	else if(b[i][j] == 1)
		PrintLCS(b, x, i-1, j);
	else
		PrintLCS(b, x, i, j-1);
}

int main(int argc, char **argv)
{
	char x[MAXLEN] = {"haiyun loves xiaoyan"};
	char y[MAXLEN] = {"zhy loves pxy"};
	int b[MAXLEN][MAXLEN];
	int c[MAXLEN][MAXLEN];
	int m, n;
	
	m = strlen(x);
	n = strlen(y);
	
	LCSLength(x, y, m, n, c, b);
	PrintLCS(b, x, m, n);
	
	return 0;
}

//[2].LCSubSequence实现方法二
const char* LCSubString(const char* strLeft, const char* strRight)
{
	if(strLeft == NULL || strRight == NULL)
		return NULL;
	int lenLeft = strlen(strLeft);
	int lenRight = strlen(strRight);
	
	vector<int> prevLine(lenRight);
	vector<int> nextLine(prevLine);
	
	int maxLen = 0;
	int pos = -1;
	
	prevLine.assign(lenRight, 0);
	
	for(int i = 0; i < lenLeft; i++)
	{
		nextLine.assign(lenRight, 0);
		for(int j = 0; j < lenRight; j++)
		{
			if(strLeft[i] == strRight[j])
			{
				if(j == 0)
				{
					nextLine[j] = 1;
					if(nextLine[j] > maxLen)
					{
						maxLen = nextLine[j];
					}
					pos = j;
				}
				else
				{
					nextLine[j] = prevLine[j - 1] + 1;
					if(nextLine[j] > maxLen)
					{
						maxLen = nextLine[j];
						pos = j;
					}
				}
			}
			else
			{
				if(j == 0)
				{
					nextLine[j] = prevLine[j];
				}
				else
				{
					nextLine[j] = (prevLine[j] > nextLine[j - 1]) ? prevLine[j] : nextLine[j - 1];
				}
			}
		}
		prevLine.assign(nextLine.begin(), nextLine.end());
	}

	char *lcs = new char[maxLen + 1];
	
	for(int i = 0, j = 1; i <= pos && j <= maxLen; )
	{
		if(prevLine[i] == j)
		{
			lcs[j - 1] = strRight[i];
			i++, j++;
		}
		else
		{
			i++;
		}
	}
	
	lcs[maxLen] = '\0';
	
	return lcs;
}


int main(int argc, char* argv[])  
{  
    const char* strLeft = "haiyun loves xiaoyan";  
    const char* strRight = "zhy loves pxy";  
  
    const char* lcs = LCS(strLeft, strRight);  
    printf("%s\n", strLeft);      
    printf("%s\n", strRight);     
    printf("LCSubSequence:%s\n", lcs);     
       
    return 0;  
}  

【VI】 KMP  博客算法解析http://blog.csdn.net/arhaiyun/article/details/12002487

#include "stdafx.h"
#include <iostream>
#include <vector>
#include <time.h>
#include <fstream>

using namespace std;

/*
根据定义next[0]=-1,假设next[j]=k, 即P[0...k-1]==P[j-k,j-1]
	1)若P[j]==P[k],则有P[0..k]==P[j-k,j],很显然,next[j+1]=next[j]+1=k+1;
	2)若P[j]!=P[k],则可以把其看做模式匹配的问题,即匹配失败的时候,k值如何移动,显然k=next[k]。
*/

void getNext(char *p, int *next)
{
	next[0] = -1;
	int j = 0;
	int k = -1;
	
	while(j < strlen(p) - 1)
	{
		if(k == -1 || p[j] == p[k])
		{
			j++;
			k++;
			next[j] = k;
		}
		else
			k = next[k];
	}
}

int KMPMatch(char *s, char *p)
{
	int next[100];
	
	int i = 0;
	int j = 0;
	
	getNext(p, next);
	
	while(i < strlen(s))
	{
		if(j == -1 || s[i] == p[j])
		{
			i++;
			j++;
		}
		else
			j = next[j];
		
		if(j == strlen(p))	
			return i - j;
	}
	
	return -1;
}


int main(void)
{
	char *s = "haiyun loves xiaoyan";
	char *p = "xiaoyan";

	cout<<KMPMatch(s, p)<<endl;
	
	system("pause");
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值