内推阿里电话面试中面试官给我出的一个题:

我想的头一个解决方案,就是放到stl 的map里面对出现的频率作为pair的第二个字段进行排序,之后按照排序结果返回:

下面口说无凭,show your code,当然在讨论帖子中遭遇了工程界大牛的sql代码在技术上的碾压。什么是做工程的,什么是工程师的思维,不要一味的埋头搞算法。

讨论帖:

http://bbs.csdn.net/topics/391080906

python 抓取百度搜索结果的讨论贴:

http://bbs.csdn.net/topics/391077668

实验数据,python从百度抓得:

# -*- coding: utf-8 -*-
"""
Spyder Editor This is a temporary script file.
""" import urllib2
import re
import os #connect to a URL
#一页的搜索结果中url大概是200个左右
file_url = open('url.txt','ab+')
#搜索框里的东西,这块可以设置成数字好让每次搜索的结果不一样
search = '123'
url = "http://www.baidu.com/s?wd="+search def setUrlToFile():
website = urllib2.urlopen(url)
#read html code html = website.read() #use re.findall to get all the links links = re.findall('"((http|ftp)s?://.*?)"', html) for s in links:
print s[0]
if len(s[0]) < 256:
file_url.write(s[0]+'\r\n') #收集实验数据
for i in range(0,50):
setUrlToFile() file_url.close() ###需要重新打开再读一下
file_url = open('url.txt','r')
file_lines = len(file_url.readlines())
print "there are %d url in %s" %(file_lines,file_url)
file_url.close()

方法1:

c++  写的读 url.txt放到map里面

对map<string , int>的value进行排序,得到前100个

运行一下也就55s,还是很快的,url长度进行了限制小于256个字符

#pragma once
/*
//计算代码段运行时间的类
//
*/
#include <iostream> #ifndef ComputeTime_h
#define ComputeTime_h //单位毫秒 class ComputeTime
{
private:
int Initialized;
__int64 Frequency;
__int64 BeginTime; public: bool Avaliable();
double End();
bool Begin();
ComputeTime();
virtual ~ComputeTime(); }; #endif
#include "stdafx.h"
#include "ComputeTime.h"
#include <iostream>
#include <Windows.h> ComputeTime::ComputeTime()
{
Initialized=QueryPerformanceFrequency((LARGE_INTEGER *)&Frequency);
} ComputeTime::~ComputeTime()
{ } bool ComputeTime::Begin()
{
if(!Initialized)
return 0; return QueryPerformanceCounter((LARGE_INTEGER *)&BeginTime);
} double ComputeTime::End()
{
if(!Initialized)
return 0; __int64 endtime; QueryPerformanceCounter((LARGE_INTEGER *)&endtime); __int64 elapsed = endtime-BeginTime; return ((double)elapsed/(double)Frequency)*1000.0; //单位毫秒
} bool ComputeTime::Avaliable()
{
return Initialized;
} // sortUrl.cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h"
//#include <utility>
#include <vector>
#include <map>
#include <fstream>
#include <iostream>
#include <string>
#include <algorithm>
#include "ComputeTime.h" using namespace std; map<string,int> urlfrequency; typedef pair<string, int> PAIR; struct CmpByValue
{
bool operator()(const PAIR& lhs, const PAIR& rhs)
{
return lhs.second > rhs.second;
}
}; void find_largeTH(map<string,int> urlfrequency)
{
//把map中元素转存到vector中 ,按照value排序
vector<PAIR> url_quency_vec(urlfrequency.begin(), urlfrequency.end());
sort(url_quency_vec.begin(), url_quency_vec.end(), CmpByValue());
//url_quency_vec.size()
for (int i = 0; i != 100; ++i)
{
cout<<url_quency_vec[i].first<<endl;
cout<<url_quency_vec[i].second<<endl;
}
} //urlheap的建立过程,URL插入时候存在的
void insertUrl(string url)
{
pair<map<string ,int>::iterator, bool> Insert_Pair;
Insert_Pair = urlfrequency.insert(map<string, int>::value_type(url,1)); if (Insert_Pair.second == false)
{
(Insert_Pair.first->second++);
} } int _tmain(int argc, _TCHAR* argv[])
{
fstream URLfile;
char buffer[1024];
URLfile.open("url.txt",ios::in|ios::out|ios::binary); if (! URLfile.is_open())
{ cout << "Error opening file"; exit (1); }
else
{
cout<<"open file success!"<<endl;
} ComputeTime cp;
cp.Begin();
int i = 0;
while (!URLfile.eof())
{
URLfile.getline (buffer,1024);
//cout << buffer << endl;
string temp(buffer);
//cout<<i++<<endl;
insertUrl(temp);
} find_largeTH(urlfrequency); cout<<"running time: "<<cp.End()<<"ms"<<endl; getchar();
//system("pause");
return 0;
}

实验结果:55s还不算太差,可以接受,毕竟是头脑中的第一个解决方案。

方法2:

hash code 版本,只是不知道怎么 hash和url关联起来:

// urlFind.cpp : 定义控制台应用程序的入口点。
// // sortUrl.cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h" #include <vector>
#include <map>
#include <fstream>
#include <iostream>
#include <string>
#include <algorithm>
#include <unordered_map>
#include "ComputeTime.h" using namespace std; map<unsigned int,int> urlhash; typedef pair<unsigned int, int> PAIR; struct info{
string url;
int cnt;
bool operator<(const info &r) const {
return cnt>r.cnt;
}
}; unordered_map<string,int> count; //priority_queue<info> pq; struct CmpByValue
{
bool operator()(const PAIR& lhs, const PAIR& rhs)
{
return lhs.second > rhs.second;
}
}; void find_largeTH(map<unsigned int,int> urlhash)
{
//把map中元素转存到vector中 ,按照value排序
vector<PAIR> url_quency_vec(urlhash.begin(), urlhash.end());
sort(url_quency_vec.begin(), url_quency_vec.end(), CmpByValue());
//url_quency_vec.size()
for (int i = 0; i != 100; ++i)
{
cout<<url_quency_vec[i].first<<endl;
cout<<url_quency_vec[i].second<<endl;
}
} // BKDR Hash Function
unsigned int BKDRHash(char *str)
{
unsigned int seed = 131; // 31 131 1313 13131 131313 etc..
unsigned int hash = 0; while (*str)
{
hash = hash * seed + (*str++);
} return (hash & 0x7FFFFFFF);
} //
void insertUrl(string url)
{ unsigned int hashvalue = BKDRHash((char *)url.c_str());
pair<map<unsigned int ,int>::iterator, bool> Insert_Pair;
Insert_Pair = urlhash.insert(map<unsigned int, int>::value_type(hashvalue,1)); if (Insert_Pair.second == false)
{
(Insert_Pair.first->second++);
} } int _tmain(int argc, _TCHAR* argv[])
{
fstream URLfile;
char buffer[1024];
URLfile.open("url.txt",ios::in|ios::out|ios::binary); if (! URLfile.is_open())
{ cout << "Error opening file"; exit (1); }
else
{
cout<<"open file success!"<<endl;
} ComputeTime cp;
cp.Begin();
int i = 0;
while (!URLfile.eof())
{
URLfile.getline (buffer,1024);
//cout << buffer << endl;
string temp(buffer);
//cout<<i++<<endl;
insertUrl(temp);
} find_largeTH(urlhash); cout<<"running time: "<<cp.End()<<"ms"<<endl; getchar();
//system("pause");
return 0;
}

性能15秒左右:缺点在于没有把hashcode和url进行关联,技术的处理速度已经非常可观了

方法3:

下面用STL的hash容器unordered_map,和优先队列(就是堆)来实现这个问题。

