2021-02-25

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

题目描述:
输入一个长度为N的整数序列 (不多于128个整数),每个整数的范围在[-1052,1052],计算这个序列的众数。

众数是指出现次数最多的那个数。

如果有多个数出现的次数都达到最多,则取在原序列最先出现的数为众数;如果所有的数都相等,则返回"no"。

输入
第一行为序列长度N。

然后是N个数,每一个数的范围都是在[-1052,1052]。 注意,这N个数之间可能有若干个空行隔开。

注意,输入数据可能有一些冗余表达信息,具体来说:

1) 正数和0前面可能有前导0和’+'符号,例如
+000123=123
+0000=0
-0000=0
2)每个数字中不含有空格和其他非数字字符,例如不会出现"100 0"或者"- 100"。
3)每个数字前面至多有一个符号,即不会出现+(-1)、-(+4)和-(-1)等情况。
输出
输出只有 1 行:

该序列的众数或者”no”。

如果有多个数出现的次数都达到最多,则取最先出现的数为众数,并且输出形式应该最简形式。

例如,如果原序列众数为+000123,则输出123;如果原序列众数为+0000或者-0000或者0000,输出0。

负数正常输出,例如:如果原序列众数为-000000001111,就输出-1111。
样例输入
6
-00001
10000
00011111111111111111111111111111111111
-01
+000000011111111111111111111111111111111111
-00000000000001
样例输出
-1

解题思想:
由于N的范围太大,所以用字符串的方式去存储,利用string 和map的用法,用map来标记每个字符串出现的次数,首先就是将所有输进来的字符串简化将前头无意义的0去掉,然后取出现最大的值即为众数,若2个出现次数相同则可以在用一个map参数去储存状态(即谁先出现),先出现的先输出

代码如下:

#include 
#include 
#include 
using namespace std;
map<string,int>a,b; //定义a来存放每次字符串出现次数,b存放字符串出现的顺序
int n,i;
string s,t;  //s是刚输进来的字符串,t是简化后的字符串
int main()
{
     
  cin>>n;
  while(n--)
  {
     
        cin>>s;
  if(s[0]=='-')//如果是负数,即开头为'-'则从s的第二位s[1]开始处理无意义的0
    i=1;
  else       //若是正数或者带'+'号的正数则从第一位即s[0]开始处理无意义的0
    i=0;
  while(s[i]=='+'||s[i]=='0')//通过while循环处理无意义的0
  {
     
    s.erase(i,1); //如果为无意义的0则删除 
  }
  if(s=="-"||s=="") //如果简化后为空,或者只有一个'-',则让其为0
    s="0";
  if(!a.count(s))//将每次刚进来简化的字符串标记为n,因为越早进来n越大,如果后面有相同次数的字符串,则通过判断n的大小来判断出现的先后次序,n越大出现越早
    b[s]=n;
  a[s]++;  //因为a[s]的原始值为0,出现一次+1
  if(a[s]>a[t]||(a[s]==a[t]&&b[s]>b[t]))//找到a[s]的最大值即为众数,如果有相同次数的则通过b[s]与b[t]的关系来判断出现的先后顺序
       t=s;
   }
  if(a.size()>2)  //因为size返回的是当前map包含的关系映射的数量,所以在我们第一次处理a[s]与a[t]时候,t一开始为空,所以这时候映射多了一个,所以若只有一个字符串,则a.size()为2,故这里只要a.size()>2就行
    cout<<t;
  else
    cout<<"no";
return 0;
}

你可能感兴趣的:(算法,数据结构,字符串,c++,c语言)