884. 两句话中的不常见单词

884. 两句话中的不常见单词

句子 是一串由空格分隔的单词。每个 单词 仅由小写字母组成。

如果某个单词在其中一个句子中恰好出现一次,在另一个句子中却 没有出现 ,那么这个单词就是 不常见的 。

给你两个 句子 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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值