2016-02-27 11 views
1

Мне нужно реализовать объединение соединений, разность и пересечение. Однако при вставке очень вложенных наборов с кортежами это дает мне неправильный ответ. Я включил фрагмент кода для функций. Любое предложение, которое я мог бы сделать, чтобы улучшить свой результат?SML разница в настройках

val x17 = {1, 2, 8}; 
val x18 = {{1, 2, 8}, (1, {1, 2, 8})}; 
val x19 = ({{1, 2, 8}, (1, {1, 2, 8})}, {1, 2, 8}); 

пример операции:

x20 = {x19} Union x18; 
x21 = x20 \ {x17}; 
x22 = x20 intersection {x17}; 

правильный ответ:

x20 ={{1, 2, 8}, (1, {1, 2, 8}), ({{1, 2, 8}, (1, {1, 2, 8})}, {1, 2, 8})}; 
x21 ={(1, {1, 2, 8}), ({{1, 2, 8}, (1, {1, 2, 8})}, {1, 2, 8})}; 
x22 ={{1, 2, 8}}; 

мой выход:

let x20 be {{1,2,8},(1,{1,2,8})}; 
let x21 be {(1,{1,2,8})}; 
let x22 be {{1,2,8}}; 

код

datatype expression = SET of expression list | INT of int 
    fun interFunc (SET [],SET b,interSet) = SET (rev interSet) 
     | interFunc (SET a,SET [],interSet) = SET (rev interSet) 
     | interFunc (SET (h1::t1),SET b,interSet) = if (List.exists (fn x=>x=h1) b) then interFunc(SET t1,SET b,h1::interSet) else interFunc(SET t1,SET b,interSet); 

     fun garbage [] = [] 
     | garbage (h::t) = if (List.exists (fn x=>x=h) t) then h::(garbage t) else (garbage t); 

     fun unionFunc (SET [],SET b) = SET (b) 
     | unionFunc (SET a,SET []) = SET (a) 
     | unionFunc (SET a,SET b) = SET (garbage [email protected]); 


     (* set operation: difference, modified interFunc *) 
     fun diffFunc (SET [],SET b,diffSet) = SET (rev diffSet) 
     | diffFunc (a,SET [],diffSet) = SET (rev diffSet) 
     | diffFunc (SET (h1::t1),SET b,diffSet) = if (List.exists (fn x=>x=h1) b) then diffFunc(SET t1,SET b,diffSet) else diffFunc(SET t1,SET b,h1::diffSet); 

ответ

2

Навскидку, я вижу несколько ошибок:


garbage (h::t) = if (List.exists (fn x=>x=h) t) then h::(garbage t) else (garbage t) 

Похоже garbage предназначена для удаления дубликатов, выбрав последнее вхождение каждого значения; например, с учетом [1,2,3,2,1,2], он должен вернуть [3,1,2]. Однако то, что он на самом деле делает, это discard последнее вхождение каждого значения, поэтому оно дало бы [1,2,2].


diffFunc (SET (h1::t1),SET b,diffSet) = if (List.exists (fn x=>x=h1) b) then diffFunc(SET t1,SET b,diffSet) else diffFunc(SET t1,SET b,h1::diffSet); 

Если h1 происходит в b, то вам нужно сделать что-то фильтровать, что из b. Вышеизложенное не делает этого, поэтому по существу оно производит объединение, а не симметричную разницу.


В целом, я рекомендую прочитать в блоге Эрика Липперта "How to debug small programs" общих рекомендаций по отладке программы.