C-返回字符指针数组中重复/出现次数最多的字符串

C-返回字符指针数组中重复/出现次数最多的字符串,c,string,similarity,C,String,Similarity,我几乎已经完成了这个问题的代码,我将在下面陈述: 鉴于: 长度为'n'的数组表示n=10000,声明如下 char **records = malloc(10000*sizeof(*records)); 每个记录[i]都是一个字符指针,指向一个非空字符串 records[i] = malloc(11); 字符串的固定长度为10个字符+'\0' 要求: 返回上述数组中最常出现的字符串 但现在,我感兴趣的是获得一种比我目前使用的原始算法稍微简单的算法,即在两个for循环中筛选

我几乎已经完成了这个问题的代码,我将在下面陈述:

鉴于:

长度为'n'的数组表示n=10000,声明如下

     char **records = malloc(10000*sizeof(*records));
每个记录[i]都是一个字符指针,指向一个非空字符串

     records[i] = malloc(11);
字符串的固定长度为10个字符+'\0'

要求:

返回上述数组中最常出现的字符串

但现在,我感兴趣的是获得一种比我目前使用的原始算法稍微简单的算法,即在两个for循环中筛选整个数组:,将两个循环遇到的字符串存储在一个大小类似的临时数组“n”中,以防所有字符串都是唯一的字符串,以便与下一个字符串进行比较。内循环从“外循环位置+1”迭代到“n”。同时,我有一个大小类似的整数数组——“n”,用于计算重复出现的次数,每个第I个元素对应于比较数组中的第I个唯一字符串。然后找到最大的整数,并在比较数组中使用其索引返回最常出现的字符串

我希望我足够清楚。我自己也为algo感到羞耻,但这是必须的。我相信在C语言中有一种更聪明的方法可以做到这一点

祝你周日愉快


干杯

虽然谷歌、维基百科和Stackoverflow的算法不太好,但我想到的一个解决方案是对数组进行排序,然后使用单个循环遍历条目。只要当前字符串与上一个相同,就增加该字符串的计数器。完成后,你会有一个字符串列表和它们的出现,如果需要的话可以进行排序。

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

在大多数语言中,通常的方法是构造一个哈希表,将字符串映射到计数。这是一个复杂的问题

例如,在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中的HASHYMAP,这样可以进行排序和扫描。它是ON.logN复杂度,比最优复杂度差,但非常实用

下面是一些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;
}

在大多数语言中,通常的方法是构造一个哈希表,将字符串映射到计数。这是一个复杂的问题

例如,在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中的HASHYMAP,这样可以进行排序和扫描。它是ON.logN复杂度,比最优复杂度差,但非常实用

下面是一些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;
}

嘿,这是个好主意。让我稍等一下,看看是否还有人添加了有趣的内容,否则我将标记您的答案:。谢谢。嘿,这是个好主意。让我稍等一下,看看是否还有人添加了有趣的内容,否则我将标记您的答案:。谢谢。供将来参考:如果sizeof char不等于1,您就没有C编译器。我总是忘记放弃它!谢谢你指出。为了将来的参考:如果sizeof char不等于1,你就没有C编译器。我总是忘记放弃它!谢谢你指出。谢谢你!你向我展示了与皮莱博格先生相同的想法,但我认为我应该在你的帖子上注明你在展示实施过程中所做的努力。干杯谢谢你,安!你向我展示了与皮莱博格先生相同的想法,但我认为我应该在你的帖子上注明你在展示实施过程中所做的努力。干杯