poj百练 1002

一开始我没看清题目要求的输出是字符串按升序排列,而是按重复次数生序排列。以致很长时间没通过。请原谅哥大笑

原题大意:英文字母(除Q和Z外)和电话号码存在着对应关系,如下所示:
A,B,C -> 2
D,E,F -> 3
G,H,I -> 4
J,K,L -> 5
M,N,O -> 6
P,R,S -> 7
T,U,V -> 8
W,X,Y -> 9
标准的电话号码格式是xxx-xxxx,其中x表示0-9中的一个数字。有时为了方便记忆电话号码,我们会将电话号码的数字转变为英文字母,如把263-7422记成America。有时,我们还加上“-”作为分隔符,如把449-6753记成Hi-World。当然,我们未必要将所有的数字都转变为字母,比如474-6635可以记成iPhone-5。
总之,一个方便记忆的电话号码由数字和除Q、Z外的英文字母组成,并且可以在任意位置插入任意多的“-”符号。
现在 ,我们有一个列表,记录着许多方便记忆的电话号码。不同的方便记忆的电话号码可能对应相同的标准号码,你的任务就是找出它们。

 

以下是算法的分析:

    第一:我们用一维数组来存贮匹配的数字,可题目要求把q,z去掉,而且怎么将字符与数字进行匹配呢?

    字符本身是24个,那么我们就存24个,把没有的置零就行了。这不是一种方法吗。(如果有很好的方法请联系,虚心受教)

    比如  hash[]="2223334445556667077888990" 就行了。

    第二:匹配并替换成数字后,我们就在操作之前升序排序,反正题目要求,而且排序后可以发现数组的连续内存中号码有一致的情况,除非是 NO duplicates。

    然后就是输出了,注意格式就行了,这题大抵这样.

   但是我打了几次还是没有通过,基本上市 timed limit。

 解决:

   如果用冒泡或者简单快排,就通不过,(我试过)。看了别人的代码。他们用了快速排序。

快排:

原 型: void qsort(void *base, int nelem, int width, int (*fcmp)(const void *,const void *));
功 能: 使用快速排序例程进行排序

参 数:1 待排序数组首地址 2 数组中待排序元素数量 3 各元素的占用空间大小 4 指向函数的指针,用于确定排序的顺序
说明:qsort函数是ANSI C标准中提供的,其声明在stdlib.h文件中,是根据二分法写的,其时间复杂度为n*log(n)。
qsort要求提供的函数是需要自己定义的一个比较函数,比较函数使得qsort通用性更好。有了比较函数qsort可以实现对数组、字符串、结构体等结构进行升序或降序排序。
如int cmp(const void *a, const void *b)中有两个元素作为参数,返回一个int值,如果比较函数返回大于0,qsort就认为a > b,返回小于0qsort就认为a < b。qsort知道元素的大小了,就可以把大的放前面去。如果你的比较函数返回本来应该是1的(即a > b),而却返回-1(小于0的数),那么qsort认为a < b,就把b放在前面去,但实际上是a > b的,所以就造成了降序排序的差别了。
 
代码:

#include <stdio.h>
#include<string.h>
#include<stdlib.h>
char hash[] = "22233344455566670778889990";

char telphone[100001][20];
char temp[20];

int compare( const void *arg1, const void *arg2 )
{
   return strcmp((char*)arg1, (char*)arg2 );
}

int main()
{

 int flag = 0;
 int nCases,j,k,i;

 int t;
 scanf("%d", &nCases);
 for(i = 0; i < nCases; ++i)
 {
  
  scanf("%s", telphone[i]);
      t=0;
  for(j = 0; j <strlen(telphone[i]); ++j)
  {
   if(telphone[i][j] >= 'A' && telphone[i][j] <= 'Z')
    temp[t++] = hash[telphone[i][j]-'A'];
   else if(telphone[i][j] >= '0' && telphone[i][j] <= '9')
    temp[t++] = telphone[i][j];
   else if(telphone[i][j] == '-')
    ;
  }
  strcpy(telphone[i], temp);
 }

 qsort(telphone, nCases, sizeof(telphone[0]), compare);//必须有排序函数。


 for(i = 0; i < nCases; ++i)
 {

  int cnt = 1;
  strcpy(temp, telphone[i]);
  
  for(j = i+1; j < nCases; ++j)
  {
   if(strcmp(temp, telphone[j]) == 0)
    cnt++;
   else
    break;
  }
  if(cnt > 1) 
  {
   flag = 1;
   for(k = 0; k < 3; ++k)
    printf("%c", temp[k]);
   printf("-");
   for(k = 3; k < 7; ++k)
    printf("%c", temp[k]);
   printf(" %d\n", cnt);
  }
  i = j-1;
 }
 if(flag == 0)
  printf("No duplicates.\n");


 return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值