测试所有可能的行组合

发布于 2024-12-25 22:25:28 字数 2312 浏览 1 评论 0原文

问题如下。有多个行具有非唯一标识符:

id value
0: {1,2,3}
0: {1,2,2}

1: {1,2,3}

2: {1,2,3}
2: {1,1,3}

我有函数 equals 可以相互比较多行。我需要编写一段代码来选择行作为函数 equals 的输入。所选行必须具有唯一 id,但我应该检查唯一 id 的所有可能组合。例如,如果有 5 行 id:0,0,1,2,3,那么我应该检查以下两个 id 组合:0,1,2,3 和 0,1,2,3,因为 0出现两次。当然,这两个组合中的每一个都将包含 id=0 的唯一行。

我的代码片段如下:

public class Test {
public static void main(String[] args) {
  ArrayList<Row> allRows = new ArrayList<Row>();
  allRows.add(new Row(0,new int[]{1,2,3}));
  allRows.add(new Row(0,new int[]{1,2,2}));
  allRows.add(new Row(1,new int[]{1,2,3}));
  allRows.add(new Row(2,new int[]{1,2,3}));
  allRows.add(new Row(2,new int[]{1,1,3}));

  boolean answer = hasEqualUniqueRows(allRows);
}

private boolean hasEqualUniqueRows(ArrayList<Row> allTokens) {
    for (int i=0; i<allTokens.size(); i++) {
        ArrayList<Integer[]> rows = new ArrayList<Integer[]>();
        rows = findUniqueRows(i,allTokens);
        boolean answer = equalsExceptForNulls(rows);
        if (answer) return true;
    }
    return false;
}
// Compare rows for similarities
public static <T> boolean equalsExceptForNulls(ArrayList<T[]> ts) {
    for (int i=0; i<ts.size(); i++) {
        for (int j=0; j<ts.size(); j++) {
            if (i != j) {
                boolean answer = equals(ts.get(i),ts.get(j));
                if (!answer) return false;
            }
        }
    }
    return true;
}

public static <T> boolean equals(T[] ts1, T[] ts2) {
    if (ts1.length != ts2.length) return false;
    for(int i = 0; i < ts1.length; i++) {
       T t1 = ts1[i], t2 = ts2[i];
       if (t1 != null && t2 != null && !t1.equals(t2)) 
           return false;
    }
    return true;
}

class Row {
          private String key;
          private Integer[] values;

      public Row(String k,Integer[] v) {
          this.key = k;
          this.values = v;
      }

      public String getKey() {
          return this.key;
      }

      public Integer[] getValues() {
          return this.values;
      }
}

}

由于具有唯一 id 的行数是先验未知的,我不知道如何解决这个问题。有什么建议吗?谢谢。

编辑#1 我更新了代码。现在更完整了。但它缺少函数findUniqueRows的实现。此函数应从 ArrayList 中选择具有唯一键 (ids) 的行。有人可以帮我开发这个功能吗?谢谢。

The problem is the following. There are multiple rows that have non-unique identifiers:

id value
0: {1,2,3}
0: {1,2,2}

1: {1,2,3}

2: {1,2,3}
2: {1,1,3}

I have the function equals that can compare multiple rows between each other. I need to write a code that selects the rows as an input of the function equals. The rows selected must have unique ids, BUT I should check all possible combinations of unique ids. For instance, if there are 5 rows with ids: 0,0,1,2,3, then I should check the following two combinations of ids: 0,1,2,3 and 0,1,2,3, because 0 apears twice. Of course, each of these two combinations will consist of unique rows that have id=0.

My code snippet is the following:

public class Test {
public static void main(String[] args) {
  ArrayList<Row> allRows = new ArrayList<Row>();
  allRows.add(new Row(0,new int[]{1,2,3}));
  allRows.add(new Row(0,new int[]{1,2,2}));
  allRows.add(new Row(1,new int[]{1,2,3}));
  allRows.add(new Row(2,new int[]{1,2,3}));
  allRows.add(new Row(2,new int[]{1,1,3}));

  boolean answer = hasEqualUniqueRows(allRows);
}

private boolean hasEqualUniqueRows(ArrayList<Row> allTokens) {
    for (int i=0; i<allTokens.size(); i++) {
        ArrayList<Integer[]> rows = new ArrayList<Integer[]>();
        rows = findUniqueRows(i,allTokens);
        boolean answer = equalsExceptForNulls(rows);
        if (answer) return true;
    }
    return false;
}
// Compare rows for similarities
public static <T> boolean equalsExceptForNulls(ArrayList<T[]> ts) {
    for (int i=0; i<ts.size(); i++) {
        for (int j=0; j<ts.size(); j++) {
            if (i != j) {
                boolean answer = equals(ts.get(i),ts.get(j));
                if (!answer) return false;
            }
        }
    }
    return true;
}

public static <T> boolean equals(T[] ts1, T[] ts2) {
    if (ts1.length != ts2.length) return false;
    for(int i = 0; i < ts1.length; i++) {
       T t1 = ts1[i], t2 = ts2[i];
       if (t1 != null && t2 != null && !t1.equals(t2)) 
           return false;
    }
    return true;
}

class Row {
          private String key;
          private Integer[] values;

