欢迎光临!欢迎分享转载本站文章,尊重原创,转载请注明出处!

扑克洗牌算法(c++版)

2017年3月20日 没有评论

这是三年前去一家游戏公司面试时被问到的一个问题,当时由于自己在传统软件公司做业务,对算法没有留心学习,虽勉强答出来了,但从未实现过。今天随手写了个小程序做下验证。

基本思路:将代表扑克牌的52个数字放入vector中,每次随机抽取一张放入新的vector,并将被抽取牌从原vector中删除。如此循环52次,即可得到随机化的牌面。

代码如下:

#include <iostream>
using namespace std;
#include <vector>
#include <stdlib.h>

int main()
{
unsigned int total;
cout << “Please input the TOTAL:” << endl;  //输入52
cin >> total;

//将52个数放入vCards0

vector<unsigned int> vCards0;
unsigned int i=1;
while(i <= total)
{
vCards0.push_back(i++);
}

vector<unsigned int> vCards1(vCards0);   //初始化另一个vector
unsigned int idx=0;
srand(time(NULL));

i=0;
unsigned int tt=total;
while(i < total)  //依次抽取52张牌
{
idx = rand() % tt;  //从vCards0中随机抽取一张牌
–tt;
vCards1[i++]=vCards0[idx];  //放入vCards1

//从vCards0中删除被抽取的那张牌

vector<unsigned int>::iterator vi=vCards0.begin();
unsigned int j=0;
while(j < idx)
{
++j;
++vi;
}
vCards0.erase(vi);
}

vector<unsigned int>::iterator vib=vCards1.begin();
vector<unsigned int>::iterator vie=vCards1.end();
while(vib != vie)
{
cout << *vib++ << ” “;
}
cout << endl;

return 0;
}

当然网上还有一些效率更高的算法,大家有兴趣可以找来看看。

分类: C/C++ 标签:

使用openresty+redis轻松实现网站访问统计

2017年2月16日 没有评论

网站的受访统计是网站运营和优化的一个重要参考数据,对于并发量较大的网站,我们可以通过nginx+redis的架构来简单实现页面受访统计。这主要得益于nginx的高并发性能和redis快速存取内存数据。实际应用中,我们可以使用openresty来快速搭建统计系统。

openresty集合了lua和lua-redis访问库,可以通过编写nginx.conf配置文件实现对redis数据库的存取。简单且高效。

  1. 安装和配置openresty及redis
  2. 修改nginx.conf,示例:

    http {
    include mime.types;
    default_type application/octet-stream;
    sendfile on;
    keepalive_timeout 65;

    server {
    listen 8088;
    server_name www.test.com;

    location /get_pv {
    set $id_param $args;
    content_by_lua ‘
    local redis_mod = require “resty.redis”
    local redis_db= redis_mod:new()
    redis_db:set_timeout(1000) — 1 second

    local ok, err = redis_db:connect(“127.0.0.1″, 6379)
    if not ok then
    ngx.log(ngx.ERR, “failed to connect to redis: “, err)
    return ngx.exit(500)
    end

    local id = string.sub(ngx.var.id_param, 4)
    local pv, err = redis_db:get(id)
    if not pv then
    redis_db:close()
    ngx.log(ngx.ERR, “failed to get redis key: “, id, err)
    return ngx.exit(500)
    end

    if pv == ngx.null then
    redis_db:close()
    ngx.log(ngx.ERR, “no pv found for “, id)
    return ngx.exit(400)
    end

    redis_db:close()

    ngx.header.content_type = “text/plain”;
    ngx.say(pv)
    ‘;
    }
    }

    server {
    listen 9099;
    server_name www.test.com;

    location /set_pv {
    set $id_param $args;
    content_by_lua ‘
    local redis_mod = require “resty.redis”
    local redis_db= redis_mod:new()
    redis_db:set_timeout(1000) — 1 second

    local ok, err = redis_db:connect(“127.0.0.1″, 6379)
    if not ok then
    ngx.log(ngx.ERR, “failed to connect to redis: “, err)
    return ngx.exit(500)
    end

    local id = string.sub(ngx.var.id_param, 4)
    local pv = redis_db:incr(id)
    if not pv then
    redis_db:close()
    ngx.log(ngx.ERR, “failed to incr redis key: “, id, err)
    return ngx.exit(500)
    end

    redis_db:close()

    ngx.header.content_type = “text/plain”;
    ngx.say(pv)
    ‘;
    }
    }
    }

  3. 在网站页面中部署统计代码

<iframe frameborder=”0″ scrolling=”no” width=”0″  height=”0″ style=”display:none;” src=”http://www.test.com:9099/set_pv?id=page_411“></iframe>

分类: Lua, Redis, 开发 标签: , , ,

openresty在又拍云的使用

2016年12月12日 没有评论
分类: 开发 标签: , ,

Chrome浏览器手机和平板UA的判断方法

2016年12月5日 没有评论

网站页面在进行移动适配时需要考虑如何判断终端类别,除了判别IOS和安卓外,为了达到更好的用户视觉体验,还需要区分手机和平板的差别。

通常是通过UA来区分的。

Chrome上手机和平板的区别是,手机端浏览器UA比平板端多了一个“Mobile”标识:

Phone UA:
Mozilla/5.0 (Linux; <Android Version>; <Build Tag etc.>) AppleWebKit/<WebKit Rev> (KHTML, like Gecko) Chrome/<Chrome Rev> Mobile Safari/<WebKit Rev>
Tablet UA:
Mozilla/5.0 (Linux; <Android Version>; <Build Tag etc.>) AppleWebKit/<WebKit Rev>(KHTML, like Gecko) Chrome/<Chrome Rev> Safari/<WebKit Rev>

