

叁蓙大山:工謪、稅務、嗣發 抱歉:不回答女人的问题
 2006-05-27 06:32
	    2006-05-27 06:32
  题目是说可能重复的号码不超过10000,并不是说独立的号码
 2006-05-27 08:58
	    2006-05-27 08:58
  昨天写的,本来不想发,不过留着也没什么用
先发出来,看看大家的修改意见,以达到题目要求,特别是内存限制
如果用数组,因为原始数据最多有一百万个之多,没输入最后一个数据之前
无法判断以前的数据哪个会不会重复,所以数据都得存起来,感觉不合适!
代码运行环境,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;
}

 2006-05-28 02:05
	    2006-05-28 02:05
  
 2006-05-28 06:11
	    2006-05-28 06:11
   2006-05-28 08:25
	    2006-05-28 08:25
   2006-05-28 08:26
	    2006-05-28 08:26
   2006-05-29 16:16
	    2006-05-29 16:16
   2006-05-29 16:52
	    2006-05-29 16:52
  /*-----------------*
  电话号码问题(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
	    2006-05-29 17:04
   2006-05-29 17:24
	    2006-05-29 17:24