      public Row(String k,Integer[] v) {
          this.key = k;
          this.values = v;
      }

      public String getKey() {
          return this.key;
      }

      public Integer[] getValues() {
          return this.values;
      }
}

}

Since the number of rows with unique ids is apriori unknown, I don´t know how to solve this problem. Any suggestions? Thanks.

Edit#1
I updated the code. Now it´s more complete. But it lacks the implementation of the function findUniqueRows. This function should select rows from the ArrayList that have unique keys (ids). Could someone help me to develop this function? Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

许一世地老天荒 2025-01-01 22:25:28

假设目标是找到没有重复的每个组合,您可以使用以下方法来完成此操作。查找重复项的测试只是为了确认它首先不会生成任何重复项。

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

public class Main {
    public static void main(String... args) {
        Bag<Integer> b = new Bag<>();
        b.countFor(1, 2);
        b.countFor(2, 1);
        b.countFor(3, 3);
        Set<String> set = new LinkedHashSet<>();
        for (List<Integer> list : b.combinations()) {
            System.out.println(list);
            String s = list.toString();
            if (!set.add(s))
                System.err.println("Duplicate entry " + s);
        }
    }
}

class Bag<E> {
    final Map<E, AtomicInteger> countMap = new LinkedHashMap<>();

    void countFor(E e, int n) {
        countMap.put(e, new AtomicInteger(n));
    }

    void decrement(E e) {
        AtomicInteger ai = countMap.get(e);
        if (ai.decrementAndGet() < 1)
            countMap.remove(e);
    }

    void increment(E e) {
        AtomicInteger ai = countMap.get(e);
        if (ai == null)
            countMap.put(e, new AtomicInteger(1));
        else
            ai.incrementAndGet();
    }

    List<List<E>> combinations() {
        List<List<E>> ret = new ArrayList<>();
        List<E> current = new ArrayList<>();
        combinations0(ret, current);
        return ret;
    }

    private void combinations0(List<List<E>> ret, List<E> current) {
        if (countMap.isEmpty()) {
            ret.add(new ArrayList<E>(current));
            return;
        }
        int position = current.size();
        current.add(null);
        List<E> es = new ArrayList<>(countMap.keySet());
        if (es.get(0) instanceof Comparable)
            Collections.sort((List) es);
        for (E e : es) {
            current.set(position, e);
            decrement(e);
            combinations0(ret, current);
            increment(e);
        }
        current.remove(position);
    }
}

Assuming the objective is to find every combination without duplicates you can do this with the following. The test to find duplicates is just to confirm it doesn't generate any duplicates in the first place.

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

public class Main {
    public static void main(String... args) {
        Bag<Integer> b = new Bag<>();
        b.countFor(1, 2);
        b.countFor(2, 1);
        b.countFor(3, 3);
        Set<String> set = new LinkedHashSet<>();
        for (List<Integer> list : b.combinations()) {
            System.out.println(list);
            String s = list.toString();
            if (!set.add(s))
                System.err.println("Duplicate entry " + s);
        }
    }
}

class Bag<E> {
    final Map<E, AtomicInteger> countMap = new LinkedHashMap<>();

    void countFor(E e, int n) {
        countMap.put(e, new AtomicInteger(n));
    }

    void decrement(E e) {
        AtomicInteger ai = countMap.get(e);
        if (ai.decrementAndGet() < 1)
            countMap.remove(e);
    }

    void increment(E e) {
        AtomicInteger ai = countMap.get(e);
        if (ai == null)
            countMap.put(e, new AtomicInteger(1));
        else
            ai.incrementAndGet();
    }

    List<List<E>> combinations() {
        List<List<E>> ret = new ArrayList<>();
        List<E> current = new ArrayList<>();
        combinations0(ret, current);
        return ret;
    }

    private void combinations0(List<List<E>> ret, List<E> current) {
        if (countMap.isEmpty()) {
            ret.add(new ArrayList<E>(current));
            return;
        }
        int position = current.size();
        current.add(null);
        List<E> es = new ArrayList<>(countMap.keySet());
        if (es.get(0) instanceof Comparable)
            Collections.sort((List) es);
        for (E e : es) {
            current.set(position, e);
            decrement(e);
            combinations0(ret, current);
            increment(e);
        }
        current.remove(position);
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文