您的位置:首页 > 其它

poj之路2--487-3279电话薄求重复

2015-05-25 10:59 141 查看

一、实现1

自己的思路实现的,少量数据时可以正常运行,因为使用了string数组,不能达到100000的数据量。这个算法是第一次使用string类的一些函数,留着供以后参考。代码如下:

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

using namespace std;

char get_num(char a)
{
char m=0;

if(a>='A'&&a<='C')
m=2;
else if(a>='D'&&a<='F')
m=3;
else if(a>='G'&&a<='I')
m=4;
else if(a>='J'&&a<='L')
m=5;
else if(a>='M'&&a<='O')
m=6;
else if(a>='P'&&a<='S')
m=7;
else if(a>='T'&&a<='V')
m=8;
else if(a>='W'&&a<='Y')
m=9;
return m+'0';
}

int main()
{
int pho_num;int i,j,m;
//	cin>>pho_num;
pho_num=12;
//	string str[100000],real_num[10000];
string str[100],real_num[100],re_str[100];
int re_num[100];
for(i=0;i<100;i++)
{
re_num[i]=1;
}
/*	string st1="",st2;
cout<<st1.length<<endl;
cout<<st2.length<<endl;
cout<<st1.empty()<<endl;
cout<<st2.empty()<<endl;
*/
/*	for(int i=0;i<pho_num;i++)
{
cin>>str[i];
}
*/
str[0]="4873279";
str[1]="ITS-EASY";
str[2]="888-4567";
str[3]="3-10-10-10";
str[4]="888-GLOP";
str[5]="TUT-GLOP";
str[6]="967-11-11";
str[7]="310-GINO";
str[8]="F101010";
str[9]="888-1200";
str[10]="-4-8-7-3-2-7-9-";
str[11]="487-3279";

for(i=0;i<pho_num;i++)
{	j=0;real_num[i]="";
string::iterator itr=str[i].begin();
while(itr<str[i].end())
{
if(j==3)
{real_num[i]+='-';j++;}

if(*itr>='0'&&*itr<='9')
{real_num[i]+=*itr++;j++;}
else if(*itr>='A'&&*itr<='Y')
{real_num[i]+=get_num(*itr++);j++;}
else
itr++;
}

}
m=0;
for(i=0;i<pho_num;i++)
{
if(!real_num[i].empty())
{
for(j=i+1;j<pho_num;j++)
{
if(!real_num[j].empty()&&(real_num[i].compare(real_num[j])==0))
{

re_str[m]=real_num[i];
re_num[m]++;
real_num[j]="";
}
}
if(re_num[m]>=2)
m++;

}

}
int temp;
for(i=0;i<m;i++)
for(j=i+1;j<m;j++)
{
if(re_str[i].compare(re_str[j])==1)
{
re_str[i].swap(re_str[j]);
temp=re_num[i];
re_num[i]=re_num[j];
re_num[j]=temp;
}
}

for(i=0;i<m;i++)
{
cout<<re_str[i]<<" "<<re_num[i]<<endl;
}

return 0;
}



二、改进

不用字符串来处理,将电话用整数进行保存,处理更快,先查找相同的电话,保存电话和重复的个数,然后用冒泡排序对电话排序,最后输出,改进的代码如下:

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

using namespace std;

int get_num(char a)
{
int m=0;

if(a>='A'&&a<='C')
m=2;
else if(a>='D'&&a<='F')
m=3;
else if(a>='G'&&a<='I')
m=4;
else if(a>='J'&&a<='L')
m=5;
else if(a>='M'&&a<='O')
m=6;
else if(a>='P'&&a<='S')
m=7;
else if(a>='T'&&a<='V')
m=8;
else if(a>='W'&&a<='Y')
m=9;
return m;
}

int get_int(string s)
{
int num=0;
string::iterator itr=s.begin();
while(itr<s.end())
{
if(*itr>='0'&&*itr<='9')
num=num*10+(*itr++-'0');
else if(*itr>='A'&&*itr<='Y')
num=num*10+get_num(*itr++);
else
itr++;
}
return num;
}

