您的位置:首页 > 运维架构

Openjudge计算概论-求序列中的众数

2013-12-26 10:34 253 查看
/*=====================================
求序列中的众数
总时间限制: 1000ms 内存限制: 65536kB
描述
输入一个长度为N的整数序列 (不多于128个整数),每个整数的范围在[-10^52,10^52],计算这个序列的众数。

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

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

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

然后是N个数据,每一个数的范围都是在[-10^52,10^52]。 注意,这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
======================================*/
总结:
  这个题目假如不是数据范围太大,直接是统计某些整数出现的次数,那就很简单:
用一个数组a存储每一个新出现的数字同时记录每一次扫描到的数字出现的次数,最后扫描数组a,把找到出现次数最多的那个数字就可以输出结果了。
  现在这个题目,数字以字符串的形式出现,而且可能有多余的前缀字符,所以可以考虑对每一次输入的字符串先进行化简操作在按照上面的算法进行统计工作。
步骤:
  1、循环输入每一个字符串数组。
  2、每输入一个字符串,立即进行化简操作(可以用子函数来完成)
化简操作:
  先检测首字符是否‘+’或‘-’并保存检测结果。
  然后扫描字符串,遇到字符‘0’则要考虑该字符是否有效字符(是否需要保存。注意:这里保存到一个临时数组。)。
  如此往复循环处理完字符数组,再把临时数组复制到原数组当中以便返回结果。(这个地方要注意是否需要保留‘-’以及整个数字为0值的时候要特别处理。)
化简完后,在原先的循环体内做字符串出现次数的统计工作,算法和简单数字统计类似。(这里要用到strcmp函数比较两个字符串是否一致。)

统计完后再次扫描数组a寻找出现次数最多的那个字符串即可输出结果。

说的不清楚,看代码吧……


#include<stdio.h>
#include<string.h>
struct number
{
char n[60];//表示化为最简形式后的数
int num;//表示这个数出现的次数。
};
void fun(char a[]);//完成对输入的每个数字进行化简的工作 .结果放在原数组
int main()
{
struct number a[130];//存储化简后的数据,每个不同的数存一次,同时记录它的次数
int N,i,len;//共有N个数,len表示a数组已经使用的单元个数
char str1[500];
int j;
int max;//众数在数组a的下标

freopen("5.in","r",stdin);
scanf("%d",&N);
len=0;
for(i=0;i<N;i++)
{
scanf("%s",str1);
fun(str1);//化简刚刚输入的这个字符串
/*printf("%s\n",str1);*/
for(j=0;j<len;j++)//检测先前是否遇到过和str1一样的数字
{
if(strcmp(a[j].n,str1)==0)
{
a[j].num++;
break;
}
}
if(j>=len)
{
strcpy(a[len].n,str1);
a[len].num=1;
len++;
}
}
if(len==1&&len<N)//统计完了,a数组只有一个元素。而且输入的数字个数不是只有1个,说明输入的N个数大小是一样的
{
printf("no\n");
}
else
{
max=0;//默认第0号是众数所在的位置
for(i=1;i<len;i++)
{
if(a[i].num>a[max].num)
max=i;
}
printf("%s\n",a[max].n);
}
/*for(i=0;i<len;i++)
{
printf("%d  %s\n",a[i].num,a[i].n);
}*/
return 0;
}
void fun(char a[])//完成对输入的每个数字进行化简的工作 .结果放在原数组
{
char temp[65];
int len=strlen(a);
int i;
char flag;
int first=0;//表示是已经否遇到第一个有效字符
int j=0;//记录数组b的长度
int k;

//下面检测第一个字符是否是正号或者负号
flag='0';
if(a[0]=='-')    flag='-';
else if(a[0]=='+')    flag='+';

//根据第一字符的结果决定循环变量i的初值
if(flag!='0')   i=1;
else i=0;
//下面是化简数组a代表的数字,结果暂存在temp数组。
for( ;i<len;i++)
{
if(a[i]=='0')
{
if(first==1)//先前已经遇到了第一个有效字符,所以这个0是有效字符
{
temp[j]=a[i];
j++;
}//如果first==0则是当前这个字符是无效字符,可以直接忽略当前的这个a[i]
}
else
{
first=1;//标记一下:遇到了有效字符
temp[j]=a[i];
j++;
}
}
//下面把temp数组存储的化简结果复制到a数组以便返回结果
if(j==0)//整个数字是0
{
a[0]='0';
a[1]='\0';
}
else
{
if(flag=='-')
{
a[0]=flag;
k=1;
}
else
{
k=0;
}
for(i=0;i<j;i++)
{
a[k]=temp[i];
k++;
}
a[k]='\0';//截止符号
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: