Java非重复序列算法

时间:2016-12-21 06:21:42

标签: java algorithm

嘿大家所以我正在制作一个应用程序,循环通过一个1625字的数组&创建一个12字的字符串。问题是单个单词不能在字符串中出现两次。

(Numbered) ex.  
0, 1, 2,  3, 4, 5, 6, 7, 8, 9, 10, 11  
0, 1, 2,  3, 4, 5, 6, 7, 8, 9, 10, 12  
0, 1, 2,  3, 4, 5, 6, 7, 8, 9, 10, ...  
0, 1, 2,  3, 4, 5, 6, 7, 8, 9, 10, 1625  
then   
0, 1, 2,  3, 4, 5, 6, 7, 8, 9, 11, 10  
0, 1, 2,  3, 4, 5, 6, 7, 8, 9, 11, 12  
0, 1, 2,  3, 4, 5, 6, 7, 8, 9, 11, ...  
0, 1, 2,  3, 4, 5, 6, 7, 8, 9, 11, 1625  
0, 1, 2,  3, 4, 5, 6, 7, 8, 9, ..., ...  
0, 1, 2,  3, 4, 5, 6, 7, 8, 9, 1625, 1624  
then   
0, 1, 2,  3, 4, 5, 6, 7, 8, 10, 9, 11  
0, 1, 2,  3, 4, 5, 6, 7, 8, 10, 9, 12  
0, 1, 2,  3, 4, 5, 6, 7, 8, 10, 9, ...  
0, 1, 2,  3, 4, 5, 6, 7, 8, 10, 9, 1625  
0, 1, 2,  3, 4, 5, 6, 7, 8, 10, 9, 12    
And so on......  

我很难弄清楚这个算法背后的数学,因为我宁愿避免"如果"声明。如果有人能够帮助我那会很棒。

(注意上面的数字是数组中包含单词的索引)

编辑:简单的输出:
0,1,2 0,1,3 0,1,4 0,1,5 0,1,6 0,1,...
0,1,9 0,2,1 0,2,3 0,2,4 0,2,5 0,2,...
0,9,...
0,9,1 0,9,2 0,9,3 0,9,...
1,0,2,
1,0,3,
1,0,4 1,0,...... 1,2,3 等等

2 个答案:

答案 0 :(得分:0)

它不是一个非常可选的解决方案,因为我觉得它的蛮力方式。
这会对你有用吗? 您可以将TOTAL_SIZE变量替换为1626(也可以将1625替换为打印。)和CHUNK_SIZE替换为12。

public class TestClass {
    static int TOTAL_SIZE = 5;
    static int CHUNK_SIZE = 3;
    static int[] wordArray = new int[TOTAL_SIZE];

    public static void main(String args[]) {
        for(int i = 0; i < TOTAL_SIZE; i++) {
            wordArray[i] = i;
        }

        List<Integer> newList = new ArrayList<>();
        int[] visitedIndexes = new int[TOTAL_SIZE];
        printAllValues(newList, visitedIndexes);
    }


    private static void printAllValues(List<Integer> newList, int[] visitedIndexes) {
        if(newList.size() == CHUNK_SIZE) {
            newList.stream().forEach(System.out::print);
            System.out.println(""); // new line
            return;
        }

        for (int i = 0; i < TOTAL_SIZE; i++) {
            if (visitedIndexes[i] != 1) {
                visitedIndexes[i] = 1;
                newList.add(wordArray[i]);
                printAllValues(newList, visitedIndexes);
                newList.remove((Integer) wordArray[i]);
                visitedIndexes[i] = 0;
            }
        }
    }
}

输出:数组大小为5,字大小为3。

012
013
014
021
023
024
031
032
034
041
042
043
102
103
104
120
123
124
130
132
134
140
142
143
201
203
204
210
213
214
230
231
234
240
241
243
301
302
304
310
312
314
320
321
324
340
341
342
401
402
403
410
412
413
420
421
423
430
431
432

说明:

  1. 从原始列表中获取每个值。
  2. 对于追加的每个字符,请填充剩余字符的每个组合。
  3. 重试此逻辑,删除跳过此附加字符并尝试所有可能的组合。
  4. 可以优化此逻辑:

    1. 通过检查for(int i = 0; i < TOTAL_SIZE; i++)循环中剩余的值的数量,如果没有足够的值可以继续(例如if((list.size() + (TOTAL_SIZE-i)) < CHUNK_SIZE) break;
    2. 此外,对于大量数据,递归可能会爆炸。

答案 1 :(得分:0)

此代码可以在小集上运行。但我不确定你的案例需要多长时间处理大量数据。希望它有所帮助!

static int STRING_SIZE = 3; //12 in your  case
static int MAX_VAL = 10; //1625 in your case
static Set<Integer> set = new LinkedHashSet<Integer>();

public static void main(String[] args) {
    fillSet();
}

static void fillSet() {
    if (set.size() == STRING_SIZE) {
        System.out.println(set);
        return;
    }
    for (int i = 0; i < MAX_VAL; i++) {
        if (set.contains(i))
            continue;
        set.add(i);

        fillSet();

        set.remove(i);
    }

}