Algorithm Haskell中的CycleSort-麻烦
我正在尝试用Haskell做一个循环,这是我的任务,但没有人让我清楚如何使用Haskell,我尝试了很多次,试图“翻译”其他语言的代码,但都没有成功。我到处都找过,但什么也没有。如果有人帮我做这件事,我会非常非常感激的。 Java中有CycleSort的代码Algorithm Haskell中的CycleSort-麻烦,algorithm,sorting,haskell,cycle-sort,Algorithm,Sorting,Haskell,Cycle Sort,我正在尝试用Haskell做一个循环,这是我的任务,但没有人让我清楚如何使用Haskell,我尝试了很多次,试图“翻译”其他语言的代码,但都没有成功。我到处都找过,但什么也没有。如果有人帮我做这件事,我会非常非常感激的。 Java中有CycleSort的代码 // Function sort the array using Cycle sort public static void cycleSort(int arr[], int n) { // count number of memo
// Function sort the array using Cycle sort
public static void cycleSort(int arr[], int n)
{
// count number of memory writes
int writes = 0;
// traverse array elements and put it to on
// the right place
for (int cycle_start = 0; cycle_start <= n - 2; cycle_start++) {
// initialize item as starting point
int item = arr[cycle_start];
// Find position where we put the item. We basically
// count all smaller elements on right side of item.
int pos = cycle_start;
for (int i = cycle_start + 1; i < n; i++)
if (arr[i] < item)
pos++;
// If item is already in correct position
if (pos == cycle_start)
continue;
// ignore all duplicate elements
while (item == arr[pos])
pos += 1;
// put the item to it's right position
if (pos != cycle_start) {
int temp = item;
item = arr[pos];
arr[pos] = temp;
writes++;
}
// Rotate rest of the cycle
while (pos != cycle_start) {
pos = cycle_start;
// Find position where we put the element
for (int i = cycle_start + 1; i < n; i++)
if (arr[i] < item)
pos += 1;
// ignore all duplicate elements
while (item == arr[pos])
pos += 1;
// put the item to it's right position
if (item != arr[pos]) {
int temp = item;
item = arr[pos];
arr[pos] = temp;
writes++;
}
}
}
}
//函数使用循环排序对数组进行排序
公共静态无效循环端口(int arr[],int n)
{
//计算内存写入的次数
int=0;
//遍历数组元素并将其启用
//对的地方
对于(int cycle_start=0;cycle_start而不是尝试翻译,让我们转到:
算法
给定一个元素a,我们可以找到它将出现在中的索引
通过简单地计算整个列表中的元素数,可以得到已排序的列表
现在比a小
如果元件已处于正确位置,则不执行任何操作
如果不是,我们将把它写到它的预期位置。该位置是
由一个不同的元素b居住,然后我们必须移动到它的
正确位置。将元件替换到正确位置的过程
位置将继续,直到图元移动到图元的原始位置
a、 这就完成了一个循环
对每个元素重复此过程会对列表进行排序,只需一次写入
当且仅当图元未处于其正确位置时进行操作。
而计算正确的位置则需要O(n)个时间
元素,从而产生一个二次时间算法,写入数
操作被最小化
实施
要根据上述大纲创建工作实现,
需要解决两个问题:
在计算正确的位置时,我们必须确保
重复计算循环的第一个元素
如果存在重复的元素,我们可以尝试将元素移动到a
到了它的正确位置,正好有一个a。
简单地交换这些将导致算法无限循环。
相反,我们必须在元素的任何副本之后插入该元素
在haskell中实现cycleSort
,我们的第一个问题应该是
循环启动的类型是什么
正常的
具有类型sort::Ord a=>[a]->[a]
,但这不适用于cycleSort
。
循环排序是一种就地算法,因此对列表进行排序毫无意义,
我们将要排序一个
但是,这种类型并不完全正确。MVector
s上的操作不是纯粹的-它们是
在某些monad中返回操作,通常是sts
或IO
。因此这种类型需要
小小的调整
我们将返回一个操作,对向量进行排序,而不是返回一个排序向量
执行时的可变向量:
cycleSort :: (PrimMonad m, Ord a) => MVector (PrimState m) a -> m ()
(PrimMonad m
仅仅意味着m
可以构造变异向量的动作,
PrimState m
用于将MVector
绑定到此特定monad)
为了与其他实现进行比较,我们可能需要计算
写道:
现在我们可以研究算法本身了
由于这是一项任务,我不会为您提供解决方案,但以下是
一些有用的功能:
Data.Vector.Mutable.length::MVector s a->Int
获取可变向量的长度
Data.Vector.Mutable.read::PrimMonad m=>MVector(PrimState m)a->Int->ma
读取可变向量索引处的值
Data.Vector.Mutable.write::PrimMonad m=>MVector(PrimState m)a->Int->a->m()
在可变向量的索引处写入值
以下是一个反转MVector的函数的使用示例:
import Control.Monad (when)
import Control.Monad.Primitive (PrimMonad, PrimState)
import qualified Data.Vector.Mutable as MV
reverseMVector :: PrimMonad m => MV.MVector (PrimState m) a -> m ()
reverseMVector v = loop 0 (MV.length v - 1) where
loop lo hi = when (lo < hi) $ do
a <- MV.read v lo
b <- MV.read v hi
MV.write v lo b
MV.write v hi a
loop (lo+1) (hi-1)
作为
--忽略所有重复的元素
让skipDupes pos=do
jtem我恐怕这有点离题了。例如,您可以询问有关cyclesorts的特定部分的问题,以及您尝试实现这些子部分失败的原因。这可能更适合于。@AJFarmar,这甚至不接近于代码审查的主题。
cycleSort :: (PrimMonad m, Ord a) => MVector (PrimState m) a -> m Int
import Control.Monad (when)
import Control.Monad.Primitive (PrimMonad, PrimState)
import qualified Data.Vector.Mutable as MV
reverseMVector :: PrimMonad m => MV.MVector (PrimState m) a -> m ()
reverseMVector v = loop 0 (MV.length v - 1) where
loop lo hi = when (lo < hi) $ do
a <- MV.read v lo
b <- MV.read v hi
MV.write v lo b
MV.write v hi a
loop (lo+1) (hi-1)
// ignore all duplicate elements
while (item == arr[pos])
pos += 1;
-- ignore all duplicate elements
let skipDupes pos = do
jtem <- MV.read v pos
if item == jtem
then skipDupes (pos + 1)
else return pos
pos <- skipDupes pos