【问题标题】:C - Returning the most repeated/occurring string in an array of char pointersC - 返回字符指针数组中重复/出现次数最多的字符串
【发布时间】:2013-01-06 06:38:04
【问题描述】:

我已经差不多完成了这个问题的代码,我将陈述如下:

鉴于:

长度为'n'(比如n = 10000)的数组声明如下,

     char **records = malloc(10000*sizeof(*records));

每条记录[i]都是一个char指针,指向一个非空字符串。

     records[i] = malloc(11);

字符串是固定长度的(10 个字符 + '\0')。

要求:

返回上述数组中出现频率最高的字符串。

但是现在,我有兴趣获得一种比我目前拥有的原始算法稍微不那么残酷的算法,即在两个 for 循环中筛选整个数组:(,将两个循环遇到的字符串临时存储在类似大小的数组('n' - 如果都是唯一字符串)用于与下一个字符串进行比较。内部循环从 'outer loop position + 1' 迭代到 'n em>'。同时,我有一个大小相似的整数数组 - 'n',用于计算重复出现次数,每个 i th 元素对应于第 i th em>(唯一)比较数组中的字符串。然后找到最大的整数,并使用它在比较数组中的索引返回最常出现的字符串。

我希望我足够清楚。我自己对算法感到很羞耻,但必须这样做。我相信在 C 中有更聪明的方法来做到这一点。

祝你周日愉快,

干杯!

【问题讨论】:

  • 供将来参考:如果sizeof char 不等于1,则说明您没有C 编译器。
  • 我总是忘记丢弃它!感谢您指出。

标签: c string similarity


【解决方案1】:

如果不擅长漂亮的算法(Google、Wikipedia 和 Stackoverflow 对我来说已经足够好了),我想到的一个解决方案是对数组进行排序,然后使用单个循环来遍历条目。只要当前字符串与前一个字符串相同,就为该字符串增加一个计数器。完成后,您将获得一个字符串及其出现的“列表”,然后可以根据需要对其进行排序。

【讨论】:

  • 嘿,这是个好主意。让我稍等一下,看看是否有人添加了一些有趣的东西,否则我会标记你的答案:)。谢谢。
【解决方案2】:

在大多数语言中,通常的方法是构造一个哈希表,将字符串映射到计数。这具有 O(N) 复杂度。

例如,在 Python 中(尽管通常您会为此使用 collections.Counter,甚至可以使用更专业的 Python 知识使这段代码更简洁,但我已将其明确用于演示)。

def most_common(strings):
    counts = {}
    for s in strings:
        if s not in counts:
            counts[s] = 0
        counts[s] += 1
    return max(counts, key=counts.get)

但是在 C 中,标准库中没有哈希表(尽管在 C++ 中,您可以使用 STL 中的 hash_map),因此可以进行排序和扫描。这是 O(N.log(N)) 复杂度,比最优更差,但非常实用。

这里有一些 C(实际上是 C99)代码来实现这个。

int compare_strings(const void*s0, const void*s1) {
    return strcmp((const char*)s0, (const char*)s1);
}

const char *most_common(const char **records, size_t n) {
    qsort(records, n, sizeof(records[0]), compare_strings);
    const char *best = 0;  // The most common string found so far.
    size_t max = 0;  // The longest run found.
    size_t run = 0;  // The length of the current run.
    for (size_t i = 0; i < n; i++) {
        if (!compare_strings(records[i], records[i - run])) {
            run += 1;
        } else {
            run = 1;
        }
        if (run > max) {
            best = records[i];
            max = run;
        }
     }
     return best;
}

【讨论】:

  • 谢谢匿名!您向我展示了与 Pileborg 先生相同的想法,但我认为我应该标记您的帖子,以表彰您为展示实施所做的努力。干杯!
猜你喜欢
  • 1970-01-01
  • 2018-03-23
  • 2011-03-13
  • 2013-09-27
  • 2012-05-10
  • 2015-01-02
  • 1970-01-01
  • 2021-06-28
  • 2014-09-22
相关资源
最近更新 更多