句子 是一串由空格分隔的单词。每个 单词 仅由小写字母组成。
如果某个单词在其中一个句子中恰好出现一次,在另一个句子中却 没有出现 ,那么这个单词就是 不常见的 。
给你两个 句子 s1 和 s2 ,返回所有 不常用单词 的列表。返回列表中单词可以按 任意顺序 组织。
示例 1:
输入:s1 = “this apple is sweet”, s2 = “this apple is sour”
输出:[“sweet”,“sour”]
C代码:
typedef struct {
char *key;
int val;
UT_hash_handle hh;
} HashTable;
HashTable *head;
void insert(char *str) {
char *token = strtok(str, " ");
HashTable *tmp = NULL;
while (token != NULL) {
HASH_FIND_STR(head, token, tmp);
if (tmp == NULL) {
HashTable *tmp = (HashTable *)malloc(sizeof(HashTable));
tmp->key = token; // token是一个地址指针,tmp->key也是
tmp->val = 1;
HASH_ADD_STR(head, key, tmp);
} else {
tmp->val++;
}
token = strtok(NULL, " ");
}
}
char **uncommonFromSentences(char *s1, char *s2, int *returnSize) {
head = NULL;
insert(s1);
insert(s2); // 还能这样求交集!
int len = HASH_COUNT(head);
char **ans = (char **)malloc(sizeof(char*) * len);
int ansTop = 0;
HashTable *curr = NULL, *next = NULL;
HASH_ITER(hh, head, curr, next) {
if (curr->val == 1) {
ans[ansTop++] = curr->key; // 通过移动行指针来对列指针赋值!字符串都是列指针,行指针用来大幅移动,赋值靠列指针。
}
}
*returnSize = ansTop;
return ans;
}
C问题代码,用于分析:
#include <stdio.h>
#include <stdlib.h>
#include <uthash.h>
#include <string.h>
typedef struct {
char *key;
int val;
UT_hash_handle hh;
} HashTable;
void insert(char *str, HashTable *hashTable) // hashTable为新创建的一个变量,来存放传过来的head值(即复制值)
{ // 如此1:这个新建的变量hashTable 与 head变量,就没有任何关系了;
printf("hashTable= %p\n", hashTable);
char *token = NULL;
token = strtok(str, " "); // str待切割字符串、" " 分隔字符串;
HashTable *tmp = NULL;
while (token != NULL) {
HASH_FIND_STR(hashTable, token, tmp);
if (tmp == NULL) {
HashTable *tmp = (HashTable *)malloc(sizeof(HashTable));
tmp->key = (char *)malloc(sizeof(char) * (strlen(token) + 1));
tmp->key = token;
tmp->val = 1;
HASH_ADD_STR(hashTable, key, tmp);
printf("hashTable= %p\n", hashTable); //如此2:HASH_ADD_STR构造的地址,保存在hashTable中,与head就毫无关系;
} else {
tmp->val++;
}
token = strtok(NULL, " "); // 获取下一个字符串的起始位置
}
}
char **uncommonFromSentences(char *s1, char *s2, int *returnSize)
{
HashTable *head = NULL; // 此时head的值为:0x0, 存head的地址是不会变的
HashTable *pEntry = NULL;
insert(s1, head); // head指向结构体数组首位置
printf("head= %p\n", head);
insert(s2, head);
int hashTableLen = HASH_COUNT(head);
printf("head= %p\n", head);
printf("hashTableLen= %d\n", hashTableLen);
// 字符串数组
// 保存hashTableLen个字符串的数组,由于需要移动指针取字符串,所以需要一个地址来保存指针(指向"字符串地址"的指针)
char **ans = (char **)malloc(sizeof(char *) * hashTableLen);
int i = 0;
HashTable *curr = NULL, *next = NULL;
HASH_ITER(hh, head, curr, next) // 待验证next含义
{
if (curr->val == 1) {
ans[i] = (char *)malloc(sizeof(char) * (strlen(curr->key) + 1)); // 最后一位存放'\0'
// strcpy(ans[i], curr->key);
ans[i] = curr->key;
i++;
}
}
// HASH_ITER(hh, head, curr, next)
// {
// free(curr->key);
// HASH_DEL(head, curr);
// }
*returnSize = i;
return ans;
}
int main(void)
{
char s1[] = "this apple is sweet"; // 必须是字符数组
char s2[] = "this apple is sour"; // 字符串指针:其数据存储在常量区,只能读取,修改
int returnSize = 0;
char** a = uncommonFromSentences(s1, s2, &returnSize);
printf("a = %s\n", a[0]);
return 0;
}
hashTable= 0000000000000000
hashTable= 00000000009D4D30
hashTable= 00000000009D4D30
hashTable= 00000000009D4D30
hashTable= 00000000009D4D30
head= 0000000000000000
hashTable= 0000000000000000
hashTable= 00000000009D1BD0
hashTable= 00000000009D1BD0
hashTable= 00000000009D1BD0
hashTable= 00000000009D1BD0
head= 0000000000000000
hashTableLen= 0