2012-06-22 2 views
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 создали две последовательности А и В, а = {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'

EDIT

После коррекции:

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. Так или иначе итерация не выполняется.

EDIT 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" 

     } 

ответ

2

После редактирования ...

Вы должны вызвать MoveNext на 2 перед обращением тока. Вы не обновляете time02 при перемещении по 2 во внутреннем цикле. И вы не проверяете окончание последовательностей (например, если 2 заканчивается, но 1 идет, вы попытаетесь получить доступ к 2 после завершения).

(Является ли это домашнее задание?)

+0

спасибо. а не домашнее задание: я перерабатываю некоторые вещи, которые я закодировал на C, используя F #, чтобы быть знакомыми с функциональным программированием. – AruniRC

+0

Не могли бы вы рассказать о том, где указать MoveNext()? внутренний цикл имеет MoveNext() в строке «while» – AruniRC

+0

Я не знаю, как сказать это яснее. Вы обращаетесь к iter02.Current, прежде чем вы вызываете iter02.MoveNext(). Сначала вы должны вызвать MoveNext(). – Brian

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" не имеет смысла мне.

+0

был какой-то файл I/O участие, а также довольно большие куски данных, наряду с временными метками. хотел сохранить «1», «2» в качестве индикаторов, из которых следует считывать последовательность, чтобы перейти к заключительному (следующему) этапу слияния (не показан). – AruniRC

+0

'seq {}' ленив, и он строит вычисления, а не данные, поэтому вам не стоит беспокоиться. Может быть, вам следует описать ваш реальный прецедент. – pad

2

Вы написали код, как если бы

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

просто использовать

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

спасибо. немедленная проблема решена, но все еще появляется ошибка во время выполнения. вопрос был должным образом отредактирован. – AruniRC

Смежные вопросы