题解字符串匹配

Posted kcn999

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解字符串匹配相关的知识,希望对你有一定的参考价值。

题目描述

  给定N个字符串(第i个字符串长度为Mi,字符串内包含数字、大小写字母,大小写敏感),请求出N个字符串中共有多少个不同的字符串。

 

输入输出格式

输入格式

  第一行包含一个整数N,为字符串的个数。

  接下来N行每行包含一个字符串,为所提供的字符串。

 

输出格式

  输出包含一行,包含一个整数,为不同的字符串个数。

 

输入输出样例

输入样例

5

abc

aaaa

abc

abcc

12345

 

输出样例

4

 

说明

 

数据规模:

  对于30%的数据:N<=10,Mi≈6,Mmax<=15;

  对于70%的数据:N<=1000,Mi≈100,Mmax<=150

  对于100%的数据:N<=10000,Mi≈1000,Mmax<=1500

样例说明:

  样例中第一个字符串(abc)和第三个字符串(abc)是一样的,所以所提供字符串的集合为{aaaa,abc,abcc,12345},故共计4个不同的字符串。

 

题解

  字符串匹配,明显就是字符串hash的裸题。

  最初本来是想用map来装hash值来判断是否有重复,但实际上不同那么麻烦,只需要按照hash值排序一下,然后直接遍历一遍序列就行了。

技术分享图片
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>

#define MAX_N 10000
#define MAX_M 1500

using namespace std;

int n;
struct String
{
    char str[MAX_M | 1];
    int len;
    unsigned long long hash;
    friend bool operator < (String x, String y)
    {
        return x.hash < y.hash;
    }
}a[MAX_N | 1];

inline int Insert(char s[], int len)
{
    unsigned long long res = 0;
    for(register int i = 0; i < len; ++i)
    {
        if(s[i] >= 0 && s[i] <= 9)
        {
            res = res * 62 + s[i] - 0;                                                 
        }
        else if(s[i] >= A && s[i] <= z)
        {
            res = res * 62 + s[i] - A + 10;
        }
        else 
        {
            res = res * 62 + s[i] - a + 36;
        }
    }
    return res;
}

int main()
{
    scanf("%d", &n);
    for(register int i = 1; i <= n; ++i)
    {
        scanf("%s", a[i].str);
        a[i].len = strlen(a[i].str);
        a[i].hash = Insert(a[i].str, a[i].len);
    }
    sort(a + 1, a + n + 1);
    int ans = 1;
    for(register int i = 1; i < n; ++i)
    {
        if(a[i].hash ^ a[i + 1].hash) ++ans;
    }
    printf("%d", ans);
    return 0;
}
参考程序

 

以上是关于题解字符串匹配的主要内容,如果未能解决你的问题,请参考以下文章

jQuery的DOM操作

循环通过 python 正则表达式匹配

题解字符串匹配

题解 Luogu P3370

Spark发现匹配字符串的出现次数

前端开发常用js代码片段