POJ 1002三种方法汇总

487-3279

题目大意就是翻译电话号码,三种方法分别是:数字打表排序的普通方法 ; 数字打表空间换时间 ; 转换为正规字符串然后排序并处理输出,该方法空间时间耗费均小

//POJ 1002好题
//标准STL代码  http://poj.org/showmessage?message_id=179496
//HASH法  http://poj.org/showmessage?message_id=171227
//堆排序320MS二叉排序540MS  http://poj.org/showmessage?message_id=171029
#include<functional>
#include<algorithm>
#include<iostream>
#include<fstream>
#include<sstream>
#include<iomanip>
#include<numeric>
#include<cstring>
#include<climits>
#include<cassert>
#include<cstdio>
#include<string>
#include<vector>
#include<bitset>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<list>
#include<set>
#include<map>
using namespace std;
/*****方法一*****/
#define M 100000+10
char hash[27]="22233344455566670778889990";
int cmp(const void *_a,const void *_b)
{
	char *a=(char*)_a;
	char *b=(char*)_b;
	return strcmp(a,b);
}
char str[M][20];
int main1()//数字打表要排序
{
	int n,i,j,ans,k,flag,length;
	char s[20];
	scanf("%d",&n);
	for(i=0;i<n;i++)
	{
		scanf("%s",str[i]);
		length=strlen(str[i]);
		k=0;
		for(j=0;j<length;j++)
		{
			if(str[i][j]>='A'&&str[i][j]<='Z')
				s[k++]=hash[str[i][j]-'A'];
			else if(str[i][j]>='0'&&str[i][j]<='9')
				s[k++]=str[i][j];
			else if(str[i][j]=='-');
		}
		s[k]='\0';
		strcpy(str[i],s);
	}
	qsort(str,n,sizeof(str[0]),cmp);
	flag=0;
	for(i=0;i<n;)
	{
		ans=1;
		for(j=i+1;j<n;j++)
		    if(strcmp(str[i],str[j])==0)
		        ans++;
		    else
		        break;
		if(ans>1)
		{
			flag=1;
			for(k=0;k<3;k++)
				printf("%c",str[i][k]);
			printf("-");
			for(k=3;k<7;k++)
				printf("%c",str[i][k]);
			printf(" %d\n",ans);
		}
		i+=ans;
	}
	if(!flag)
	    printf("No duplicates.");
	return 0;
}
/*****方法二*****/
int trans(char c)
{
    if(c=='A'||c=='B'||c=='C') return 2;
    if(c=='D'||c=='E'||c=='F') return 3;
    if(c=='G'||c=='H'||c=='I') return 4;
    if(c=='J'||c=='K'||c=='L') return 5;
    if(c=='M'||c=='N'||c=='O') return 6;
    if(c=='P'||c=='R'||c=='S') return 7;
    if(c=='T'||c=='U'||c=='V') return 8;
    if(c=='W'||c=='X'||c=='Y') return 9;
    return c-'0';
}
int a[10000000];
int main2()//数字打表,不用排序,空间换时间
{
    int N,num;
    scanf("%d",&N);
    string str;
    while(N--)
    {
        num=0;
        cin>>str;
        for(int i=0;i<str.length();i++)
        {
            if(str.at(i)!='-') 
                num=num*10+trans(str.at(i));
        }
        a[num]++;
    }
    num=0;
    for(int i=0;i<10000000;i++)
    {
        if(a[i]>1)
        {
            num=1; 
            printf("%03d-%04d %d\n",i/10000,i%10000,a[i]);
        }
    }
    if(num==0)
        printf("No duplicates.\n");
    return 0;	
}
/*****方法三*****/
int main3()//普通方法,转换为正规字符串然后排序并处理输出,空间时间耗费均小
{
	string str[100002];	
    char mm[]={'2','2','2','3','3','3','4','4','4','5','5','5','6','6','6','7','7','7','8','8','8','9','9','9'};
	char s[60],s1[60],cmp1[7],cmp2[7];
	int n,i,j,k;
	scanf("%d",&n);
	for(i=0;i<n;i++)
	{
	    scanf("%s",s);
		k=0;
		for(j=0;j<strlen(s);j++)
		{
			if(s[j]>='A'&&s[j]<='P')
			{
			    s1[k]=mm[s[j]-'A'];
				k++;
			}
			else if(s[j]>'Q'&&s[j]<='Y')
			{
			    s1[k]=mm[s[j]-'A'-1];
				k++;
			}
			else if(s[j]>='0'&&s[j]<='9')
			{
			    s1[k]=s[j];
				k++;
			}
        }
		s1[k]='\0';
		str[i]=s1;
    }
    sort(str,str+n);
    int count=0,flag=-1,h;
	i=0;
	while(i<n)
	{
	    h=1;
		while(1)
		{
			for(j=0;j<7;j++)
				if(str[i][j]-str[i+1][j]!=0)
					break;
		    if(j==7)            
			{
				h++;
				i++;
				flag=0;
			}
			else
			{
				i++;
				break;
			}
		}
		if(h!=1)
		    printf("%c%c%c-%c%c%c%c %d\n",str[i-1][0],str[i-1][1],str[i-1][2],str[i-1][3],str[i-1][4],str[i-1][5],str[i-1][6],h);
    }
	if(flag==-1)
		printf("No duplicates.\n");
    return 0;
}
记录下来时常复习总结。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值