POJ 1002 字符串(编程基础题目)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/peter_xiazhen/article/details/86562908

好久不打代码了,这道题也是wa了老半天,废话不多说,先说几个坑点吧。

①、POJ的数据范围很大,所以不要用string了,TLE到怀疑人生。

②、统计每个电话号码的出现次数,把至少出现一次的电话号码,按照字典序输出。所以有两个想法。

<1>、直接用数组,数组的下标表示电话号码,存的是出现的次数,好处就是不用排序了,下标的遍历就是

按照字典序,从小到大的。但是,敲黑板,代价就是你必须数组开得很大,1e7保底吧,不然内存爆炸到怀疑人生。

<2>、第二种高级一点,用到的是Map,Map是一种集合容器,能够把Key-Value一一对应起来,试想关键字就表示电话号码,

存的是出现的次数,还有一个好处是Map存储的时候其实是有序的,它会按照关键字的字典序存储,包括输出,很省事了。

但是map在使用的时候,迭代器那里得注意。

③、输出的时候,因为是按照格式输出,所以 printf("%03d-%04d %d\n",i/10000,i%10000,num[i]);

注意注意0不能丢,要对齐的。代码如下

第一种:

#include <stdio.h>
#include <string.h>
const int maxn=1e7+5;
int num[maxn];//这个数组开大一点,因为想用数组下标来表示电话号码
char s[110];  //这里有个好处是不用排序了,下表就是从小到大遍历的
int n;

int converse(char temp)  //将字符转换成数字
{
    if (temp>='0'&&temp<='9') return temp-'0' ;
    else if (temp=='A'||temp=='B'||temp=='C') return 2;
    else if (temp=='D'||temp=='E'||temp=='F') return 3;
    else if (temp=='G'||temp=='H'||temp=='I') return 4;
    else if (temp=='J'||temp=='K'||temp=='L') return 5;
    else if (temp=='M'||temp=='N'||temp=='O') return 6;
    else if (temp=='P'||temp=='R'||temp=='S') return 7;
    else if (temp=='T'||temp=='U'||temp=='V') return 8;
    else if (temp=='W'||temp=='X'||temp=='Y') return 9;
    else return -1;
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%s",s);
        int cnt = strlen(s);
        int tol=0;
        for(int j=0;j<cnt;j++)
        {
            int temp = converse(s[j]);
            if (temp==-1) continue;
            else tol=tol*10+temp;
        }
        num[tol]++;
    }
    bool flag = false;
    for(int i=0;i<maxn;i++)
    {
        if (num[i]>1)
        {
            flag = true;
            printf("%03d-%04d %d\n",i/10000,i%10000,num[i]);
        }
    }
    if (!flag) printf("No duplicates.\n");
    return 0;
}

第二种

#include <stdio.h>
#include <string>
#include <string.h>
#include <map>
#include <iostream>
using namespace std;

int n;
char s[110];
map<int,int,greater<int> > q; //这里可以修该map的KEY默认排序规则,加上greater<int>
//就变成了从大到小排序 

int solve(char temp)
{   
	if(temp>='0'&&temp<='9') return temp-'0';
	else if (temp=='A'||temp=='B'||temp=='C') return 2;
	else if (temp=='D'||temp=='E'||temp=='F') return 3;
	else if (temp=='G'||temp=='H'||temp=='I') return 4;
	else if (temp=='J'||temp=='K'||temp=='L') return 5;
	else if (temp=='M'||temp=='N'||temp=='O') return 6;
	else if (temp=='P'||temp=='R'||temp=='S') return 7;
	else if (temp=='T'||temp=='U'||temp=='V') return 8;
	else if (temp=='W'||temp=='X'||temp=='Y') return 9;
	else return -1;
}

int main()
{
	scanf("%d",&n);
	getchar();
	for(int i=1;i<=n;i++)
	{	
		scanf("%s",s);
		int tol=0;
		int cnt=strlen(s);
		for(int j=0;j<cnt;j++)
		{
			int temp = solve(s[j]);
			if (temp==-1) continue;
			else tol =tol*10+temp;
		}
		q[tol]++; 
	}
	map<int,int>::iterator iter;    //map的专用迭代器,作为遍历map用的
	bool flag = false;              //map是有序容器,默认是按照key的字典序排序 
	for(iter =q.begin();iter!=q.end();iter++)
	{
		if (iter->second>1) 
		{
			flag =true;
			printf("%03d-%04d %d\n",iter->first/10000,iter->first%10000,iter->second);
		}	
	} 
	if (!flag) printf("No duplicates.\n");

	return 0;
}

猜你喜欢

转载自blog.csdn.net/peter_xiazhen/article/details/86562908