开发者社区> 贺利坚> 正文

C++实践参考:洗牌(范型程序设计)

简介: 【项目2:洗牌】   在扑克牌游戏中,每次游戏开始都要求把54张牌重新排列一下,称为洗牌。试编写程序将一副扑克牌(用54个整数1~54表示)随机洗好后,顺序输出54张牌的情况。   参考界面: 参考解答(共4种,可作为程序阅读,品味用STL解决问题的方法,必要时,请查找相关手册)   解法1:初始化一个 vector,顺序加入所有牌,即整数1~54。然后从容器中随机
+关注继续查看

【项目2:洗牌】
  在扑克牌游戏中,每次游戏开始都要求把54张牌重新排列一下,称为洗牌。试编写程序将一副扑克牌(用54个整数1~54表示)随机洗好后,顺序输出54张牌的情况。
  参考界面:
这里写图片描述

参考解答(共4种,可作为程序阅读,品味用STL解决问题的方法,必要时,请查找相关手册)
  解法1:初始化一个 vector,顺序加入所有牌,即整数1~54。然后从容器中随机抽取一个加到另一个vector中,这个过程一共执行54次。

#include <ctime>
#include <vector>
#include <list>
#include <iostream>
#include <iterator>
#include <cstdlib>
using namespace std;

using namespace std;
typedef vector<int> IntVector;
typedef unsigned int VIndex;
void vectorShuffle(IntVector &unshuffled,IntVector &shuffled)
{
    VIndex p,size=unshuffled.size();
    while(size)
    {
        p=rand()%size--;
        shuffled.push_back(unshuffled[p]);
        unshuffled.erase(unshuffled.begin()+p);
    }
}

int main()
{
    ostream_iterator<int> os(cout," ");
    srand(time(NULL));
    IntVector c,sc;
    for(VIndex i=1; i<=54; i++)
    {
        c.push_back(i);
    }
    cout<<"Before Shuffle"<<endl;
    copy(c.begin(),c.end(),os);
    cout<<endl;
    vectorShuffle(c,sc);
    cout<<"\nAfter Shuffled"<<endl;
    copy(sc.begin(),sc.end(),os);
    cout<<endl<<endl;
    return 0;
}

  解法2:相同思路,用list

#include <ctime>
#include <vector>
#include <list>
#include <iostream>
#include <iterator>
#include <cstdlib>
using namespace std;

typedef list<int> IntList;
typedef unsigned int VIndex;

void listShuffle(IntList &unshuffled,IntList &shuffled)
{
    VIndex  p, size=unshuffled.size();
    IntList::iterator iter;
    while(size)
    {
        p=rand()%size--;
        iter=unshuffled.begin();
        while(p!=0)
        {
            iter++;
            p--;
        }
        shuffled.push_back(*iter);
        unshuffled.erase(iter);
    }
}
int main()
{
    ostream_iterator<int> os(cout," ");
    srand(time(NULL));
    IntList cl,scl;
    for(VIndex i=1; i<=54; i++)
    {
        cl.push_back(i);
    }
    cout<<"Before Shuffle"<<endl;
    copy(cl.begin(),cl.end(),os);
    cout<<endl;
    listShuffle(cl,scl);
    cout<<"\nAfter Shuffled"<<endl;
    copy(scl.begin(),scl.end(),os);
    cout<<endl<<endl;
    return 0;
}

  解法3:随机交换两个位置的元素来洗牌。函数中time是要执行交换的次数,如果是54张牌的话,交换次数大于27的话就已经表现出很随机的排列了。

#include <ctime>
#include <vector>
#include <iterator>
#include <algorithm>
#include <iostream>
using namespace std;
typedef vector<int> IntVector;
void SwapShuffle(IntVector &datas, int time)
{
    unsigned size=datas.size(),p1,p2;
    while(time--)
    {
        p1=rand()%size;
        p2=rand()%size;
        swap(datas[p1],datas[p2]);
    }
}
int main()
{
    ostream_iterator <int>  os(cout," ");
    srand(time(NULL));
    vector <int> poker;
    for(int i=1; i<=54; i++)
    {
        poker.push_back(i);
    }
    cout<<"Before Shuffle"<<endl;
    copy(poker.begin(),poker.end(),os);
    cout<<endl;
    SwapShuffle(poker,100);
    cout<<"\nAfter Shuffled"<<endl;
    copy(poker.begin(),poker.end(),os);
    cout<<endl<<endl;
    return 0;
}

  解法4:采用STL的 random_shuffle 算法

#include <ctime>
#include <vector>
#include <iterator>
#include <algorithm>
#include <iostream>
using namespace std;
int main()
{
    ostream_iterator <int>  os(cout," ");
    srand(time(NULL));  // 洗牌前要先初始化随机数种子
    vector <int> poker;
    for(int i=1; i<=54; i++)
    {
        poker.push_back(i);
    }
    cout<<"Before Shuffle"<<endl;
    copy(poker.begin(),poker.end(),os);
    cout<<endl;
    random_shuffle(poker.begin(),poker.end());
    cout<<"\nAfter Shuffled"<<endl;
    copy(poker.begin(),poker.end(),os);
    cout<<endl<<endl;
    return 0;
}

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
C++ 中的内存对齐——实践篇
> 本文为《C++ 中的内存对齐》系列之下篇,[上篇](https://ata.alibaba-inc.com/articles/243681)介绍内存对齐的理论基础,建议优先食用~ ### TL;DR - 编译器可能会在结构体中填充字节,以满足所有成员的对齐要求; - 可以通过预处理指令 `#pragma pack` 及 `alignas` 标识符自定义内存对齐; - 对于栈上及静态变量,编
519 0
客户端单元测试实践——C++篇
我们团队在手淘中主要负责BehaviX模块,代码主要是一些逻辑功能,很少涉及到UI,为了减少双端不一致问题、提高性能,我们采用了将核心代码C++化的策略。由于团队项目偏底层,测试同学难以完全覆盖,回归成本较高,部分功能依赖研发同学自测,为了提高系统的稳定性,我们在团队中实行了单元测试,同时由于集团客户端C++单元测试相关经验沉淀较少,所以在此分享下团队在做单元测试中遇到的问题与解决思路,希望能对大家所有帮助。
712 0
Linux下跨语言调用C++实践
Linux下跨语言调用C++实践
135 0
Qt Creator plugin动手实践(4)C++ 类ModeManager源码分析
Qt Creator plugin动手实践(4)C++ 类ModeManager源码分析
159 0
Qt Creator plugin动手实践(3)C++ 类ModeManager源码分析
Qt Creator plugin动手实践(3)C++ 类ModeManager源码分析
169 0
记一次完整 C++ 项目编译成 WebAssembly 的实践
有 2W+ 行代码,一篇通用的技术方案
5372 0
Linux C++ 应用二进制兼容实践
本文将介绍一些在开发多 Linux 平台 C++ 应用时可能遇到的兼容性问题和相关的解法。虽然是以 C++ 为讲述对象,但兼容性这个问题,在没有 VM 帮你做这些脏活累活的情况下,是所有 C-like 语言(比如 Go、Rust 等)都可能遇到的。
2154 0
带你读《C++代码整洁之道:C++17 可持续软件开发模式实践》之三:原则
如果想用C++语言编写出易维护的、扩展性良好的以及生命力强的软件,那么,对于所有的软件开发人员、软件设计人员、对现代C++代码感兴趣或想降低开发成本的项目领导者来说,本书都是必需品。如果你想自学编写整洁的C++代码,那么本书也是你需要的。本书旨在通过一些示例帮助各个技术层次的开发人员编写出易懂的、灵活的、可维护的和高效的C++代码。即使你是一名资深的开发工程师,在本书中也可以找到有价值的知识点。
1700 0
带你读《C++代码整洁之道:C++17 可持续软件开发模式实践》之二:构建安全体系
如果想用C++语言编写出易维护的、扩展性良好的以及生命力强的软件,那么,对于所有的软件开发人员、软件设计人员、对现代C++代码感兴趣或想降低开发成本的项目领导者来说,本书都是必需品。如果你想自学编写整洁的C++代码,那么本书也是你需要的。本书旨在通过一些示例帮助各个技术层次的开发人员编写出易懂的、灵活的、可维护的和高效的C++代码。即使你是一名资深的开发工程师,在本书中也可以找到有价值的知识点。
1771 0
+关注
贺利坚
烟台大学计算机学院教师,建设系列学习资源,改革教学方法,为IT菜鸟建跑道,让大一的孩子会编程,为迷茫的大学生出主意,一起追求快乐的大学。 著书《逆袭大学:传给IT学子的正能量》,帮助处于迷茫中的大学
文章
问答
视频
文章排行榜
最热
最新
相关电子书
更多
GPON Class C++ SFP OLT Transce
立即下载
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载