用标准C++搞定了一个小ACM题

问题描述在这里:http://acm.pku.edu.cn/JudgeOnline/problem?id=1002
   
大致意思就是输入一系列字符,按照一定的规则把其转化成标准格式的电话号码,统计,对重复出现的电话号码进行计数,最后按照号码的升序排列输出 。

大致就能想到应该是分成这么几步:

1.                对每一行字符串转换成标准格式,将结果存储在一个类中,用“标

准号码”来命名这个类,就是SStdTelNo

2.                对所有号码的重复个数进行统计

3.                排序

后来想了一下,23是可以放在一步里做的,就是做成Binary Tree。一边插入排序一边统计重复个数。这样的效率也可以大大提高 。 可惜啊,这个程序为了贪图简便,没有采用这样的方法。

结果其实还是有问题的,就是运行超时了。一方面可能由于服务器上测试数据很多,没有采用好的算法导致运行时间过长;另一方面由于采用C++引入的效率损耗。最近没有时间,等假期有时间再写一个BINARYTREE的版本,试试能不能完全通过.  :)

不多说了,代码如下:

#include <iostream>
#include 
<fstream>
#include 
<string>
#include 
<vector>

using namespace std;

class SStdTelNo {

public:
    
static SStdTelNo parseTelNo(const string & str) {
        SStdTelNo ret;
        
char digit;
        
if(str.size()<7)
            
return ret;
        unsigned 
int count = 0;
        
for(int i=0;i<str.size() && count<7;i++){
            digit 
= str[i];
            
if(digit>='0' && digit<='9'
                ret.num[count
++= digit;
            
else if(digit>='A' && digit<='R'
                ret.num[count
++= (digit - 'A')/3 + '2';
            
else if(digit>='S' && digit<='Y')
                ret.num[count
++= (digit - 'S' + 2)/3 + '7';
    }

        
if(count!=7)
        
return SStdTelNo();
    
        
return ret;
    }

public:
    SStdTelNo() 
{
        
for(int i=0;i<7;i++)
            num[i]
='0';
        num[
7= '';
    }

    SStdTelNo(
const char * buf){
        
for(int i=0;i<7;i++{
            
if(buf[i]>='0' && buf[i]<='9')
                num[i] 
= buf[i];
            
else{
                
*this=SStdTelNo();
                
break;
        }

        }

    }


public:
    
void toString(string & str) {
        str 
= "";
        str.append(num,
3);
        str.append(
"-");
        str.append(num
+3,4);
    }

    
bool operator==(const SStdTelNo & obj) {
    
for(int i=0;i<7;i++)
            
if(num[i]!=obj.num[i])
                
return false;

        
return true;
    }

    
bool operator>(const SStdTelNo & obj) {
        
if(strcmp(num,obj.num)>0)
            
return true;
        
return false;
    }

private:
    
char num[8];
}
;

int main()
{
    
string rawTel;
    
string stdTel;
    SStdTelNo stdTelObj;
    vector
<SStdTelNo> numbers;
    vector
<int>       counters;
 
    
int count;
    cin
>>count;
    
//    ifstream in("data.txt");
    while(count--){
        getline(cin,rawTel);
        stdTelObj 
= SStdTelNo::parseTelNo(rawTel);
    
//    stdTelObj.toString(stdTel);
    
//    cout<<stdTel<<endl;
        int index;
        
for(index=0;index<numbers.size();index++{
            
if(stdTelObj == numbers[index]) {
                counters[index]
++;
                
break;
            }

        }

        
if(index==numbers.size()) ///Didnt find a match;
            numbers.push_back(stdTelObj);
            counters.push_back(
1);
        }

    }

    
////Bubble Sort
    unsigned int round,index;
    
for(round=1;round<numbers.size();round++)
        
for(index=0;index<numbers.size()-round;index++{
        
if(numbers[index]>numbers[index+1]) {
        SStdTelNo temp 
= numbers[index];
                numbers[index] 
= numbers[index+1];
                numbers[index
+1= temp;

                
int temp2 = counters[index];
                counters[index] 
= counters[index+1];
                counters[index
+1= temp2;
        }

        }

    
////Output result;
    for(index=0;index<numbers.size();index++{
        
if(counters[index]!=1{
            numbers[index].toString(stdTel);
            cout
<<stdTel<<' '<<counters[index]<<endl;
        }

    }

    
return 1;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值