比如,以下是Galaxy Nexus上Chrome的UA示例:

Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19

可以用以下正则表达式来判别:

Phone pattern: ‘Android’ + ‘Chrome/[.0-9]* Mobile’
Tablet pattern: ‘Android’ + ‘Chrome/[.0-9]* (?!Mobile)’

更详细的说明请参考:

Chrome-User-Agent-Strings

Browser detection using the user agent

另外,下边这个页面可以显示当前浏览器的UA:

http://my-user-agent.com/

分类: js 标签: ,

Redis低版本无法向前兼容高版本RDB文件

2016年9月26日 没有评论

今天做了一个操作导致Redis无法启动。

在部署某一程序的过程中,先是单独安装了3.2.3版本的redis,安装完成后ps一下,redis已经启动。然后又使用安装包部署程序,安装包中包含一个2.8.13版本的redis,直接把之前装的3.2.3的redis给覆盖掉了。程序安装完成后发现redis进程没了,而且通过service redis_6379 restart无法启动。

怎么回事?查看/var/log/redis_6379.log发现如下错误:

[31934] 26 Sep 11:31:47.087 # Can’t handle RDB format version 7
[31934] 26 Sep 11:31:47.087 # Fatal error loading the DB: Invalid argument. Exiting.

哦,当前版本的redis无法处理version=7的RDB格式,这才明白是兼容性问题,但这种“向前兼容”一般很难做到的。

解决办法:删除rdb文件/var/lib/redis/6379/dump.rdb,重启redis就行了。

分类: Redis, 运维 标签: ,

将博客文章自动收录到搜索引擎

2016年7月13日 没有评论

文章被搜索引擎收录是增加网站流量的一个重要途径,如何才能提升收录量呢?

其实,百度和360等主流搜索引擎为站长们提供了“自动收录”功能,只需要增加一段代码,文章即可在浏览时被自动收录到搜索引擎。很方便。

  • 登录百度和360站长平台,添加要收录的网站。
  • 百度

站长需要在每个页面的HTML代码中包含以下自动推送JS代码:

<script>
(function(){
var bp = document.createElement(‘script’);
var curProtocol = window.location.protocol.split(‘:’)[0];
if (curProtocol === ‘https’){
bp.src = “https://zz.bdstatic.com/linksubmit/push.js';
}
else{
bp.src = ‘http://push.zhanzhang.baidu.com/push.js';
}
var s = document.getElementsByTagName(“script”)[0];
s.parentNode.insertBefore(bp, s);
})();
</script>

如果站长使用PHP语言开发的网站,可以按以下步骤操作:
1、创建名为“baidu_js_push.php”的文件,文件内容是上述自动推送JS代码;
2、在每个PHP模板页文件中的 <body> 标记后面添加一行代码:
<?php include_once(“baidu_js_push.php”) ?>

  • 360

请将如下js代码安装到要提交的页面</body>前:

<script>
(function(){
var src = (document.location.protocol == “http:”) ? “http://js.passport.qihucdn.com/11.0.1.js?255286f2da4022ae8c37b8798c879160″:”https://jspassport.ssl.qhimg.com/11.0.1.js?255286f2da4022ae8c37b8798c879160″;
document.write(‘<script src=”‘ + src + ‘” id=”sozz”><\/script>’);
})();
</script>

分类: 开发 标签:

一个简单的cnzz数据采集与监控方案

2016年6月8日 2 条评论
  1. 场景
    • 有多个网站需要监控
    • 每个网站的cnzz数据只能分别通过密码来查看
  2. 方案
    • 使用casperjs定时批量抓取每个网站的cnzz数据截图,对于监控来说,一般只抓取概要图和趋势图就行了
    • 将抓取的数据按日期保存在web服务器的html目录里,命名方式为cnzz/DATE/SiteID_overview.png和cnzz/DATE/SiteID_trends.png
    • 写个简单的php页面,通过SiteID枚举出当前日期下的各网站的概要图和趋势图
  3. 实现方法
分类: js, 监控 标签: , ,

使用casperjs进行网页截图

2016年6月7日 没有评论

casperjs有个很实用的功能就是网页截图,通过几个capture函数就能很方便的实现截图功能。

简单代码如下:

var casper = require(“casper”).create();
var x = require(‘casper’).selectXPath;  //用来简化XPath操作

casper.start(‘http://new.cnzz.com/v1/login.php?siteid=123454321′, function(){
this.fill(‘form[name=”form1″]’, {
‘password': 123456
}, true);
});

casper.then(function(){
//this.capture(‘cnzz.png’); //截取整个页面
this.captureSelector(‘cnzz.png’, x(‘//*[@id=”overview_top_order_table”]’)); //截取指定的selector
});

casper.run();

需要注意的是,如果网页内包含中文,服务器上需要安装中文字符集包。CentOS上通过以下命令来安装:

yum install bitmap-fonts bitmap-fonts-cjk

分类: js 标签: ,

casperjs批量执行多个url

2016年6月3日 没有评论

使用each api可以批量访问多个url。例子:

var casper = require(“casper”).create();

var links = [
“http://baidu.com/”,
“http://qq.com/”,
“http://bing.com/”
];

casper.start();

casper.each(links, function(self, link) {
this.thenOpen(link, function() {
this.echo(this.getTitle() + ” – ” + link);
});
});

casper.run();

分类: js 标签:

一大波常用小工具袭来

2016年6月2日 没有评论

今天发现一个比较实用的网站:tool.lu,集合了很多日常使用到的工具,比如:在线运行小段代码、正则表达式、favicon生成、字符串加解密、ip查询等。

这么多工具集合起来,很方便,站长很有创意。

收藏备用。

分类: 工具 标签: