You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Prolog技术咨询:如何判断X是否为A、B、C的中位数

Checking if X is the Median of A, B, C in Prolog

Hey there! Great question—testing for a median is a perfect starting problem in Prolog, and your initial approach is totally on the right track. Let's break this down step by step.

Your Initial Approach: Sorting a List

First, let's tackle the "how to turn three values into a list" part—it's way simpler than you might think! In Prolog, you can just wrap the three variables in square brackets to create a list: [A, B, C]. That's it, no extra hoops to jump through.

Next, sorting the list. A quick heads-up: Prolog's built-in sort/2 predicate removes duplicates, which could cause issues if you have repeated numbers (e.g., sort([2,2,3], Sorted) gives [2,3], which only has two elements). Instead, use msort/2—it sorts the list without stripping duplicates, which is exactly what we need for our median check.

Here's a concise implementation using your original idea:

is_median(X, A, B, C) :-
    msort([A, B, C], [_, X, _]).

How this works:

  • msort([A,B,C], Sorted) takes your three numbers and returns a sorted list (ascending order, duplicates preserved).
  • We then match the sorted list to [_, X, _]—the underscores are "don't care" variables, meaning we only care that the middle element is X.

Test it out with these queries:

  • is_median(2, 1, 2, 3). → true
  • is_median(2, 2, 2, 2). → true (all elements are the same, so 2 is the median)
  • is_median(3, 1, 2, 4). → false

Efficiency Concerns

Don't stress about efficiency here! Sorting three elements is a constant-time operation—no matter what values you pass, it's just a fixed number of comparisons. This approach is more than efficient enough for any use case involving three numbers.

Alternative: Logical Condition Checks

If you want to avoid sorting entirely, you can write logical conditions that directly verify X is the median. This is a bit more verbose but highlights Prolog's logical roots:

is_median(X, A, B, C) :-
    % X sits between A and B (in either order)
    (X >= A, X =< B ; X =< A, X >= B),
    % X sits between A and C (in either order)
    (X >= A, X =< C ; X =< A, X >= C),
    % X sits between B and C (in either order)
    (X >= B, X =< C ; X =< B, X >= C).

Or, if you prefer handling duplicates explicitly with min/max values, here's another take (with a helper predicate to count occurrences):

% Helper to count how many times a value appears in a list
count(_, [], 0).
count(X, [X|T], N) :- count(X, T, N1), N is N1 + 1.
count(X, [Y|T], N) :- X \= Y, count(X, T, N).

is_median(X, A, B, C) :-
    min_list([A,B,C], Min),
    max_list([A,B,C], Max),
    (   % X is the minimum and appears at least twice
        X = Min, count(Min, [A,B,C], Count), Count >= 2
    ;   % X is the maximum and appears at least twice
        X = Max, count(Max, [A,B,C], Count), Count >= 2
    ;   % X is strictly between min and max
        X > Min, X < Max
    ).

Final Thoughts

Your initial idea is excellent—sorting the list is intuitive and easy to read, which is perfect when you're learning Prolog. The msort/2 trick fixes the duplicate issue, and the whole thing is super efficient.

Content from Stack Exchange, question author: Westfall

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 07:24:38