SNS算法比赛--搞错时间了,没交上就贴出来玩玩,希望大家指教

题目是这样的:

 开心网的自助广告系统于2010年8月上线发布,通过该系统,中小企业或创业型团队可以面向开心网不同地区、年龄、性别的用户进行精准且低成本的广告投放,从而帮助其更好地提升品牌价值、开展市场营销活动。
  在自助广告系统中,用户的地域、年龄、性别等属性都是重要因素,为了更加精准地区分不同地域的用户,除了用户的既有属性之外,还可以根据用户的IP地址进行地域转换。此转换由于是在用户访问时实时执行,所以对性能的要求非常高。
  假设你是开心网的工程师,请实现此种转换。

输入:

  两个文本文件,一个是IP库文件(ipbase.txt),所有IP地址均为IPV4 IP地址,文件为GBK编码, 格式是一行一个IP范围与地址的映射。分为三列,第一列是起始IP,第二列是结束IP,第三列是此范围内的IP(含起始IP和结束IP)对应的地址,列之间以制表符分隔。另一个文件是要查询的IP文件(ipcheck.txt) ,每行为一个IP地址。

输出:

每行输出一个查询结果,格式为:查询的IP 对应的地址(以制表符分隔)。

示例:

IP库文件:

61.50.219.4261.50.221.33北京
61.50.221.3461.50.221.34北京
61.50.221.3561.50.221.42北京
222.33.75.18222.33.75.255辽宁
222.33.76.0222.33.77.255辽宁
222.33.78.0222.33.79.129辽宁
222.33.79.130222.33.79.130辽宁
222.33.79.131222.33.84.105辽宁
222.33.84.106222.33.84.106辽宁
222.36.52.37222.36.52.37天津
222.36.52.38222.36.52.224天津
222.36.52.225222.36.52.225天津
222.36.52.226222.36.64.219天津
222.36.64.220222.36.64.220天津

要查询的IP文件:
61.50.221.34
222.33.76.2
222.33.75.18
222.33.75.19

得到如下结果:
61.50.221.34 北京
222.33.76.2 辽宁
222.33.75.18 辽宁
222.33.75.19 辽宁

我的机子比较差劲试运行了一下在给的测试文件情况下生成了50K的文本result.txt 结果耗时170ms

热诚期盼大虾高手指导

实现代码如下:

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

#include <time.h>

using namespace std;

typedef unsigned int UINT;
typedef struct{
UINT start;
UINT close;
string LocId;//以后再改int,先测试
}IpNode;//IP 地址结构体
static UINT NUM_IPS = 10000;//文件行数

void resolveIp(UINT& temp, string IP){//IP 格式为4.0.0.0,转化后从temp返回
temp = 0; int pos = -1; int prepos = 0;
for(int i = 0; i < 4; i++){
   int shift = 24 - 8*i;
   prepos = pos + 1;
   pos = IP.find_first_of(".",prepos);
   temp += (atoi(IP.substr(prepos,pos).c_str()) << shift);
}
}

int main(int argc , char* argv[])
{
clock_t start, finish;//声明时间
start=clock();//开始时间
char* input = argv[1];
char* intha = argv[2];
//cout<< input<<endl<<intha;

//string* IpLoc = new string[NUM_IPS];//用来做地址存储以后map查找
//IpNode* nodes = new IpNode[NUM_IPS];
vector<IpNode> nodes(NUM_IPS);
ifstream inf(input);
if(! inf){
   cerr<<"Could not open ipbase.txt" << endl;
   exit(EXIT_FAILURE);
}
int i;//计数有多少行
for(i = 0; !inf.eof(); i++) {//暂时这样,不能标志到文件结尾
   if(i >= NUM_IPS )
   { NUM_IPS += 1000;
    nodes.resize(NUM_IPS);
   }
   string Ip;
   inf >> Ip;//4.0.0.0
   resolveIp(nodes[i].start, Ip);
   inf >> Ip;
   resolveIp(nodes[i].close, Ip);
   inf >> Ip;
   nodes[i].LocId = Ip;
}
NUM_IPS = i;//重新定长度
//从文件中读入IP输出地址
inf.close();
ifstream read(intha);
ofstream out("result.txt");
if(! read){
   cerr<<"Could not open ipcheck.txt" << endl;
   exit(EXIT_FAILURE);
}

string IP[2000];UINT k = 0;
for(UINT j = 0; !read.eof(); j++){
   if(j < 2000){
    read >> IP[k];
    UINT temp = 1;
    resolveIp(temp, IP[k]);
    UINT l = 0; UINT u = NUM_IPS-1; UINT m;
    if(temp ==0)break;
    for(;;){
     if(l > u){break;}
     m = (l+u)/2;
     if(nodes[m].close < temp)
      l = m +1;
     else if(nodes[m].start >temp)
      u = m -1;
     else if(nodes[m].start <= temp && nodes[m].close >=temp){
    
      out<<IP[k]<<"/t"<<nodes[m].LocId<<endl;
      break;
     }
    }
    k++;
   }
   else{
    k = 0;
   }
}
flush(cout);
out.close();
finish=clock();//结束时间
cout<<endl<<(double)(finish-start)<<endl;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值