0

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

对于 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"

       }
4

3 回答 3

3

You need to change

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

to

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

so that the code is type-checked with seq<int>.

I don't understand your intention. If you want to compare each corresponding pair of elements in two sequences, there are more functional solutions:

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

If you want to merge two sorted sequences, using GetEnumerator is fine but returning "2" and "1" doesn't make sense to me.

于 2012-06-22T10:54:01.520 回答
2

你写的代码好像

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

只需使用

            let time01 = iter01.Current
            let time02 = iter02.Current 
于 2012-06-22T10:54:47.557 回答
2

修改后...

您需要在 2 上调用 MoveNext,然后才能访问 current。当您在内部循环中移动 2 时,您不会更新 time02 。而且您没有正确检查序列的结尾(例如,如果 2 结束但 1 正在运行,您将尝试在结束后访问 2)。

(这是作业吗?)

于 2012-06-22T16:26:17.060 回答