一种较优的洗牌算法
来源:互联网 发布:mathlab软件下载 编辑:程序博客网 时间:2024/05/11 12:55
本人已经多次接触到关于洗牌算法的讨论,在之前面试时也有人曾问我过,据我所看,大多的实现都不太理想,今晚来了兴致也就捣鼓了一下,放上来以供大家交流交流,从代码中可以看出来,本屌丝的洗牌算法还是挺优的,并且做到了52张牌,张张都是随机抽取到的,如果还有什么不足之处还请大神指点指点
main.cpp
#include "Cards.h"#include <iostream>#include <time.h>int main(int argc, const char * argv[]){ // 以系统时间为随机种子 srand((unsigned)time(0)); Cards cards; cards.init(); cards.shuffle(); for (int i=0; i<5; ++i) { Cards::Card* card = cards.getCardByIndex(i); printf("%3d", card->_index); } return 0;}
Cards.h
#ifndef __Shuffle__Cards__#define __Shuffle__Cards__#include <iostream>class Cards{public: // 单张纸牌,这里是为了面向对象,里面的成员你也根据自己的需求来修改 struct Card { public: Card(){cleanUp();} virtual ~Card(){} // 索引号 char _index; void cleanUp() { _index = 0; } }; Cards(); virtual ~Cards(); // 初始化 void init(); // 洗牌 void shuffle(); // 取牌 Card* getCardByIndex(int index); // 展示纸牌的索引 void showIndexes();private: // 牌的总数量 int _count; // 纸牌的索引,因为纸牌最多为52张,所以这里用char就足够了 char* _card_indexes; // 所有纸牌 Card* _cards;};#endif /* defined(__Shuffle__Cards__) */
Cards.cpp
#include "Cards.h"Cards::Cards(){ // 纸牌总数为52张 _count = 52; // 申请内存加初始化 _card_indexes = new char[_count]; memset(_card_indexes, 0, sizeof(char) * _count); _cards = new Card[_count]; /* _cards不在这初始化是因为每个元素已经在Card的构造函数里初始化了, * 这里不能用malloc来申请内存,如果用malloc那就得进行强转,就不会走Card的构造函数和析构函数 */}Cards::~Cards(){ // 释放内存 delete []_card_indexes; delete []_cards;}void Cards::init(){ for (int i=0; i<_count; ++i) { // 将纸牌的索引号放入_card_indexes数组 _card_indexes[i] = i; // 填上每张纸牌的索引号, _cards[i]._index = i; }}void Cards::shuffle(){ // rand_max为随机上限,初始值为纸牌总数量 int rand_max = _count; // 随机抽取,直到次数为纸牌的总数量为止 for (int i=0; i<_count; ++i) { // 取到随机数,该随机数为_card_indexes的索引 int index_of_indexes = rand() % rand_max; // 如果抽到的索引号不为随机上限,则进行移动 if (index_of_indexes != rand_max - 1) { // 取出即将被覆盖的内存的数据 char card_index = _card_indexes[index_of_indexes]; // 拷贝目标 char* dest = _card_indexes + index_of_indexes; // 拷贝源 char* src = dest + 1; // 拷贝的元素个数 int n = _count - index_of_indexes - i - 1; // 拷贝 memcpy(dest, src, sizeof(char) * n); // 将之前取出的数据放入移动了的数据之后 _card_indexes[rand_max - 1] = card_index; } // 打印出每抽取一次的结果 printf("%d--->%d\n", i, index_of_indexes); showIndexes(); // 每抽完一次,随机上限就少一次, --rand_max; }}Cards::Card* Cards::getCardByIndex(int index){ // 先取到纸牌的索引 int card_index = _card_indexes[index]; // 再去取纸牌 return _cards + card_index;}void Cards::showIndexes(){ for (int i=0; i<_count; ++i) { int card_index = _card_indexes[i]; printf("%2d,", card_index); // 每打印13个元素换行 if (!((i + 1) % 13)) { printf("\n"); } }}
0 0
- 一种较优的洗牌算法
- 洗牌随机算法的一种Java实现
- 洗牌的一个算法
- 洗牌算法的学问
- 洗牌算法的研究
- 错误的洗牌算法
- 简易的洗牌算法
- A Simple In-Place Algorithm for In-Shuffle 一种简单的原地洗牌算法
- 一种较实用的用户架构
- List排序(较实用的一种)
- C#实现的洗牌算法
- 一个很小的洗牌算法
- 不用随机数的洗牌算法
- 证明洗牌算法的随机性
- 洗牌算法汇总以及测试洗牌程序的正确性
- 洗牌算法
- 洗牌算法
- 洗牌算法
- mac os x10.9 安装jdk ,配置环境变量,解决eclipse打不开问题
- tinypy源码笔记(一)——简单介绍
- Qt串口通讯
- 神仙道人物属性基础知识普及
- 各种排序算法的实现-5(表插入排序-2)
- 一种较优的洗牌算法
- python 多线程处理抓取网页
- 黑马程序员_HTML基础
- 找工作之面试血泪史
- 在WIN7下如何成功配置AppServ
- 调试器工作原理——基础篇
- Metro界面的真正意义
- vim7.4官方源码在vs2013的编译方法及问题总结
- 关于vs2012/2013的C编译器生成的exe的向后兼容xp的问题