编程统计候选人的得票数。有若干位候选人(n<=10),候选人姓名从键盘输入(候选人姓名不区分大小写,姓名最长为9个字节),若干位选民,选民每次输入一个得票的候选人的名字(姓名最长为9个字节),若选民输错候选人姓名,则按废票处理。程序自动统计各候选人的得票结果,并按照得票数由高到低的顺序排序。最后输出各选票人得票结果和废票信息。
输入格式:
先输入候选人人数n和n名候选人姓名,再输入选民人数m和m位选民的选票。
输出格式:
先根据选票结果由高到低输出各候选人得票结果,再根据废票情况输出废票信息(换行后,输出提示信息“invalid vote:”,再输出废票信息)。
输入样例1:
3
zhang
li
wang
9
Wang
Zhang
zhuang
LI
Liao
ZHANG
WANG
Wang
wang
输出样例1:
输入样例2:
2
liu
yang
5
Liu
liu
YANG
yang
Liu
输出样例2:
liu:3
yang:2
一道印象非常深刻的磨了很久的题。
其中,第四个测试点:**段错误,是数组越界。**虽然题目只有10,但是若是写11,还是不够,我一气之下写了个100,就过了。大E了,又没有闪。
磨了两个小时的几个教训:
1、一定要写注释,标明变量代表什么,特别是代码长的时候。
2、数组尽量大。
3、一段一段地测试数据。
#include<iostream>
#include<bits/stdc++.h>
bool cmp(int a,int b)
{
return a>b;
}
struct vote
{
char name[100];
int piao;
}a[100];
using namespace std;
int main()
{
int n,m;
//1 输入候选人
cin>>n;
for(int i=0;i<n;i++)
{
cin>>a[i].name;
}
//2 输入投票
cin>>m;
string b,b_name[100];
int invalid[100];//输错名字对应下标;
int flag=0,temp=0;//flag是用来判断是否输错名字;temp是输错名字的次数。
for(int i=0;i<m;i++)
{
cin>>b_name[i];//b是投票名;
b=b_name[i];
flag=0;
for(int j=0;j<n;j++)
{
if(b==a[j].name)
{
a[j].piao++;
flag++;
break;
}
else
{
int temp2=0;//temp2用来记录大小写调整完后是否完全相同;
int len1=b.size(),len2=strlen(a[j].name) ;
//cout<<b<<" "<<len1<<a[j].name<<" "<<len2<<endl;
if(len1==len2)
{
for(int k=0;b[k];k++)
{
if(b[k]==a[j].name[k])
{
temp2++;
continue;
}
else
{
if(islower(b[k])) b[k]=toupper(b[k]);
else if(isupper(b[k])) b[k]=tolower(b[k]);
if(b[k]==a[j].name[k])
{
temp2++;
continue;
}
else break;
}
}
}
if(temp2==len2)
{
flag++;
a[j].piao++;
}
}
}
if (flag==0)
{
invalid[temp]=i;
temp++;
}
}
//3 输出结果
int piao1[100],piao2[100];//把票数单独存一下;
for(int i=0;i<n;i++)
{
piao1[i]=a[i].piao;
piao2[i]=a[i].piao;
}
sort(piao2,piao2+n,cmp);//piao2被从大到小排了
int piao3[100];
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(piao2[i]==piao1[j])
{
piao3[i]=j;
}
}
}
for(int i=0;i<n;i++)
{
cout<<a[piao3[i]].name<<":"<<a[piao3[i]].piao;
if(i!=n-1) cout<<endl;
}
if(temp!=0)
{
cout<<endl<<endl<<"invalid vote:"<<endl;
for(int i=0;i<temp;i++)
{
cout<<b_name[invalid[i]];
if(i!=temp-1) cout<<endl;
}
}
return 0;
}