int main()
{
int pho_num;int i,j,m;
int pho[100000];
int re_pho[100000];
int re_num[100000];

cin>>pho_num;
//	pho_num=12;string str[20];
string str;
/*
str[0]="0003279";
str[1]="ITS-EASY";
str[2]="888-0100";
str[3]="3-10-10-10";
str[4]="888-GLOP";
str[5]="TUT-GLOP";
str[6]="000-3279";
str[7]="310-GINO";
str[8]="F101010";
str[9]="888-0100";
str[10]="-4-8-7-3-2-7-9-";
str[11]="487-3279";
*/
for(i=0;i<pho_num;i++)
{

cin>>str;
pho[i]=get_int(str);
}

m=0;
for(i=0;i<pho_num;i++)
{
if(pho[i]>=0)
{
re_num[m]=1;
for(j=i+1;j<pho_num;j++)
{
if(pho[j]>=0&&pho[i]==pho[j])
{

re_pho[m]=pho[i];
re_num[m]++;
pho[j]=-1;
}
}
if(re_num[m]>=2)
m++;
}
}

int temp;
for(i=0;i<m;i++)
for(j=i+1;j<m;j++)
{
if(re_pho[i]>re_pho[j])
{
temp=re_pho[i];
re_pho[i]=re_pho[j];
re_pho[j]=temp;

temp=re_num[i];
re_num[i]=re_num[j];
re_num[j]=temp;
}
}

for(i=0;i<m;i++)
{
temp=re_pho[i]/10000;
if(temp/10==0)cout<<"00";
else if(temp/100==0)cout<<"0";
cout<<temp;
cout<<"-";
temp=re_pho[i]%10000;
if(temp/10==0)cout<<"000";
else if(temp/100==0)cout<<"00";
else if(temp/1000==0)cout<<"0";
cout<<temp;
cout<<" "<<re_num[i]<<endl;
}

return 0;
}


提交后,显示超时,需要继续改进代码,实现中使用了四个for循环,可以考虑操作合在一起进行;同时,排序算法,考虑快排,试试能不能通过。

三、改进2

进行了简化处理,并用快速排序进行排序,但提交后照样是超时,先保存一下代码,后续再进行研究。

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

using namespace std;

int get_num(char a)
{
int m=0;

if(a>='A'&&a<='C')
m=2;
else if(a>='D'&&a<='F')
m=3;
else if(a>='G'&&a<='I')
m=4;
else if(a>='J'&&a<='L')
m=5;
else if(a>='M'&&a<='O')
m=6;
else if(a>='P'&&a<='S')
m=7;
else if(a>='T'&&a<='V')
m=8;
else if(a>='W'&&a<='Y')
m=9;
return m;
}

int get_int(string s)
{
int num=0;
string::iterator itr=s.begin();
while(itr<s.end())
{
if(*itr>='0'&&*itr<='9')
num=num*10+(*itr++-'0');
else if(*itr>='A'&&*itr<='Y')
num=num*10+get_num(*itr++);
else
itr++;
}
return num;
}

void Qsort(int a[],int b[],int low,int high)
{
int pivot,privotloc,pi_num;
int first,last;
if(low>=high)
{
return;
}
first=low;last=high;
pivot=a[first];
pi_num=b[first];
while(first<last)
{
while(first<last&&a[last]>=pivot)--last;
a[first]=a[last];//比初始关键字小的移到数组前面
b[first]=b[last];
while(first<last&&a[first]<=pivot)++first;
a[last]=a[first]; //比初始关键字小的移到数组末端
b[last]=b[first];
}
a[first]=pivot;  //初始关键字将数组分成两部分后,记录位置
b[first]=pi_num;
privotloc=first;
Qsort(a,b,low,privotloc-1);   //递归实现前半区
Qsort(a,b,privotloc+1,high);  //递归实现后半区

}

