| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 4321 人关注过本帖
标题:电话号码问题(我保证很难)
只看楼主 加入收藏
feng1256
Rank: 4
等 级:贵宾
威 望:14
帖 子:2899
专家分:0
注 册:2005-11-24
收藏
得分:0 


叁蓙大山:工謪、稅務、嗣發 抱歉:不回答女人的问题
2006-05-27 06:32
youxiaxyz
Rank: 1
等 级:新手上路
帖 子:85
专家分:0
注 册:2006-4-5
收藏
得分:0 
以下是引用–★–在2006-5-27 5:16:00的发言:
可行性分析:
1。连字符位置固定,信息量为零。可在输出阶段搞定。
2。七位号码最大9999999,小于256的立方,宜用自定义的长度为3字节的“无符号整型u3”表示之。反之,如果用字符数组char[7~8]表示,一则内存开销大一倍以上,二则排序速度也劣于整数比大小。
3。依题意,独立的电话号码数不超过10000个,每个号码的重复次数不超过100。因此可定义如下的无名结构数组解决问题:
struct {
unsigned short low2;
unsigned char high1;//二者联合起来充当u3类型
unsigned char times;//记录重复次数
} NB[10000];
4。庞大的输入数据分批读入内存,以减少内存开销。
5。关于填充NB[]数据库的初步考虑
⑴折半查找过程(找到则times++否则)
⑵插入排序过程(此环节速度怕有问题)
6。[补充]实际上用long int存放号码也完全可行。
7。[自评]本方案可能在速度上难以达到额定要求。

题目是说可能重复的号码不超过10000,并不是说独立的号码

2006-05-27 08:58
feng1256
Rank: 4
等 级:贵宾
威 望:14
帖 子:2899
专家分:0
注 册:2005-11-24
收藏
得分:0 

昨天写的,本来不想发,不过留着也没什么用
先发出来,看看大家的修改意见,以达到题目要求,特别是内存限制

如果用数组,因为原始数据最多有一百万个之多,没输入最后一个数据之前
无法判断以前的数据哪个会不会重复,所以数据都得存起来,感觉不合适!

代码运行环境,C-Free(XP)
[CODE]
#include "stdio.h"
#include "malloc.h"
#include "stdlib.h"

typedef struct node{
long tel_num; /*号码*/
char frequ_num; /*重复次数*/
struct node* next;
} *Linklist,Node;
long n;
char code[8][4]={ "ABC","DEF","GHI","JKL","MNO","PRS","TUV","WXY"};

int Sear_subcript(char ch) /*找到字符对应的数字字符*/
{
int i,j;

for(i=0;i<7;i++)
for(j=0;j<3;j++)
if(code[i][j]==ch)
return i+50;
return 0;
}

Linklist Infor_Input(void)
{
Linklist head, newp,previousp,currentp;
int j,subcript;
long i;
char ch,str[15];

head=(Linklist) malloc (sizeof(Node));
if(head==NULL)
exit(-1);
head->next=NULL;
for(i=0;i<n;i++)
{

newp=(Linklist) malloc (sizeof(Node));
if(newp==NULL)
exit(-1);
newp->next=NULL;
for(j=0;j<8;j++)
{
ch=getchar();
if(ch>='0'&&ch<='9')
str[j]=ch;
else if(subcript=Sear_subcript(ch))
str[j]=subcript;
else if(ch=='\n')
{
str[7]='\0';
newp->tel_num=atol(str); /*转化为数字*/
newp->frequ_num=1;
break;
}
else
j--;
}
if(!head->next) /*链表的一个按数字大小的前插操作*/
head->next=newp;
else
{
previousp=NULL;
currentp=head->next;
if(currentp->tel_num == newp->tel_num)
currentp->frequ_num++;
else if(currentp->tel_num > newp->tel_num)
{
newp->next=currentp;
head->next=newp;
}
else
while( currentp->tel_num < newp->tel_num)
{
previousp=currentp;
currentp=currentp->next;
if(currentp)
{
if(currentp->tel_num == newp->tel_num)
{
currentp->frequ_num++;
break;
}
if(currentp->tel_num > newp->tel_num)
{
previousp->next=newp;
newp->next=currentp;
break;
}
}
else
{
previousp->next=newp;
break;
}
}
}
}
return head;
}

