我可以使用动态内存分配来减小int数组的大小,然后重新分配内存吗?

时间:2019-01-22 10:43:45

标签: c pointers malloc realloc

我创建了一个程序,该程序计算找到列表中的string的次数,并将该数字打印在屏幕上并将其保存在int *arr中。但是,当有两个相同的strings时,count结果显然会打印两次并存储在输出/列表中。我的问题是:我是否可以检查是否已找到一个单词两次,如果是,然后free将该内存块并使用realloc()为整个int *arr重新分配内存?这是我的sortedCount()方法,该方法到目前为止已完成我上面所述的内容:

void sortedCount(int N) {
    int *wordCount;
    int i = 0;
    wordCount = malloc(N * sizeof(int));
    for(i = 0; i < N; i++) {
        wordCount[i] = count(N,wordList[i],1);
    }
    /* free mem */
    free(wordCount);
    return;
}

1 个答案:

答案 0 :(得分:2)

假设您有一个words个单词的动态分配数组:

char  **word;
size_t  words;

如果您想知道唯一单词的数目以及它们在数组中重复的次数,则可以使用disjoint-set data structure的简化版本和计数数组。

我们的想法是我们每个都有两个words元素数组:

size_t *rootword;
size_t *occurrences;

rootword数组包含该单词首次出现的索引,occurrences数组包含该单词首次出现的次数。

例如,如果words = 5word = { "foo", "bar", "foo", "foo", "bar" },则rootword = { 0, 1, 0, 0, 1 }occurrences = { 3, 2, 0, 0, 0 }

要填充rootwordoccurrences数组,请首先将两个数组初始化为“所有单词都是唯一的且仅出现一次”状态:

    for (i = 0; i < words; i++) {
        rootword[i] = i;
        occurrences[i] = 1;
    }

接下来,您使用双循环。外循环遍历唯一的单词,跳过重复的单词。我们通过将其occurrence计数设置为零来检测重复项。内循环遍历我们不知道是否唯一的单词,然后挑选出当前唯一单词的重复项:

    for (i = 0; i < words; i++) {

        if (occurrences[i] < 1)
            continue;

        for (j = i + 1; j < words; j++)
            if (occurrences[j] == 1 && strcmp(word[i], word[j]) == 0) {
                /* word[j] is a duplicate of word[i]. */
                occurrences[i]++;
                rootword[j] = i;
                occurrences[j] = 0;
            }
    }

在内部循环中,我们显然忽略了已知为重复的单词(并且j仅在occurrences[j]只能是01的单词上进行迭代)。这也加快了后面的词根的内部循环,因为我们仅比较候选词,而不是我们已经为其找到词根的那些词。

让我们研究一下使用word = { "foo", "bar", "foo", "foo", "bar" }输入的循环中发生了什么。

 i ╷ j ╷ rootword  ╷ occurrences ╷ description
───┼───┼───────────┼─────────────┼──────────────────
   │   │ 0 1 2 3 4 │ 1 1 1 1 1   │ initial values
───┼───┼───────────┼─────────────┼──────────────────
 0 │ 1 │           │             │ "foo" != "bar".
 0 │ 2 │     0     │ 2   0       │ "foo" == "foo".
 0 │ 3 │       0   │ 3     0     │ "foo" == "foo".
 0 │ 4 │           │             │ "foo" != "bar".
───┼───┼───────────┼─────────────┼──────────────────
 1 │ 2 │           │             │ occurrences[2] == 0.
 1 │ 3 │           │             │ occurrences[3] == 0.
 1 │ 4 │         1 │   2     0   │ "bar" == "bar".
───┼───┼───────────┼─────────────┼──────────────────
 2 │   │           │             │ j loop skipped, occurrences[2] == 0.
───┼───┼───────────┼─────────────┼──────────────────
 3 │   │           │             │ j loop skipped, occurrences[3] == 0.
───┼───┼───────────┼─────────────┼──────────────────
 4 │   │           │             │ j loop skipped, occurrences[4] == 0.
───┼───┼───────────┼─────────────┼──────────────────
   │   │ 0 1 0 0 1 │ 3 2 0 0 0   │ final state after loops.