/*-----------------*
电话号码问题(VC下)
*-----------------*/
#include<stdio.h>
#include<stdlib.h> //调用ldiv()
#include<string.h> //调用memmove()
#define LPHONE 7 //电话号码的位数
char b['Z']={0, //将诸如ABC译为2,…,WXY译为9等
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0,0,
2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,0,7,7,8,8,8,9,9,9};
char NB[1250000];//可存放1千万个不同号码
struct
{
long num;//号码本身
char dup;//复用次数
} ph[10000],*p;
int iph=0;//统计复用号码总数
//将num写入复用号码表ph[ ]
void insert(long num)
{
int i;
//以下是顺序搜索最好改成二分搜索
for(p=ph,i=0;i<iph;i++,p++)
if(num<p->num)break;
else if(num==p->num)
{ p->dup++;return; }
memmove(p+1,p,(iph-i)*sizeof(ph[0]));
p->num=num;
p->dup=2;//为何不是1?
iph++;
}
int main()
{
ldiv_t re; //这是ldiv()所要求的
int ntest=12; //测试数据有12个
char*test[ ]={//具体测试数据如下
"4873279","ITS-EASY","888-4567","3-10-10-10",
"888-GLOP","TUT-GLOP","967-11-11","310-GINO",
"F101010","888-1200","-4-8-7-3-2-7-9","487-3279",
};
unsigned char tmp,val;
int i,j,k;
long nb;
for(j=0;j<ntest;j++)
{
for(nb=k=i=0;i<LPHONE;k++)
{
sscanf(test[j]+k,"%c",&tmp);
if(tmp=='-')continue;
nb=nb*10+b[tmp];
++i;
}
re=ldiv(nb,8);//效果re.rem=nb%8和re.quot=nb/8
val=1;val<<=re.rem;//效果val=pow(2,re.rem)
tmp=NB[re.quot];
if(tmp+val==(tmp|val)) //这是得意之笔
NB[re.quot]|=val;//若是迄今未见复用的号码,相应位置1
else insert(nb);
}
//效果验证:
if(iph==0)
printf("No duplication\n");
else
for(p=ph,i=0;i<iph;i++,p++)
{ re=ldiv(p->num,10000);
printf("%d: %03d-%04d %d\n",i+1,re.quot,re.rem,p->dup);
}
return 0;
}
[此贴子已经被作者于2006-5-30 9:25:43编辑过]