首页 > 代码库 > POJ 3080 Blue Jeans 三种暴力法

POJ 3080 Blue Jeans 三种暴力法

本题可以使用暴力法直接求解,思路也挺简单的,不过实现起来也挺麻烦的。

本题最暴力直接使用strstr过。 这里使用hash表的方法过,这种方法好像有个学名的,主要思路就是把一个需要查找的字符串赋予一个数值,那么就可以把一串字符串的比较转换为一个值的比较了,那么就可以加速字符串的查找了。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

const long long MOD = (int)(1E9+7);//如果增加mod的话,会有很大几率出错的,本题就不能增加MOD,否则一直WA,不使用MOD就马上AC了
const int MAX_N = 61;
const int MAX_M = 11;
const int ALP_LEN = 4;
const int SIGNIFICANT = 3;
const char *intToChar = "ATGC";
short charToInt[256];
char dict[MAX_M][MAX_N];
char subStr[MAX_N];
long long finger;

bool searchFinger(char *txt, int L, int len)
{
	long long F = 0;
	long long K = 1;
	int i = 0;
	for (; i < L; i++)
	{
		F = ((F*5)+charToInt[txt[i]]);
		K = K*5;
	}
	if (F == finger) return true;
	for (int j = 0; i < len; j++, i++)
	{
		F = ((F*5)+charToInt[txt[i]]);
		F = (F-K*charToInt[txt[j]]);
		if (F == finger) return true;
	}
	return false;
}

int main()
{
	charToInt['A'] = 1;//不能从0开始,如果使用hash法
	charToInt['T'] = 2;
	charToInt['G'] = 3;
	charToInt['C'] = 4;
	int T, n;
	scanf("%d", &T);
	while (T--)
	{
		scanf("%d", &n);
		getchar(); // get rid of '\n'
		for (int i = 0; i < n; i++)
		{			
			gets(dict[i]);
		}
		int len = MAX_N - 1;
		int maxLen = 0;
		char res[MAX_N] = {'\0'};
		for (int i = 0; i < len; i++)//search every start position
		{
			finger = 0;
			for (int L = 1; L <= len-i; L++)//every substring
			{
				subStr[L-1] = dict[0][i+L-1];
				subStr[L] = '\0';
				finger = ((finger*5)+(charToInt[subStr[L-1]]));

				int j = 1;
				for (; j < n; j++)
				{
					if (!searchFinger(dict[j], L, len)) break;
				}
				if (j != n) break;//break to the next start position

				if (L > maxLen || (L==maxLen && strcmp(res, subStr)>0))
				{//alphabetic first
					strcpy(res, subStr);
					maxLen = L;
				}		
			}
		}
		if (maxLen < SIGNIFICANT)
		{
			puts("no significant commonalities");
		}
		else
		{
			printf("%s\n", res);
		}
	}
	return 0;
}


使用strstr也可以,时间效率是一样的:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

const int MAX_N = 61;
const int MAX_M = 11;
const int ALP_LEN = 4;
const int SIGNIFICANT = 3;
char dict[MAX_M][MAX_N];
char subStr[MAX_N];

int main()
{
	int T, n;
	scanf("%d", &T);
	while (T--)
	{
		scanf("%d", &n);
		getchar(); // get rid of '\n'
		for (int i = 0; i < n; i++)
		{			
			gets(dict[i]);
		}
		int len = MAX_N - 1;
		int maxLen = 0;
		char res[MAX_N] = {'\0'};
		for (int i = 0; i < len; i++)//search every start position
		{
			for (int L = 1; L <= len-i; L++)//every substring
			{
				subStr[L-1] = dict[0][i+L-1];
				subStr[L] = '\0';
				int j = 1;
				for (; j < n; j++)
				{
					if (!strstr(dict[j], subStr)) break;
				}
				if (j != n) break;//break to the next start position

				if (L > maxLen || (L==maxLen && strcmp(res, subStr)>0))
				{//alphabetic first
					strcpy(res, subStr);
					maxLen = L;
				}		
			}
		}
		if (maxLen < SIGNIFICANT)
		{
			puts("no significant commonalities");
		}
		else
		{
			printf("%s\n", res);
		}
	}
	return 0;
}


使用strstr的第二种方法:

const int MAX_N = 61;
const int MAX_M = 11;
const int ALP_LEN = 4;
const int SIGNIFICANT = 3;
char dict[MAX_M][MAX_N];
char subStr[MAX_N];

int main()
{
	int T, n;
	scanf("%d", &T);
	while (T--)
	{
		scanf("%d", &n);
		getchar(); // get rid of '\n'
		for (int i = 0; i < n; i++)
		{			
			gets(dict[i]);
		}
		int len = MAX_N - 1;
		int maxLen = 0;
		char res[MAX_N];
		for (int i = 0; i < len; i++)//search every start position
		{
			int len2 = len-i;
			strncpy(subStr, dict[0]+i, len2);
			for (int L = len2; L > 0; L--)//every substring
			{
				subStr[L] = '\0';
				int j = 1;
				for (; j < n; j++)
				{
					if (!strstr(dict[j], subStr)) break;
				}
				if (j == n)
				{
					if (L > maxLen || (L==maxLen && strcmp(res, subStr)>0))
					{//alphabetic first
						strcpy(res, subStr);
						maxLen = L;
					}
					break;	//break to the next start position
				}
			}
		}
		if (maxLen < SIGNIFICANT)
		{
			puts("no significant commonalities");
		}
		else
		{
			printf("%s\n", res);
		}
	}
	return 0;
}