int main()
{
int pho_num;int i,j,m;
int pho[100000],num[100000];
int re_pho[100000];
int re_num[100000];
int pho_temp=0;

cin>>pho_num;
//	pho_num=12;string str[20];
string str;
/*
str[0]="0003279";
str[1]="487-3279";
str[2]="888-0100";
str[3]="3-10-10-10";
str[4]="888-GLOP";
str[5]="TUT-GLOP";
str[6]="000-3279";
str[7]="310-GINO";
str[8]="F101010";
str[9]="888-0100";
str[10]="-4-8-7-3-2-7-9-";
str[11]="487-3279";
*/
m=0;
for(i=0;i<pho_num;i++)
{

cin>>str;
pho_temp=get_int(str);
/*	if(i==0)
{
num[m]=1;
pho[m++]=pho_temp;
}
*/
///*
for(j=0;j<m;j++)
{

if(pho[j]==pho_temp)
{
num[j]++;
break;

}

}
if(j==m)
{
num[m]=1;
pho[m++]=pho_temp;
}
//*/
}

int shu_temp=0;
for(i=0;i<m;i++)
{
if(num[i]>=2)
{
re_pho[shu_temp]=pho[i];
re_num[shu_temp++]=num[i];
}
}

int temp;

Qsort(re_pho,re_num,0,shu_temp-1); //排序

for(i=0;i<shu_temp;i++)
{
temp=re_pho[i]/10000;
if(temp/10==0)cout<<"00";
else if(temp/100==0)cout<<"0";
cout<<temp;
cout<<"-";
temp=re_pho[i]%10000;
if(temp/10==0)cout<<"000";
else if(temp/100==0)cout<<"00";
else if(temp/1000==0)cout<<"0";
cout<<temp;
cout<<" "<<re_num[i]<<endl;
}
if(shu_temp==0)
cout<<"No duplicates."<<endl;
return 0;
}


四、改进3

看了一些思路,修改了下程序,终于ac了,代码如下:

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

using namespace std;

int comp(const void *a,const void *b)
{
return *(int *)a-*(int *)b;
}

int get_num(char a)
{
int m=0;

if(a>='A'&&a<='C')
m=2;
else if(a>='D'&&a<='F')
m=3;
else if(a>='G'&&a<='I')
m=4;
else if(a>='J'&&a<='L')
m=5;
else if(a>='M'&&a<='O')
m=6;
else if(a>='P'&&a<='S')
m=7;
else if(a>='T'&&a<='V')
m=8;
else if(a>='W'&&a<='Y')
m=9;
return m;
}

int get_int(string s)
{		int num=0;
for(int i=0;i<s.length();i++)
{
if(s[i]>='0'&&s[i]<='9')
num=num*10+(s[i]-'0');
else if(s[i]>='A'&&s[i]<='Y')
num=num*10+get_num(s[i]);
}
return num;
}

int main()
{
int pho_num;int i,j,m;
int pho[100000];
int pho_temp=0;

cin>>pho_num;

string str;

m=0;
for(i=0;i<pho_num;i++)
{
cin>>str;
//scanf("%s",str);
pho[i]=get_int(str);
}

qsort(pho,pho_num,sizeof(int),comp); //自带的快速排序

int temp;
m=0;int no=0;
for(i=0;i<pho_num;i++)
{
m=1;
while(pho[i]==pho[i+1])
{
no=1;
m++;i++;
}
if(m>=2)
{
temp=pho[i]/10000;
if(temp/10==0)cout<<"00";
else if(temp/100==0)cout<<"0";
cout<<temp;
cout<<"-";
temp=pho[i]%10000;
if(temp/10==0)cout<<"000";
else if(temp/100==0)cout<<"00";
else if(temp/1000==0)cout<<"0";
cout<<temp;
cout<<" "<<m<<endl;
}

}
if(no==0)
cout<<"No duplicates."<<endl;
return 0;
}


总结:

这道题整整花了一天时间,前后整体了改了四次,先是用字符串处理和保存数据,将问题复杂了,处理操作更难而且内存更大。

第二,我是先统计重复号码,挑选出重复的再进行的排序,想着排序的整数数量会减少,但是实现起来较复杂,貌似花费时间更多,因此改为了先对所有排序,然后在统计重复的时候进行输出。

总之,在想思路时,必须充分考虑实现的复杂性,尽量简化步骤。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: