Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm Haskell中的CycleSort-麻烦_Algorithm_Sorting_Haskell_Cycle Sort - Fatal编程技术网

Algorithm Haskell中的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

我正在尝试用Haskell做一个循环,这是我的任务,但没有人让我清楚如何使用Haskell,我尝试了很多次,试图“翻译”其他语言的代码,但都没有成功。我到处都找过,但什么也没有。如果有人帮我做这件事,我会非常非常感激的。 Java中有CycleSort的代码

// 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