引个言
NS3系列许久没有更新,一方面是回到家后各种琐事忙忙碌碌,另一方面也是最主要的就是,好吧我懒。(欧耶)
一边好好过年,一边好好规划,后续科研方面可能会分享NS3-Gym的相关应用,应该,应该哈~
回归主题,其实春晚是没怎么好好看的,小尼的“对不上”算是认真观看的一大因素。正好最近在跟着大佬的课重温数据结构,一边看课一边搓搓leetcode的简单题目,也算轻松自在。恰好博主更新了顺序表的相关课程,于是就跟着复盘一下,分享一波~(归根结底不是我想出来的哈)
附上博主主页英雄哪里出来-CSDN博客
见证奇迹
首先定义数组a,里面放着手里的四张牌,定义一个计数器cnt,while结构中是一个迭代100次的“洗牌逻辑”,通过随机数取余得到0-3的x和y,通过中间变量tmp完成索引为x和y的元素交换,相当于洗牌啦。
int a[4] = { 2,7,6,5 };
int cnt = 0;
while (cnt++ < 100)
{
int x = rand() % 4;
int y = rand() % 4;
int tmp = a[x];
a[x] = a[y];
a[y] = tmp;
}
定义数组b,通过循环把a拷贝到b,也就是把手里的牌撕开。
int b[4];
for (int i = 0; i < 4; ++i)
{
b[i] = a[i];
}
定义一个数组c,这里定义的容量比较大,也是为了后续插牌操作有足够的空间。
l和r分别表示开头和结尾,通过两次for循环把数组a和b,放入c中。
int c[1000];
int l = 0, r = 0;
for (int i = 0; i < 4; ++i)
{
c[r++] = a[i];
}
for (int i = 0; i < 4; ++i)
{
c[r++] = b[i];
}
连续两次把第一个元素放在最后
c[r++] = c[l++];
c[r++] = c[l++];
首先把c中最后三个元素往后移3个位置,我朝佩服博主的代码这样简练,上述过程中使用r和l后都+1,保证指针始终指向首尾。随后将c中前3个元素插入到空出来的位置,随后l与r都加3,保持首尾指向。
c[r] = c[r - 3];
c[r + 1] = c[r - 2];
c[r + 2] = c[r - 1];
c[r - 3] = c[l];
c[r - 2] = c[l + 1];
c[r - 1] = c[l + 2];
l += 3;
r += 3;
把数组第一个元素放在屁股底下(说实话博主这变量名一绝),“南方人”取第一张牌随便找个位置插入(这里默认是插入到倒数第二个位置,其实没有关系,后面通过调试我们可以发现中间元素的顺序没有关系),最后把尾指针r+1。我记着节目中还有基于名字、性别的插入操作,但基本逻辑一致。博主通过头指针后移来等价丢牌操作,此处++l代表男人拿起一张牌丢掉。
int pigudixia = c[l++];
int x = c[l++];
c[r] = c[r - 1];
c[r - 1] = x;
++r;
++l;
丢牌之后把第一张牌放在最后,反复数次,随后就开始念咒语:“好运留下来,烦恼丢出去~"
cnt = 0;
while (cnt++ < 7)
{
c[r++] = c[l++];
}
cnt = 0;
while (cnt++ < 5)
{
c[r++] = c[l++];
//好运留下来
print(c,l,r);
l++;
//烦恼丢出去
print(c,l,r);
}
让我们看看最后的结果: 2 2
cout << pigudixia << ' ' << c[l] << endl;
怎么个回事
作者编写了一个输出函数用于观察数组的变化过程,这里发现基于头尾指针的思想真的很方便
void print(int c[],int l,int r)
{
for(int i = l; i < r; i ++)
{
cout << c[i] << ' ' ;
}
cout << endl;
}
这里附上完整代码,其中加入了输出函数,用于观察整个过程:
#include<iostream>
using namespace std;
void print(int c[],int l,int r)
{
for(int i = l; i < r; i ++)
{
cout << c[i] << ' ' ;
}
cout << endl;
}
int
main()
{
int a[4] = { 2,7,6,5 };
int cnt = 0;
while (cnt++ < 100)
{
int x = rand() % 4;
int y = rand() % 4;
int tmp = a[x];
a[x] = a[y];
a[y] = tmp;
}
// 迭代一百次,实现打乱效果
int b[4];
for (int i = 0; i < 4; ++i)
{
b[i] = a[i];
}
//把a的元素拷贝给b
int c[1000];
int l = 0, r = 0;
//滚动数组c,l、r分别代表数组的边界,左闭右开
for (int i = 0; i < 4; ++i)
{
c[r++] = a[i];
}
//把a数组插入到c数组的尾部
for (int i = 0; i < 4; ++i)
{
c[r++] = b[i];
}
//把b数组插入到c数组的尾部
c[r++] = c[l++];
c[r++] = c[l++];
//连续两次把第一个数据插入在最后
print(c,l,r);
//打印一次
c[r] = c[r - 3];
c[r + 1] = c[r - 2];
c[r + 2] = c[r - 1];
//将数组最后三个元素后移3个位置
c[r - 3] = c[l];
c[r - 2] = c[l + 1];
c[r - 1] = c[l + 2];
//将数组头三个元素插入到空出来的位置
l += 3;
r += 3;
//l、r各右移三个位置
print(c,l,r);
int pigudixia = c[l++];
//把数组头元素存储在屁股底下
int x = c[l++];
c[r] = c[r - 1];
c[r - 1] = x;
++r;
//南方人取数组头元素随便找个位置插入
++l;
//男人拿起一张扔掉
print(c,l,r);
cnt = 0;
//计数器准备
while (cnt++ < 7)
{
c[r++] = c[l++];
}
//每次循环把第一个元素放在最后
print(c,l,r);
cnt = 0;
while (cnt++ < 5)
{
c[r++] = c[l++];
//好运留下来
print(c,l,r);
l++;
//烦恼丢出去
print(c,l,r);
}
cout << pigudixia << ' ' << c[l] << endl;
return 0;
}
运行结果如下:
6 7 5 2 6 7 5 2 //初始
2 6 6 7 5 7 5 2
7 5 7 5 6 2
5 7 5 6 2 7
7 5 6 2 7 5
5 6 2 7 5
6 2 7 5 5
2 7 5 5
7 5 5 2
5 5 2
5 2 5
2 5
5 2
2 // 底牌
2 2 // 屁股底下和底牌成功对上
龙年大吉
在这里只是简单地搬运了博主的代码,加了些自己的注释,供我们学习参考,最近在跟博主的C++数据结构课程,真心感觉不错,让我惊喜的是博主课程还能以这样的方式进行更新,博主真的很用心(单纯平心而论,并无任何意图)。
最后祝我们龙年大吉,每天都是大晴天~