// urlFind.cpp : 定义控制台应用程序的入口点。
// // sortUrl.cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h" #include <vector>
#include <map>
#include <fstream>
#include <iostream>
#include <string>
#include <algorithm>
#include <unordered_map>
#include <queue>
#include "ComputeTime.h" using namespace std; typedef pair<string, int> PAIR; struct info
{
string url;
int cnt;
bool operator<(const info &r) const
{
return cnt<r.cnt;
}
}; unordered_map<string,int> hash_url; priority_queue<info> pq; void find_largeTH(unordered_map<string,int> urlhash)
{ unordered_map<string,int>::iterator iter = urlhash.begin();
info temp;
for (; iter!= urlhash.end();++iter)
{
temp.url = iter->first;
temp.cnt = iter->second;
pq.push(temp);
} for (int i = 0; i != 100; ++i)
{ cout<<pq.top().url<<endl;
cout<<pq.top().cnt<<endl;
pq.pop();
}
} void insertUrl(string url)
{ pair<unordered_map<string ,int>::iterator, bool> Insert_Pair;
Insert_Pair = hash_url.insert(unordered_map<string, int>::value_type(url,1)); if (Insert_Pair.second == false)
{
(Insert_Pair.first->second++);
} } int _tmain(int argc, _TCHAR* argv[])
{
fstream URLfile;
char buffer[1024];
URLfile.open("url.txt",ios::in|ios::out|ios::binary); if (! URLfile.is_open())
{ cout << "Error opening file"; exit (1); }
else
{
cout<<"open file success!"<<endl;
} ComputeTime cp;
cp.Begin();
int i = 0;
while (!URLfile.eof())
{
URLfile.getline (buffer,1024);
//cout << buffer << endl;
string temp(buffer);
//cout<<i++<<endl;
insertUrl(temp);
} find_largeTH(hash_url); cout<<"running time: "<<cp.End()<<"ms"<<endl; getchar();
//system("pause");
return 0;
}

基本上算是算法里面比较优秀的解决方案了,面试官如果能听到这个方案应该会比较欣喜。





方法4:实验耗时未知,技术上碾压了上述解决方案,中高年轻人,不要重复造轮子!哈哈

数据库,SQL语句:

load data infile "d:/bigdata.txt" into table tb_url(url);

SELECT
url,
count(url) as show_count
FROM
tb_url
GROUP BY url
ORDER BY show_count desc
LIMIT 100





阿里电话面试问题----100万个URL如何找到出现频率最高的前100个?的更多相关文章

  1. 阿里电话面试问题----100万个URL怎样找到出现频率最高的前100个?

    内推阿里电话面试中面试官给我出的一个题: 我想的头一个解决方式.就是放到stl 的map里面对出现的频率作为pair的第二个字段进行排序.之后依照排序结果返回: 以下口说无凭,show your co ...

  2. SQL 从100万条记录中的到 成绩最高的记录

    从100万条记录中的到 成绩最高的记录 问题分析:要从一张表中找到成绩最高的记录并不难,有很多种办法,最简单的就是利用TOP 1 select top 1 * from student order b ...

  3. 阿里Java开发电话面试经历--惨败

    近期准备跳槽,想试试知名大企业--阿里.经过boss直聘上一些内部人员的内推,有幸获得了一次电话面试的机会.(虽然在面试开始之前就大概知道结果是如何,但是也总得试试自己个有多水,哈哈哈...) 跟大家 ...

  4. 阿里P8面试官:如何设计一个扛住千万级并发的架构?

    大家先思考一个问题,这也是在面试过程中经常遇到的问题. 如果你们公司现在的产品能够支持10W用户访问,你们老板突然和你说,融到钱了,会大量投放广告,预计在1个月后用户量会达到1000W,如果这个任务交 ...

  5. Java 最常用类(前100名)来自一万个开源项目

    大部分的 Java 软件开发都会使用到各种不同的库.近日我们从一万个开源的 Java 项目中进行分析,从中提取出最常用的 Java 类,这些类有来自于 Java 的标准库,也有第三方库.每个类在同一个 ...

  6. 上海支付宝终面后等了两周,没能收到offer却来了杭州淘宝的电话面试

    上上周一(14/12/22)上海支付宝hr终面 http://www.cnblogs.com/zhanghaoh/p/4178386.html 苦苦等了两周,没能如愿收到offer,却在今天等来了 杭 ...

  7. 电话面试问答Top 50 --[伯乐在线]

    今年是2015年,在过去几年中,电面(电话面试)是筛选程序员职位候选人的最流行的方式.它让雇佣双方很容易互相了解对方,候选人不需要去未来雇主的所在地,面试官也不用做额外的安排.这是我介绍程序员面试问题 ...

  8. 100万套PPT模板,包含全宇宙所有主题类型PPT,绕宇宙100圈,持续更新

    100万套PPT模板,包含全宇宙所有主题类型PPT(全部免费,都是精品,没有一张垃圾不好看的PPT,任何一张PPT拿来套入自己的信息就可以立马使用),绕宇宙100圈,任意一个模板在某文库上都价不菲.强 ...

  9. 如何通过Dataphin构建数据中台新增100万用户?

    欢迎来到数据中台小讲堂!这一期我们来看看,作为阿里巴巴数据中台(OneData - OneModel.OneID.OneService)方法论的产品载体,Dataphin如何帮助传统零售企业实现数字化 ...

