OpenJudge NOI 1.13 15:求序列中的众数

【题目链接】

OpenJudge NOI 1.13 15:求序列中的众数

【题目考点】

1. 字符串
2. 顺序查找

【解题思路】

由于输入的数字有52位,一般整型无法存储。因此必须把数字当作字符串来处理。
首先处理输入的数字串。

  • 如果首位是符号,则略过这一位
  • 而后找到第一个不是0的数字的位置,截取从该位置开始到末尾的字符串。
    • 如果截取到的字符串长度为0,说明该数字的各位都是0,该数字就是0,直接返回0。(数字0前面不应添加负号)
    • 如果截取到的字符串长度大于0,如果首位符号是负号,那么在前面添加负号。

将处理后的数字串存储在数组st中,st[i]表示第i个字符串。与之对应的,ct[i]表示第i个字符串出现的个数。
每读入一个字符串s,将其处理后,在st数组中顺序查找,看是否存在字符串s,如果存在,则其对应的数量增加1。
如果数字种类只有1种,那么所有数字都相等,输出no。
最后遍历ct数组,找到出现次数最大的数字的下标mxi(如果最大出现次数相等,mxi取最小值,也就是比较时用<),输出st[mxi]
由于st数组中数字字符串是按读入的顺序存储的,所以最小的mxi对应的就是最先读入的数字字符串。

由于处理后的数字字符串和出现的个数是绑定的,也可以设结构体解决该问题。

【题解代码】

解法1:不使用结构体
#include<bits/stdc++.h>
using namespace std;
#define N 130
string proc(string s)//整理字符串
{
    int st;//遍历的起始位置 
    if(s[0] == '+' || s[0] == '-')
        st = 1;
    else
        st = 0;
    string r;//构造的字符串 
    bool isPreZero = true;//是否在看前导0 
    for(int i = st; i < s.length(); ++i)
    {
        if(isPreZero)
        {
            if(s[i] == '0')
                continue;
            else
                isPreZero = false;
        }
        r = r+s[i];//r后面连接s[i] 
    }
    if(r.length() == 0)//如果都是前导0,r的长度为0,这个数字就是0 
        return "0";
    else if(s[0] == '-')//如果前面有负号,则添加负号 
        return '-' + r;
    else
        return r;
}
int main()
{
    string s, st[N];//st[i]:整理后第i个数字 
    int n, ct[N], ni = 0;//ni:数字的种类数 ct[i]:第i个数字的个数 
    cin >> n;
    for(int i = 1; i <= n; ++i)
    {
        cin >> s;
        s = proc(s);
        bool hasNum = false;//是否找到s这个数字 
        for(int j = 1; j <= ni; ++j)
        {
            if(st[j] == s)
            {
                ct[j]++;
                hasNum = true;
                break;
            }
        }
        if(hasNum == false)//如果st中没有s
        {
            st[++ni] = s;
            ct[ni] = 1;
        }
    }
    if(ni == 1)//所有数字都相同,数字种类只有1种 
        cout << "no";
    else
    {
        int mxi = 1;//数字个数最大的数字的下标 
        for(int i = 1; i <= ni; ++i)
            if(ct[i] > ct[mxi])
                mxi = i;
        cout << st[mxi];
    }
    return 0;
}
解法2:使用结构体
#include<bits/stdc++.h>
using namespace std;
struct Node
{
    string s;//整理后的数字字符串
    int ct;//st:第一次出现的位置 ct:出现的个数
};
string proc(string s)//整理字符串
{    
    int i;
    bool isneg = false;
    if(s[0] == '-')
        isneg = true;
    for(i = 0; i < s.length()-1; ++i)
        if(s[i] >= '1' && s[i] <= '9')
            break;
    string r = s.substr(i);//i为第一个非0数字的位置,从这一位置开始取到末尾 
    if(isneg && !(r.length() == 1 && r[0] == '0'))//如果有负号,且不是0,则在数字前添加负号。如果r是0,有负号也不加负号
        r = '-' + r;
    return r;
}
int main()
{
    string s;
    Node node[130];
    int n, ni = 0;
    cin >> n;
    for(int i = 1; i <= n; ++i)
    {
        cin >> s;
        s = proc(s);
        int j;
        for(j = 1; j <= ni; ++j)
        {
            if(node[j].s == s)
            {
                node[j].ct++;
                break;
            }
        }
        if(j > ni)//如果数组node中没有s
        {
            node[++ni].ct = 1;
            node[ni].s = s;
        }
    }
    if(ni == 1)//所有数字都相同,数字种类只有1种 
        cout << "no";
    else
    {
        int mxi = 1;
        for(int i = 1; i <= ni; ++i)
            if(node[i].ct > node[mxi].ct)
                mxi = i;
        cout << node[mxi].s;
    }
    return 0;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值