【问题标题】:How to shuffle a array of objects with no two duplicates next to each other? [closed]如何洗牌一个没有两个重复的对象数组? [关闭]
【发布时间】:2019-11-25 16:57:12
【问题描述】:

我需要对从 API 接收到的对象数组进行洗牌。该数组将具有相同的重复对象。

有效输入:

  • ["a","a","a","a","b","b","b","b","c","c","c","c "]
  • ["a", "a", "b", "b"] 或 ["b", "b", "a", "a"]

输入无效:

  • ["a","a","a","a","b","c"]
  • [“a”、“b”、“a”、“b”]

洗牌后:

  • i 和 i + 1 处的对象应该不同
  • 每次对数组进行洗牌时,都应该生成一个新的有效解

有效输出:

  • b,a,c,b,a,c,a,c,b,a,c,b
  • c,a,b,a,b,c,a,c,b,a,b,c
  • c,b,a,c,b,a,c,b,a,c,b,a

无效输出:

  • c,c,a,b,b,a,c,b,a,c,b,a

我开始使用 Fisher-Yates 进行初始洗牌,然后验证解决方案是否有效。 一旦我有一个小集合,这种蛮力方法就起作用了,但随着输入的增长它变得无用。 有没有一种有效的方法来生成随机排列而不会使重复项彼此相邻?

Efficient algorithm for ordering different types of objects 提供了有关如何使同类对象彼此远离的见解,不幸的是,如果我再次尝试随机播放,我会遇到相同的解决方案/模式。

https://stackoverflow.com/a/32366585/4271233 生成满足“没有两个相邻的重复项”的所有可能排列,但遗憾的是我需要生成所有排列然后随机选择一个

【问题讨论】:

标签: java arrays algorithm shuffle


【解决方案1】:

这个解决方案不是最优的,但你可以从这个开始

    public static void main(String[] args) {
        String[] input = new String[]{
                "a", "a", "a", "a", "b", "b", "b", "b", "c", "c", "c", "c"
        };
        // here we'll generate the output
        String[] output = new String[input.length];
        // how many different characters do we have?
        int characters = 0;
        for (int i = 1; i < input.length; i++) {
            if (!input[i - 1].equals(input[i])) {
                break;
            } else {
                characters++;
            }
        }
        // how many times each character appears
        int times = input.length / characters;
        // different characters to shuffle
        String[] toShuffle = new String[characters];
        int m = 0;
        while (times * m < input.length) {
            toShuffle[m] = input[times * m];
            m++;
        }
        // for each position in output
        for (int i = 0; i < output.length;) {
            // define a list with all different characters
            List<String> remain = new ArrayList<>(Arrays.asList(toShuffle));
            // set a random character without repetition
            int j = 0;
            while (j < characters) {
                int pos = 0;
                // after {characters} we have a chance of repetition so we check
                if(i % characters == 0 && i != 0) {
                    do {
                        pos = Double.valueOf(Math.random() * remain.size())
                                .intValue();
                    } while (output[i-1].equals(remain.get(pos)));
                } else {
                    pos = Double.valueOf(Math.random() * remain.size())
                            .intValue();
                }
                // assign a character
                output[i] = remain.get(pos);
                // remove from possible chars to not repeat
                remain.remove(pos);
                j++;
                i++;
            }
        }
        // this is the solution
        System.out.println(Arrays.toString(output));
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-30
    • 2013-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多