随机推荐

  1. BZOJ#1717:[Usaco2006 Dec]Milk Patterns 产奶的模式(后缀数组+单调队列)

    1717: [Usaco2006 Dec]Milk Patterns 产奶的模式 Description 农夫John发现他的奶牛产奶的质量一直在变动.经过细致的调查,他发现:虽然他不能预见明天产奶的 ...

  2. OpenCV设置摄像头分辨率及全屏显示

    OpenCV3.0下 设置摄像头分辨率为1920*1440,并全屏显示图像窗口. int _tmain(int argc, _TCHAR* argv[]) { Mat frame; VideoCapt ...

  3. Python安装与环境变量的配置

    python下载: Python安装包下载地址:http://www.python.org/ 根据实际的操作系统,安装合适的安装版本. Python安装: 本文以python 2.7.8(64位)为例 ...

  4. ctf writeup之程序员密码

    起因 在v2ex上看到有人发了一篇帖子,说做了一个程序员小游戏,遂试玩了一下. 游戏的地址在这里: http://www.bettertomissthantomeet.com/pages/level. ...

  5. Eleven

    A. Eleven time limit per test : 1 second memory limit per test:  256 megabytes input:  standard inpu ...

  6. C++格式化输出浮点数

    主要内容 介绍C++中如何格式化输出浮点数. 控制浮点数输出格式需要包含iomanip头文件. 使用fixed来控制输出的浮点数的小数位是固定的.可参考http://en.cppreference.c ...

  7. pyinstaller 工具起步

    准备 依赖 pyinstaller下载 语法 核心命令 可选项 实战 md2htmlpy 使用pyinstaller 其他测试 -D选项 --icon选项 遇到错误怎么办 总结 继上次的那个Pytho ...

  8. Swift基础之使用Alamofire库进行网络请求和断点下载

    好久没有写过Swift相关的文章博客了,这里我就展示一下关于使用Alamofire库的方法 1.什么是Alamofire (1)Alamofire 的前身是 AFNetworking.AFNetwor ...

  9. springMVC源码分析--SimpleUrlHandlerMapping(四)

    上一篇博客springMVC源码分析--AbstractUrlHandlerMapping(三)中我们介绍了AbstractUrlHandlerMapping,主要介绍了一个handlerMap的ur ...

  10. C++ 虚函数表 单继承

    本文研究单继承情况下,c++对象的虚函数表的具体情况. 假设有两个类A,B, 其中B由A派生出来,A含有虚函数fun1,B含有虚函数fun2. 测试的代码如下: #include<iostrea ...