问题描述:给定一个模式patter和一个字符串str,查找str是否遵循相同的模式。 在这里follow表示完全匹配,以便在模式中的字母和str中的非空单词之间有一个双连字符。
示例1: 输入:pattern = "abba", str = "dog cat cat dog" 输出:true
示例2: 输入:pattern = "abba", str = "dog cat cat fish" 输出:false
示例三: 输入:pattern = "aaaa", str = "dog cat cat dog" 输出:false
难度:easy
相关内容:数组,哈希表,字符串的相关方法的应用
解题逻辑:我们的目的是判断str内的单词的模式是否与pattern一致,根据这个思想我们可以想到哈希表,我们可以根据给定的pattern作出哈希表,根据哈希表来做出判断。
具体步骤: 1:将str中的单词分割出来存到s中(可以利用strtok()函数) 2:利用哈希表,s的值为哈希表的值,利用26个字母的连续型得到长度为26的数组(数组的大小也需要做出处理),则将0到25作为关键字,刚开始是哈希表的全部为空 3:利用循环建立哈希表,对pattern中出现的字母提取关键字,并列取出str中的单词,判断该关键字对应的哈希表中的值是否为空,若为空,则将该单词存入(其中我们还要判断这个单词是不是已经出现过了(利用循环),若出现重复,则返回false),若不为空,则判断关键字所对应的值是否与s中的单词相等,若不相等,则返回false(说明不对应),直到循环结束,若没有出现上述的情况,则返回true。
代码:(可以与思路相结合看)
bool wordPattern(char* pattern, char* str) {//参考
int str_len = strlen(str);//字符串长度
char buffer[str_len + 1];//定义char数组,用于
strcpy(buffer, str);//将str复制到buffer
char *s = strtok(buffer, " ");//strtok函数原型:char *strtok(char s[], const char *delim);作用是以delim为分割符对buffer进行分割,分割部分存在s中
char *p = pattern;
char *table[26];//因为英文字母有26个,设置26个关键字
memset(table, '\0', 26 * sizeof(char *));//将table初始化为空
//memset(void *s,int ch,size_t n);
//函数解释:将s中当前位置后面的n个字节 (typedef unsigned int size_t )用 ch 替换并返回 s 。
//memset:作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法
do {
if (*p == '\0') //如果pattern为空,则直接返回false
return false;
int input = *p++ - 'a';//利用input定位关键字
if (table[input] == NULL) { //建立哈希表
for (int i = 0; i < 26; i++) {
if (table[i] == NULL) //如果table[i]为空,则结束本次循环,继续下一个循环
continue;
if (strcmp(table[i], s) == 0) //如果table[i]中有与S的值相等,返回false
return false;
}
table[input] = (char *) malloc((strlen(s) + 1) * sizeof(char));//给table[input]分配地址(我觉的最难的部分应该在这)
strcpy(table[input], s);//将s复制到table[input]中
}
else {
if (strcmp(table[input], s)) //比较table[input]与s是否相等,若不相等,则返回false
return false;
}
s = strtok(NULL, " ");//将str被分割的 下一部分传到s中
} while (s != NULL);
for (int i = 0; i < 26; i++)//释放哈希表table[i]
free(table[i]);
if (*p != '\0') //如果p没有访问到最后,则返回false
return false;
return true;
}