开发者

Filtering directly and indirectly connected things from list

开发者 https://www.devze.com 2022-12-23 02:35 出处:网络
if you have a function \"test a b\" which returns true if a and b are connected directly and if you have a given unordered list of things, what would be an elegant and fast solution to filter all conn

if you have a function "test a b" which returns true if a and b are connected directly and if you have a given unordered list of things, what would be an elegant and fast solution to filter all connected things from given list?

Example:

let test a b = let diff = a - b in diff == 0 ;;

let lst = [4;1;7;3;8;9;2;0] ;;

filter_connected 2 lst ;;

-> [4;1;3;2;0]

Any hints?


Hmmm, I will try to refine my question...

  1. there exists an unsorted list of things, pE. "let lst = [a;b;c;d;e;f;g;h];;" with type val a' list
  2. there exists also a function 开发者_如何转开发which decide if two things are directly connectable or in other words, if the two things are direct neighbours: val test : a' -> a' -> bool
  3. what I need is a function which has three arguments, the first one is a specific thing, the second one the unsorted list of things as suggested above, the last one is the test-function described above: val filter_connected : a' -> a' list -> (a' -> a' -> bool) -> a' list

if a <-> b are direct neigbours and b <-> c are direct neighbours then [a;b;c] are connected.

The suggested "List.filter () lst" does not help here, because it only filters the directed neighbours.

In the example above with a <-> b and b <-> c as direct neighbours in case of test-function, and all others not, the "filter_connected" call will be:

"filter_connected b lst (test);;"

and would return: [a;b;c]

Hope it will be more clean...


I will assume that you want to get the elements of the original list that are at distance less than 2 from 2.

        Objective Caml version 3.11.1

# let test x = abs (x - 2) <= 2 ;;
val test : int -> bool = <fun>
# List.filter test [4;1;7;3;8;9;2;0] ;;
- : int list = [4; 1; 3; 2; 0]
# 

List.filter is a function from the standard library. List.filter f l produces the list of elements of l for which f answers true.

Getting the function that decides if each element should go in the results list is orthogonal to the problem of filtering the list once you have this function, so you should do that first.

If you wish to use for f a function that is the transitive closure of a relation that you have, you can use the library ocamlgraph to obtain that transitive closure. Specifically, of these functions, use add_vertex for each puzzle piece, add_edge for each relation that you have, and then apply function transitive_closure to get a new graph g in which you can ask if there is an edge between two elements e1 and e2 with mem_edge g e1 e2. The partially applied function mem_edge g e1 can be passed to List.filter.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号