POJ-3461 Oulipo

题目链接:

http://poj.org/problem?id=3461

题目大意:

求前一个字符串在第二个字符中出现的次数

解题思路:

根据求出的kmpNext数组对第二个字符串进行匹配

代码如下:

// POJ3461.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#pragma warning (disable:4996) //去freopen的警告
#define _CRT_SECURE_NO_DEPRECATE //去scanf报错

#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
using namespace std;

void perKMP(char *src, int len, int *rule);
int KMP(char *src, int src_len, char *dest, int dest_len);
char src[100008], dest[1000008];
int main()
{
	int T;
	scanf("%d", &T);
	while (T--)
	{
		int ans = 0;
		scanf("%s%s", &src, &dest);
		ans=KMP(src, strlen(src), dest, strlen(dest));
		printf("%d\n", ans);
	}
    return 0;
}
void perKMP(char *src, int len, int *rule)
{
	int i=0, j=-1;
	rule[0] = -1;
	while (i < len)//i是判断到的个数j是循环节重复的个数
	{
		//printf("i1:%d j1:%d ", i, j);
		while (-1 != j && src[i] != src[j])//找到最近与上一次的src[i]相等的字符,如果没有-1
		{
			//printf("src[%d]=%c ", j, src[j]);
			j = rule[j];
		}
		//printf("src[%d]=%c src[%d]=%c ", i, src[i], j, src[j]);
		i++;
		j++;
		//printf("src[%d]=%c src[%d]=%c ", i, src[i], j, src[j]);
		if (src[i] == src[j])//比较下一位的字符是否相等,如果相等就让他等于j的值
		{
			rule[i] = rule[j];
		}
		else//如果不相等就让他等于他前面循环的一样的个数
		{
			rule[i] = j;
		}
		printf("rule[%d]=%d\n", i, rule[i]);
	}
}
int KMP(char *src, int src_len, char *dest, int dest_len)
{
	int rule[100008];
	int i=0, j=0;
	int ans = 0;
	perKMP(src, src_len, rule);
	/*for (int i = 0; i < src_len; i++)
	{
		printf("rule[%d]=%d\n", i, rule[i]);
	}*/
	//printf("%d", dest_len);
	while (i < dest_len)//i为判断到的位数j为循环个数
	{
		while (-1 != j && dest[i] != src[j])//找到最近与上一次的src[i]相等的字符,如果没有-1
		{
			j = rule[j];
		}
		i++; 
		j++;
		//printf("rule[%d]=%d\n", j,rule[j]);
		if (j >= src_len)
		{
			//printf("%d\n",i-src_len);//匹配的位置
			ans++;
			j = rule[j];
		}
	}
	return ans;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值