【问题标题】:How can I (more) easily compare two sets of numbers?我如何(更)轻松地比较两组数字?
【发布时间】:2012-11-25 03:39:00
【问题描述】:

我有一组三个数字,我想将一组数字与另一组数字进行比较。即,第一组中的每个数字都小于另一组中的至少一个数字。需要注意的是,第一组中的下一个数字必须小于第二组中的 不同 数字(即,{6,1,6} 对 {8,8,2} 有效,但 {6,2,6} 反对 {8,8,2} 不会)。我有一个工作方法,但它是蛮力和丑陋的。

如果我们有 setA 和 setB,并且每个都有元素 a、b 和 c:

if(setB.a < setA.a)
    if(setB.b < setA.b)
        if(setB.c < setA.c)
            return true;
    else if(setB.b < setA.c)
        if(setB.c < setA.b
            return true;

等等……

【问题讨论】:

  • 您能发布您当前的方法吗? (了解您想要更轻松地做到这一点)
  • 发布了一个样本。它又长又丑又尴尬。但你明白了。

标签: java numbers compare set


【解决方案1】:

编辑:我刚刚意识到您说这些集合被硬编码为 3 个值。这是一种适用于任何大小集合的超级通用算法。

对于一个三值集合,你可以对集合元素做同样的转储和排序,然后做:

if(setB.a < setA.a)
    if(setB.b < setA.b)
        if(setB.c < setA.c)
            return true;
return false;

================================================ =======

通用算法:

这是我能立即想到的最有效的方法。

伪代码(比 java 更 Pythonic,抱歉——希望 cmets 解释一下):

list l1 = set1.items() //get the items out
list l2 = set2.items()

l1 = sort(l1)
l2 = sort(l2) //sort the lists

int set2idx1 = l1[0].find_closest_greater_than_value(l2) //binary search or something
if set2idx1 exists:
    l2 = l2[set2idx1+1:] //in python this means l2 is reassigned to a subarray of l2 starting at set2idx1+1 going to the end of l2
else:
    return false

for(int i=1; i<l1.len; i++)
    int set2idxi = l1[i].find_closest_greater_than_value(l2) //binary search or something
    if set2idxi exists:
        l2 = l2[set2idxi+1:]
    else
        return false

return true

如有不妥之处请留言

编辑编辑:

为任何相关方解释一般算法:

  1. 将集合元素转储到数组中
  2. 对这些数组进行排序
  3. 遍历第一个数组,查看第二个数组中是否有大于当前值的值。如果是这样,请获取该值的索引并删除之前和包括该索引的所有内容,并将第二个数组变量重新分配给剩余的内容。
  4. 如果没有这样的值(因为它不存在或者您已经用完了要测试的值,则返回 false)。否则,最后返回 true。

这里的想法是,由于数组已排序,因此您知道任何大于第二个数组中匹配元素的元素都将大于您在第一个数组中测试的元素。所以你可以去掉较低的值,因为你不想使用相同的值,你也可以去掉你找到的那个。如果你曾经返回 false,你知道那是因为要么没有更大的值,要么是因为 array1 中的数字都大于 array2 中的数字,要么是因为 array2 中没有足够的数字大于 array1 中的数字。

【讨论】:

  • 我不认为我理解这一点:/
  • 还编辑了我意识到您的设置大小是固定的。我需要学会更仔细地阅读问题。
  • 太棒了。我不知道为什么我没有想到排序。谢谢!
【解决方案2】:

下面的伪代码呢?

Condition(A : Set, B : Set) : Bool =
    Let a := max(A), b := min(B) In
        // Namely, that each number in the first set is less than at least one number in the other set
        If a <= b Then
            // the next numbers in the first set must be less than a different number in the second set 
            Condition(without(A, a), without(B, b))
        Else
            False
        EndIf

其中 without(A, a) 表示集合 A 减去集合 {a}

【讨论】:

    【解决方案3】:

    似乎List 会比Set 做得更好,因为您的示例包含重复元素。简单地说:

    1) 对两个列表进行排序。

    2) 从第二个列表中剪掉前几个元素,直到第一个和第二个列表的大小相等。

    3) 对于每个i,直接比较list1[i]list2[i]

    代码:

    import java.util.*;
    class Main {
        public static void main (String[] args) {
            List<Integer> list1 = new ArrayList<Integer>();
            List<Integer> list2 = new ArrayList<Integer>();
            list1.add(3); list1.add(7); list1.add(7);
            list2.add(8); list2.add(8); list2.add(2); list2.add(1); list2.add(5);
            //algorithm:
            Collections.sort(list1);
            Collections.sort(list2);
            List<Integer> list3 = list2.subList(list2.size() - list1.size(), list2.size());
            System.out.println(list1.size() + " " + list3.size());
            boolean pass = true;
            for(int i = 0; pass && i < list1.size(); i++)
                if(list1.get(i) >= list3.get(i))
                    pass = false;
            System.out.println(pass);
        }
    }
    

    【讨论】:

    • 对不起,我不是说我在使用 Set 对象。您的解决方案与科琳的想法相同,但她是第一个。不过谢谢你:)
    • @eagerbeaver 哦,开个玩笑。但我的subList 实现与她的不同,因为您最多只需要list2 中的size(list1) 元素就可以将它与list1 进行比较。
    猜你喜欢
    • 2015-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-11
    • 2011-10-26
    • 1970-01-01
    • 2011-04-25
    相关资源
    最近更新 更多