题目链接: http://poj.org/problem?id=1200 题目大意:给定子串长度,字符中不同字符数量,以及一个字符串,求不同的子串数量。
把子串插入map,map自动去重,最后输出map的size 结果是超时的。
超时代码:
/**
* @description: http://poj.org/problem?id=1200,采用map解题
* @author: michael ming
* @date: 2019/5/8 16:14
* @modified by:
*/
#include <iostream>
#include <stdio.h>
#include <map>
#include <string>
using namespace std;
int main()
{
size_t sublen, diffchar;
scanf("%d%d",&sublen,&diffchar);
map<string, int> substring;
string str, substr;
cin >> str;
size_t len = str.size();
for(size_t i = 0, j = i+sublen-1; j < len; i++,j++)
{
substr = str.substr(i, sublen);
substring.insert(pair<string, int>(substr, 1));
}
cout << substring.size();
return 0;
}
sublen
个字符哈希得到哈希值,因为题目说可能的子串组合小于1600万种,我们把得到的哈希值对1600万求模,存在数组中置为1(初始为0)。AC代码:
/**
* @description: 计算子串的种数
* @author: michael ming
* @date: 2019/5/8 17:20
* @modified by:
*/
#include <iostream>
#include <string>
#include <memory.h>
using namespace std;
void chartoint(string &str, int *num) //把字符中出现过的字符转成1开始的数字
{
int value = 1;
int len = str.size();
for(int i = 0; i < len; ++i)
{
if(num[str[i]] == 0)
num[str[i]] = value++;
}
}
size_t hashfunc(int i, int j, int m, int *num, string &str) //计算子串hash值
{
int hashValue = 0;
for(int k = i; k <= j; ++k)
hashValue = hashValue*m + num[str[k]];
return hashValue;
}
int main()
{
const unsigned int max = 16000001;
int num[300] = {0};
size_t *hash = new size_t[max];
memset(hash, 0, sizeof(hash));
int sublen, m;
int result = 0;
string str;
cin >> sublen >> m >> str;
chartoint(str, num);
for(int i = 0; i <= str.size()-sublen; ++i)
{
size_t hashValue = hashfunc(i, i+sublen-1, m, num, str)%max;
if(!hash[hashValue])
{
result++;
hash[hashValue] = 1;
}
}
cout << result << endl;
delete[] hash;
return 0;
}