字符串哈希模板

9.字符串哈希模板

题目描述

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

#友情提醒:如果真的想好好练习哈希的话,请自觉,否则请右转PJ试炼场:)

输入格式

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

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

输出格式

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

输入输出样例

输入 #1复制

5
abc
aaaa
abc
abcc
12345

输出 #1复制

4

说明/提示

对于 30%30% 的数据:N≤10,M i≈6,M m a x≤15。

对于 70%70% 的数据:N≤1000, M i ≈ 100 M_i≈100 Mi100 M i≈100,M**m a x≤150。

对于 100%100% 的数据:N≤10000,M i≈1000,M m a x≤1500。

样例说明:

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

Tip: 感兴趣的话,你们可以先看一看以下三题:

BZOJ3097:http://www.lydsy.com/JudgeOnline/problem.php?id=3097

BZOJ3098:http://www.lydsy.com/JudgeOnline/problem.php?id=3098

BZOJ3099:http://www.lydsy.com/JudgeOnline/problem.php?id=3099

如果你仔细研究过了(或者至少仔细看过AC人数的话),我想你一定会明白字符串哈希的正确姿势的_

#include<iostream>
#include<cstring>
#include<algorithm>
#define ull unsigned long long
using namespace std;
ull base=131;
int n,ans=0;
int h[10005];
string str[10005];
/*自然溢出*/
int hash1(string s)
{
    ull ss=0;
    for(int i=0;i<s.length();i++)
    {
        ss=ss*base+(ull)s[i];
    }
    return ss&0x7fffffff;
}
void func()
{
    string s;
    for(int i=0;i<n;i++)
    {
        cin>>s;
        int hs=hash1(s);
        h[i]=hs;
    }
    sort(h,h+n);
}
int main()
{
    cin>>n;
    func();
    for(int i=1;i<=n;i++)
    if(h[i]!=h[i-1]) ans++;
    cout<<ans<<endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 您好,可以使用以下的方法来实现这个功能: 1. 定义一个字符串数组,用来保存输入的字符串。 2. 使用一个循环读入所有的字符串。 3. 对于每个字符串,使用另一个循环遍历每个字符,并使用一个桶来记录每个字符出现的次数。 4. 最后遍历桶,统计有多少个字符出现了一次,即为不同的字符串数。 代码如下: ```c #include <stdio.h> #include <string.h> #define N 1000 int main() { // 定义字符串数组 char str[N][N]; // 定义桶,记录每个字符出现的次数 int count[256] = {0}; int n; printf("请输入字符串数:"); scanf("%d", &n); // 读入字符串 for (int i = 0; i < n; i++) { scanf("%s", str[i]); } // 遍历字符串 for (int i = 0; i < n; i++) { int len = strlen(str[i]); // 遍历每个字符 for (int j = 0; j < len; j++) { count[(int)str[i][j]]++; } } // 统计出现一次的字符数 int res = 0; for (int i = 0; i < 256; i++) { if (count[i] == 1) { res++; } } printf("不同的字符串数量为:%d\n", res); return 0; } ``` 希望这能帮到您! ### 回答2: 要编写一个C语言程序,可以统计一组给定字符串中有多少个不同的字符串,首先需要明确输入和输出的要求。 输入:n个字符串字符串包含大小写字母数字。 输出:不同的字符串的数量。 编写程序的思路如下: 1. 导入所需的标准库:`stdio.h`和`string.h`。 2. 声明并初始化一个整数变量`count`,用于保存不同字符串的数量。 3. 声明一个字符数组`str`,用于保存输入的字符串。 4. 使用`for`循环,遍历所有输入的字符串。 5. 在循环中,对每个字符串进行处理判断是否和之前的字符串相同。 - 声明一个布尔变量`isDifferent`,用于判断当前字符串是否和之前的字符串不同。 - 使用`for`循环,遍历之前的所有字符串。 - 在循环中,使用函数`strcmp()`来比较当前字符串和之前的字符串。 - 如果比较结果为0,则说明当前字符串和之前的字符串相同,将`isDifferent`置为`false`,并跳出循环。 6. 在判断完所有之前的字符串后,如果`isDifferent`为`true`,则说明当前字符串与之前的字符串都不同,将`count`加1。 7. 循环结束后,输出`count`的值,即不同字符串的数量。 下面是一个实现上述思路的简单代码示例: ```c #include <stdio.h> #include <string.h> int main() { int n, count = 0; printf("请输入字符串的数量:"); scanf("%d", &n); char str[100][100]; printf("请输入字符串:\n"); for (int i = 0; i < n; i++) { scanf("%s", str[i]); bool isDifferent = true; for (int j = 0; j < i; j++) { if (strcmp(str[i], str[j]) == 0) { isDifferent = false; break; } } if (isDifferent) { count++; } } printf("不同的字符串数量为:%d\n", count); return 0; } ``` 这样,我们就可以用C语言编写一个程序,输入n个字符串,然后输出其中不同字符串的数量。 ### 回答3: 要编写一个C语言程序来计算给定n个字符串中有多少个不同的字符串,可以采取以下方法: 1. 首先,定义一个结构体来表示一个字符串。结构体中包含一个字符数组用于存储字符串的内容。 ```c typedef struct { char str[100]; // 假设每个字符串最长为100 } String; ``` 2. 然后,读取输入的n个字符串并存储在一个字符串数组中。 ```c String strings[100]; // 假设最多有100个字符串 int n; // 输入的字符串数量 // 读取输入的字符串 for (int i = 0; i < n; i++) { scanf("%s", strings[i].str); } ``` 3. 接下来,使用一个哈希表来记录字符串的出现次数。 ```c #include <stdio.h> #include <string.h> #define HASH_SIZE 1000 // 假设哈希表的大小为1000 typedef struct { char key[100]; // 假设键值最长为100 int value; // 字符串出现的次数 } HashNode; HashNode hashTable[HASH_SIZE]; // 初始化哈希表 void initHashTable() { memset(hashTable, 0, sizeof(hashTable)); } // 根据字符串计算哈希值 int hashCode(char* str) { int hash = 0; while (*str) { hash += *str++; } return hash % HASH_SIZE; } // 在哈希表中查找字符串,并返回对应的出现次数 int findValue(char* str) { int index = hashCode(str); while (hashTable[index].value != 0) { if (strcmp(hashTable[index].key, str) == 0) { return hashTable[index].value; } index = (index + 1) % HASH_SIZE; // 处理哈希冲突 } return 0; // 未找到 } // 在哈希表中插入字符串 void insertValue(char* str) { int index = hashCode(str); while (hashTable[index].value != 0) { if (strcmp(hashTable[index].key, str) == 0) { hashTable[index].value++; return; } index = (index + 1) % HASH_SIZE; // 处理哈希冲突 } strcpy(hashTable[index].key, str); hashTable[index].value = 1; } ``` 4. 遍历字符串数组,将每个字符串插入哈希表中,并累计不同字符串的数量。 ```c // 计算不同字符串的数量 int count = 0; initHashTable(); // 初始化哈希表 for (int i = 0; i < n; i++) { if (findValue(strings[i].str) == 0) { // 未在哈希表中找到该字符串 insertValue(strings[i].str); // 将字符串插入哈希表中 count++; // 计数加1 } } ``` 5. 最后,将不同字符串的数量输出。 ```c printf("不同字符串的数量为:%d\n", count); ``` 这样即可实现通过C语言编写一个程序,用于计算给定n个字符串中有多少个不同的字符串
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值