注册 登录
编程论坛 C语言论坛

输入一组字符串,输出出现次数最多的字符串及其个数

AsherAla 发布于 2021-01-21 14:01, 2614 次点击
输入一个整数n(1 <= n <= 100)
然后输入n个字符串(长度 <= 1000 ,字符为小写)
例如:
输入:
3
aaa
bb
bb
输出:
bb 2
7 回复
#2
rjsp2021-01-21 15:12
你自己是怎么想的呢?排序,还是直接选择?
我重新问,假如不是一系列字符串,而是一系列整数的话,你会做吗?
#3
AsherAla2021-01-21 15:48
回复 2楼 rjsp
啊 要是这么说就简单化了
#4
AsherAla2021-01-21 20:27
回复 2楼 rjsp
这是从一组数中找重复出现的
程序代码:

#include"stdio.h"
#include"string.h"
int main()
{
    int n;
    while(~scanf("%d", &n))
    {
        int s[10001] = {0}, num, max = 0, count = 0;
        for(int i = 0; i < n; ++ i)
        {
            scanf("%d", &num);
            s[num] ++;
            //printf("%d %d\n", num, s[num]);
            if(max <= s[num])
            {
                if(count < num && s[num] == max)
                {
                    count = num;
                    continue;
                }
                if(s[num] > max)
                {
                max = s[num];
                count = num;   
                }
            }
        }
        printf("%d %d\n", count, max);
    }
    return 0;
}

用这个数组下标法怎么做字符串的?
#5
rjsp2021-01-22 09:02
回复 4楼 AsherAla
你这代码我看不懂,
起先就看不懂, while(~scanf("%d", &n)) 这是要连续输入吗?可题目中只说输入一次;
最严重的是 int s[10001],这个 10001 是哪里来的?是你自己限定输入范围不超过10000吗?任何算法都跟数据范围相关,你不能将一个限定数据范围极小的算法适用于正常范围。

用这个数组下标法怎么做字符串的?
题目交代“(长度 <= 1000 ,字符为小写)”,那么数据范围就是 0 到 26的1000次方,你开一个 26的1000次方 的数组就行了。26的1000次方 大约是 9.4*10×1414,这个宇宙容不下,本宇宙所有粒子一共才 3.28×10^80个。
如果不要求 下标索引,而只要求比较快速索引的话,可以用 红黑树 或 哈希表 之类的算法。不过,你为了这么个小程序去写红黑树/哈希表的话,类似大炮打蚊子。
#6
rjsp2021-01-22 09:16
回复 4楼 AsherAla
按照你这个想法的话,伪代码大约是

int main( void )
{
    ……

    char s[100][1001]; // 题目限定 1<=n<=100, 字符串长度<=1000
    size_t s_len = 0;
    unsigned c[100] = { 0 };
   
    for( size_t i=0; i!=n; ++i )
    {
        读入一个字符串 x
        在s中查找x
        如果在下标index处找到了x,那么
            ++c[index]
        如果没找到,那么
            strcpy( s[s_len++], x );
            ++c[index]
    }

    在 c 中找到最大值,取其下标idx。输出 s[idx] 和 c[idx]
    当然,查找最大值也可以放在上一个循环中。
}
#7
rjsp2021-01-22 09:24
程序代码:

#include <stdio.h>
#include <string.h>

int main( void )
{
    unsigned n;
    scanf( "%u", &n );

    char s[100][1001]; // 题目限定 1<=n<=100, 字符串长度<=1000
    size_t s_len = 0;
    unsigned c[100] = { 0 };

    size_t result = 0;
    for( size_t i=0; i!=n; ++i )
    {
        char x[1001];
        scanf( "%s", x );

        size_t index;
        for( index=0; index!=s_len && strcmp(s[index],x)!=0; ++index );
        if( index == s_len )
            strcpy( s[s_len++], x );
        ++c[index];

        if( c[index] > c[result] )
            result = index;
    }

    printf( "%s %u\n", s[result], c[result] );
}
#8
AsherAla2021-01-22 10:07
以下是引用rjsp在2021-1-22 09:02:47的发言:

你这代码我看不懂,
起先就看不懂, while(~scanf("%d", &n)) 这是要连续输入吗?可题目中只说输入一次;
最严重的是 int s[10001],这个 10001 是哪里来的?是你自己限定输入范围不超过10000吗?任何算法都跟数据范围相关,你不能将一个限定数据范围极小的算法适用于正常范围。

 题目交代“(长度 <= 1000 ,字符为小写)”,那么数据范围就是 0 到 26的1000次方,你开一个 26的1000次方 的数组就行了。26的1000次方 大约是 9.4*10×1414,这个宇宙容不下,本宇宙所有粒子一共才 3.28×10^80个。
如果不要求 下标索引,而只要求比较快速索引的话,可以用 红黑树 或 哈希表 之类的算法。不过,你为了这么个小程序去写红黑树/哈希表的话,类似大炮打蚊子。


你这代码我看不懂,
起先就看不懂, while(~scanf("%d", &n)) 这是要连续输入吗?


这个代码其实是其他题目的,我就是想问这种思路行不行,貌似不行,就是字符串范围太大了。 非常感谢~\
while(~scanf("%d", &n)); 这个就是一个输入框架,就是可以连续输入测试,可以不用退出。
1