void Display_result(Linklist head)
{
int flag=0;

head=head->next;
while(head)
{
if(head->frequ_num>1)
{
printf("%03ld-%04ld %d\n",head->tel_num/10000,
head->tel_num%10000,head->frequ_num);
flag=1;
}
head=head->next;
}
if(!flag)
printf("No duplication!\n");
}

void Destory_Linklist(Linklist head)
{
Linklist currentp;

while(head)
{
currentp=head;
head=head->next;
free(currentp);
}
}

int main()
{
Linklist head;


printf("n=");
scanf("%ld",&n);
fflush(stdin); /*处理掉\n*/
head=Infor_Input();
printf("\n\n");
Display_result(head);
Destory_Linklist(head);

return 0;
}


[/CODE]


叁蓙大山:工謪、稅務、嗣發 抱歉:不回答女人的问题
2006-05-28 02:05
–★–
Rank: 3Rank: 3
等 级:新手上路
威 望:6
帖 子:1512
专家分:0
注 册:2006-5-1
收藏
得分:0 
感谢12楼(即楼主)提醒。再次进行
【可行性分析】
1。连字符位置固定,信息量为零。可在输出阶段搞定。
2。依题意,独立的电话号码数可能达1百万个,因此难以用常规方法解决问题。但是
3。考虑到该城市的电话号码仅7位,最多只有1千万种可能性,原则上开个庞大的char nb[10,000,000]数组便能解决问题。然而这违反题目要求,怎么办?
4。因为1千万bit/8≈1.25MB<1.5MB,所以定义一个庞大的static unsigned char NB[1250000]数组 然后1bit、1bit地使用方能满足题目要求。这么做的优点:电话号码实际上是自动排序的。缺点:只能弄清某号码用过没有,无法知道复用次数。为此
5。再定义拥有10000个元素的结构体数组
struct {
unsigned long number;//七位电话号码
unsigned char times; //记录复用次数
} DUP[10000];
6。本方案数据占用内存
1250000+10000×(4+1)=1300000bytes,
代码很短,可忽略不计。

落霞与孤鹜齐飞,秋水共长天一色! 心有多大,路有多宽。三教九流,鸡鸣狗盗。兼收并蓄,海纳百川。
2006-05-28 06:11
soft_wind
Rank: 3Rank: 3
等 级:新手上路
威 望:8
帖 子:1430
专家分:0
注 册:2006-4-5
收藏
得分:0 

我觉得还是用链表来做好些,就像版主老大那样,
至于内存,就让当号码重复的次数大于100时就输出然后释放掉.
不然是不可能到达要求的.


对不礼貌的女生收钱......
2006-05-28 08:25
soft_wind
Rank: 3Rank: 3
等 级:新手上路
威 望:8
帖 子:1430
专家分:0
注 册:2006-4-5
收藏
得分:0 
不过也不好办,不能确定它的顺序,哎,
这样输出顺序很可能不对,
不行哩!

对不礼貌的女生收钱......
2006-05-28 08:26
soft_wind
Rank: 3Rank: 3
等 级:新手上路
威 望:8
帖 子:1430
专家分:0
注 册:2006-4-5
收藏
得分:0 
把翻译过来的号码都写入文件中去,大家看这样行不行,
然后再读文件排序统计?OK?

对不礼貌的女生收钱......
2006-05-29 16:16
feng1256
Rank: 4
等 级:贵宾
威 望:14
帖 子:2899
专家分:0
注 册:2005-11-24
收藏
得分:0 
这办法真狡猾,,得读入一个写一个,把数据转移到硬盘上去了,估计是可以的

叁蓙大山:工謪、稅務、嗣發 抱歉:不回答女人的问题
2006-05-29 16:52
–★–
Rank: 3Rank: 3
等 级:新手上路
威 望:6
帖 子:1512
专家分:0
注 册:2006-5-1
收藏
得分:0 

/*-----------------*
电话号码问题(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编辑过]


落霞与孤鹜齐飞,秋水共长天一色! 心有多大,路有多宽。三教九流,鸡鸣狗盗。兼收并蓄,海纳百川。
2006-05-29 17:04
走刀口→超
Rank: 6Rank: 6
等 级:贵宾
威 望:20
帖 子:5018
专家分:0
注 册:2006-3-14
收藏
得分:0 
崩溃。根本不明白这是啥米。。。
不知道要什么时候才能看懂,最近为网页忙太多了。。。

人在江湖【走】,怎能不挨【刀】;为了能活【口】,唯有把己【超】!come on...
2006-05-29 17:24
快速回复:电话号码问题(我保证很难)
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.012903 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved