- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
在任何具体问题之前,请注意我的目标不是随机洗牌,而是像理想的发牌者对一组牌那样进行完美洗牌,即将一副牌分成两半,执行一次洗牌(将半副牌中的一张牌与另一半副牌中的一张牌交错)。 (这实际上是 Sedgewick 的 Algorithms in C 第三版中的一项练习:nbr 11.3 第 445 页)
所以,我对 Fisher-Yates shuffle 等算法不感兴趣。
也就是说,我的观点是在执行洗牌时避免使用任何辅助数组,我能够提供的代码如下:
template<typename T>
void two_way_shuffle(vector<T>& data,int l,int r)
{
int n=(r-l)+1;
int m=(r+l)/2;
if(n%2==0) ++m;
int s,p{l+1};
for(;p<=r;p+=2,m++)
{
s=data[m]; //Make space
//Shift the elements
for(int i{m};i>p;i--)
data[i]=data[i-1];
//Put the element in the final position
data[p]=s;
}
}
template<typename T>
void two_way_unshuffle(vector<T>& data,int l,int r)
{
int n=(r-l)+1;
if(n%2!=0){
--r;
--n;
}
int m=(r+l)/2;
int s,p{l+1},w{r-1};
for(;p<=w;p++,w--)
{
s=data[w];
for(int i{w};i>p;i--)
data[i]=data[i-1];
data[p]=s;
}
//Complete the operation
for(p=l+1,w=m;p<w;p++,w--)
swap(data[p],data[w]);
}
洗牌操作的基本思想是跟踪数组“p”中应该插入下一个元素的位置,然后从数组数据中的位置“w”复制该元素,留下一个空白空间,然后将数组从左向右移动,以便将空白空间准确移动到位置“p”,一旦完成,代码只需移动到 data[p] 之前保存的值“s”。很简单..它看起来工作正常(一些洗牌的例子)
FROM: 12345678
TO: 15263748
FROM: IS THIS WORKING CORRECTLY OR NOT?
TO: ICSO RTRHEICST LWYO ROKRI NNGO T?
FROM: SHUFFLING TEST
TO: SNHGU FTFELSIT
我的问题是在 unshuffle 操作中,我相信可以避免最后一个 for 循环中的交换序列,但我无法找到切肉刀的方法来做到这一点。问题在于主循环 unshuffle 执行移位操作,最终以错误的顺序留下数组前半部分的元素(因此,需要在第二个 for 中进行交换)。
我几乎可以肯定必须有一种聪明的方法来完成这项工作而不会出现这样的代码复杂性..
对于 unshuffle 算法可以改进的地方,您有什么建议吗?或者对我所做的任何其他建议?
谢谢
最佳答案
我认为您的代码保留了太多变量。当你打乱数组时,你正在处理一个大小递减的范围 [lo, hi]
,你将最右边的条目 hi
与左边的元素 block 交换 [lo, hi)
。您可以仅根据这两个变量来表达算法:
0 1 2 3 4 5
------- swap [1, 3) and [3]
0 3 1 2 4 5
---- swap [3, 4) and [4]
0 3 1 4 2 5
- [5, 5) is empty: break
这对于奇数个元素是一样的,只是空范围超出了界限,这没关系,因为我们不访问它。这里的操作是:右移 block ,将旧的hi
元素放在lo
位置,增加lo
和hi
步幅 2 和 1。
当你取消洗牌时,你必须恢复这些步骤:在最后一个元素开始 lo
和 hi
对于偶数大小的数组和超出数组的一个元素对于奇数大小的数组.然后以相反的顺序执行所有步骤:首先减少 lo
和 hi
,然后将 block 向左移动并将旧的 lo
放在 hi
位置。当 lo
达到 1 时停止。(它将达到 1,因为我们从一个奇数索引开始并且我们递减 2。)
您可以通过打印 lo
和 hi
来测试您的算法:它们对于洗牌和取消洗牌必须相同,只是顺序相反。
所以:
template<typename T>
void weave(std::vector<T>& data)
{
size_t lo = 1;
size_t hi = (data.size() + 1) / 2;
while (lo < hi) {
T m = data[hi];
for (size_t i = hi; i-- > lo; ) data[i + 1] = data[i];
data[lo] = m;
lo += 2;
hi++;
}
}
template<typename T>
void unweave(std::vector<T>& data)
{
size_t n = data.size();
size_t lo = n + n % 2 - 1;
size_t hi = lo;
while (hi--, lo-- && lo--) {
T m = data[lo];
for (size_t i = lo; i < hi; i++) data[i] = data[i + 1];
data[hi] = m;
}
}
我删除了左右索引,这降低了代码的灵 active ,但希望更清晰易读。您可以将它们放回去,只需要它们来计算 lo
和 hi
的初始值。
关于c++ - 完美的shuffle和unshuffle,没有辅助数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30396616/
我正在尝试复制以下 while 循环,但它们交错我的“卡片”的方式有所不同。 这是我当前有效的 while 循环,我的目标是重新创建此循环,但颠倒两个 card_force 数组的顺序: while
我有以下 Spark 作业,试图将所有内容保留在内存中: val myOutRDD = myInRDD.flatMap { fp => val tuple2List: ListBuffer[(St
我最近开始学习 tensorflow。 我不确定是否有区别 x = np.array([[1],[2],[3],[4],[5]]) dataset = tf.data.Dataset.from_ten
我想重置 pyspark 代码中的 spark.sql.shuffle.partitions 配置,因为我需要加入两个大表。但是以下代码在最新的spark版本中不起作用,错误说“xxx中没有方法“se
我只是想验证我对这些参数及其关系的理解,如果我错了请通知我。 mapreduce.reduce.shuffle.input.buffer.percent 告诉分配给 reducer 的整个洗牌阶段的内
假设我的数据库中有 10 个项目正在尝试洗牌,我如何更改当前的代码,以便每次从数据库中提取一个名称时,一次显示一个名称,而不是全部显示一次? $con = mysqli_connect("XXX",
1.概述 转载:Flink Remote Shuffle 开源:面向流批一体与云原生的 Shuffle 服务 2.开源 作为支持 Flink 流批一体与云原生的重要组成部分,Flink Remote
这个 fiddle 演示了我的问题:https://jsfiddle.net/petebere/fhg84je2/ 我想确保每次用户单击按钮时都会显示数组中的随机元素。问题是,有时进行新的混洗时,新混
对于那些了解情况的人来说,这应该是一个足够简单的问题 - 为什么我会在控制台中收到此错误?我尝试按照 Shuffle homepage 上“用法”下显示的代码进行操作但我认为该页面忽略了包含开始使用该
在下面的 Spark admin 在端口 8080 上运行的屏幕截图中: 此代码的“随机读取”和“随机写入”参数始终为空: import org.apache.spark.SparkContext;
docs说“所有排列的发生概率大致相等。”但我不知道这是否包括返回相同订单的可能性(无论多么小)。我有一个方法(见下文),在两次测试运行期间,列表以原始顺序返回,也许……其他因素可能有问题,比如可能已
我有一份处理大量数据的工作。此作业经常运行而没有任何错误,但偶尔会引发此错误。我正在使用 Kyro Serializer。 我正在使用 yarn 集群运行 Spark 1.2.0。 完整的堆栈跟踪在这
我正在 EC2 集群上部署 Spark 数据处理作业,该作业对于集群来说很小(16 个核心,总共 120G RAM),最大的 RDD 只有 76k+ 行。但是中间严重倾斜(因此需要重新分区)并且每
打乱数据的 spark sql 聚合操作,即 spark.sql.shuffle.partitions 200(默认情况下)。当 shuffle partition 大于 200 时,性能会发生什么变
打乱数据的 spark sql 聚合操作,即 spark.sql.shuffle.partitions 200(默认情况下)。当 shuffle partition 大于 200 时,性能会发生什么变
当在 Python 3 中使用 random 模块 random.shuffle(list(range(n))) 时,但是 random.shuffle(range( n)) 没有。 为什么会这样?
当我尝试在 pycaret 中训练某些东西时,我收到此错误消息 ValueError: Setting a random_state has no effect since shuffle is Fa
我正在以推测模式运行 Spark 作业。我有大约 500 个任务和大约 500 个 1 GB gz 压缩文件。我不断地进入每项作业,对于 1-2 个任务,附加错误,然后它会重新运行数十次(阻止作业完成
作为Django中关键字云函数的一部分,我正在尝试输出字符串列表。是否有模板过滤器,可让您随机播放列表中的项目?我认为这很简单,但是我在官方文档中找不到任何适用的过滤器。 最佳答案 制作自己的东西很简
同时思考this问题并与参与者交谈后,出现了这样的想法:对一组有限的明显有偏见的随机数进行洗牌,使它们变得随机,因为你不知道它们被选择的顺序。这是真的吗?如果是的话,有人可以指出一些资源吗? 编辑:我
我是一名优秀的程序员,十分优秀!