合并两个时间戳序列以产生字符串时出错

时间:2012-06-22 10:48:39

标签: f# functional-programming f#-interactive

代码根据它们的timestamp值对两个输入序列(seq01和seq02)进行排序,并返回一个序列,该序列表示要按顺序读取哪个序列。

对于seq02的时间戳值小于seq01的时间戳值的情况,我们对返回的序列产生“2”,否则为“1”。这些表示在那时是采用seq01还是采用seq02使数据按顺序排列(按时间戳值)。

let mergeSeq (seq01:seq<_>)  (seq02:seq<_>) = 
    seq { 
            use iter01 = seq01.GetEnumerator()
            use iter02 = seq02.GetEnumerator() 
            while iter01.MoveNext() do
                let _,_,time01 = iter01.Current
                let _,_,time02 = iter02.Current 
                while time02 < time01 && iter02.MoveNext()  do 
                    yield "2"
                yield "1"
    }

为了在FSI中测试它,创建了两个序列a和b,a = {1; 3; 5; ...}和b = {0; 2; 4; ...}。因此let c = mergeSeq a b的预期值应为{“2”,“1”,“2”,“1”......}。但是我收到此错误:error FS0001: The type ''a * 'b * 'c' does not match the type 'int'

修改

纠正后:

let mergeSeq (seq01:seq<_>)  (seq02:seq<_>) = 
    seq { 
            use iter01 = seq01.GetEnumerator()
            use iter02 = seq02.GetEnumerator() 
            while iter01.MoveNext() do
                let time01 = iter01.Current
                let time02 = iter02.Current 
                while time02 < time01 && iter02.MoveNext()  do 
                    yield "2"
                yield "1"
    }

运行此操作后,还有另一个错误:call MoveNext。不知怎的,迭代没有被执行。

编辑2

let mergeRef (seq01:seq<_>) (seq02:seq<_>) = 
    seq{
            use iter01 = seq01.GetEnumerator()
            use iter02 = seq02.GetEnumerator()
            iter01.MoveNext() 
            iter02.MoveNext() 

            let temp01 = ref iter01.Current  //!!using mutable reference
            let temp02 = ref iter02.Current

            while iter01.MoveNext() do
                while (iter02.MoveNext()) && ((!temp02) < (!temp01)) do
                    temp02 := iter02.Current
                    yield "2"
                yield "1" 
                temp01 := iter01.Current

            //if seq01 finishes before seq02
            while iter02.MoveNext() do
                yield "2"

       }

3 个答案:

答案 0 :(得分:3)

您需要更改

let _,_,time01 = iter01.Current
let _,_,time02 = iter02.Current

let time01 = iter01.Current
let time02 = iter02.Current

以便使用seq<int>对代码进行类型检查。

我不明白你的意图。如果要比较两个序列中的每个对应元素对,可以使用更多功能解决方案:

let mergeSeq seq01 seq02 = 
    Seq.map2 (fun s1 s2 -> if s2 < s1 then "2" else "1") seq01 seq02

如果要合并两个已排序的序列,使用GetEnumerator很好,但返回"2""1"对我没有意义。

答案 1 :(得分:2)

您已编写代码,就好像

一样
a={1,1,1;2,2,2;3,3,3...}

只需使用

            let time01 = iter01.Current
            let time02 = iter02.Current 

答案 2 :(得分:2)

编辑后......

在访问当前之前,您需要在2上调用MoveNext。当您在内循环中移动2时,您不会更新time02。并且你没有正确检查序列的结尾(例如,如果2结束但是1正在进行,你将尝试在结束后访问2)。

(这是家庭作业吗?)