如何从3 X 15阵列中找到1 X 15阵列?

时间:2010-06-23 12:21:49

标签: php javascript algorithm

我试图从3 X 15阵列创建1 X 15维唯一数组。我无法做到这一点。请帮我解决这个问题。提前谢谢。

3 X 15阵列

Array[(1,2,3),(1,2,3),(1,2,3),(1,2,3),(1,2,3),(1,2,3),(1,2,3),(1,2,3),(1,2,3),(1,2,3),(1,2,3),(1,2,3),(1,2,3),(1,2,3),(1,2,3)]

5 个答案:

答案 0 :(得分:2)

你有一组3个字符(1,2,3),你想要3个字母的字母表中每个可能的15个字母的单词。解决方案是递归的:

Let size be your word size, given as parameter
Let alphabet be your character set, given as parameter
If size is 0 then
  return collection with empty string
Let result be the collection of possible words, starting empty
Let subset be the solution of the problem for size-1 and alphabet
For every word in subset:
  For every character in alphabet:
    Let newword be the concatenation of character and word
    Add newword to result
return result

(教学,未经优化)javascript:

function words(size, alphabet) {
  if(size == 0) return [''];
  var result = [];
  var subset = words(size-1, alphabet);
  for(var i=0; i<subset.length; i++) {
    var word = subset[i];
    for(var j=0; j<alphabet.length; j++) {
      var character = alphabet[j];
      var newword = character+word;
      result.push(newword);
    }
  }
  return result;
}
words(3,['1','2','3']);
// 111,211,311,121,221,321,131,231,331,112,212,312,122,222,322,132,232,332,113,213,313,123,223,323,133,233,333

注意:15个字母中有超过1400万个字,一组3个字符。所以计算时间很长。

编辑:如果您的数组并不总是具有相同的3个字符,那么您必须更改该函数的第一行。必须将数组作为参数给出,然后函数弹出它将用作字母表的第一个数组,并将其余数据提供给递归调用:

function words(arrays) {
  if(arrays.length == 0) return [''];
  var result = [];
  var alphabet = arrays.shift();
  var subset = words(arrays);
  for(var i=0; i<subset.length; i++) {
    var word = subset[i];
    for(var j=0; j<alphabet.length; j++) {
      var character = alphabet[j];
      var newword = character+word;
      result.push(newword);
    }
  }
  return result;
}
words([['a','b','c'],['d','e','f'],['h','i','j']])
// adh,bdh,cdh,aeh,beh,ceh,afh,bfh,cfh,adi,bdi,cdi,aei,bei,cei,afi,bfi,cfi,adj,bdj,cdj,aej,bej,cej,afj,bfj,cfj

答案 1 :(得分:0)

您似乎将javascript与其他语言混合在一起 - javascript没有多维数组, 虽然数组可以由数组(或数组数组)组成

这是一个包含15个3成员数组的javascript数组

var a= [[1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3],
    [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], 
    [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3]];

如果要将其折叠为仅包含基元的数组,可以使用String方法映射每个元素 -

a=a.map(String);    
alert(a.join('\n'))  

/*  returned value: 
1,2,3
1,2,3
1,2,3
1,2,3
1,2,3
1,2,3
1,2,3
1,2,3
1,2,3
1,2,3
1,2,3
1,2,3
1,2,3
1,2,3
1,2,3
*/

但在这种情况下,唯一数组只有一个成员。

//对于IE和旧版客户端,您可以使用map方法 -

if(![].map){
    Array.prototype.map= function(fun, scope){
        var L= this.length, A= Array(this.length), i= 0, val;
        if(typeof fun== 'function'){
            while(i< L){
                if(i in this){
                    A[i]= fun.call(scope, this[i], i, this);
                }
                ++i;
            }
            return A;
        }
    }
}

答案 2 :(得分:0)

最后 - 我想我知道你在寻找什么。

假设:

input = {{"a","b","c"},{"d","e","f"},{"g","h","i"},{"j","k","l"}};

// expected output:
// "adgj", "bdgj", "cdgj", "aegj", "begj", "cegj", ... , "cfil"
//  0000    1000    2000    0100    1100    2100          2222   <-- indexes

解决方案的关键是上一个注释行中的数字序列。您必须生成此序列和序列值作为创建组合的键,例如:

a_25 => {0,2,2,1} => input[0][0]+input[0][2]+input[0][2]+input[0][1] => "afik"

我为输入数组选择了不同的大小和内容,只是为了说明这个想法。序列生成器将获取一个数组,执行并“递增”并返回'递增'数组,如:

increment({0,2,2,1}) -> {0,2,2,2}
increment({0,2,2,2}) -> {1,0,0,0}

希望继续执行任务会有所帮助。

答案 3 :(得分:0)

据我了解,您正在寻找使用3x15数组的内部数组计算所有排列,以指定输出数组的每个索引的可能性集。

这是一个递归的Java解决方案(我不确定你实际使用的语言是什么,这就是为什么最好不要在你的标签中列出4种不同的语言):

public static void main(String[] args) throws Exception {
    List<int[]> perms = new ArrayList<int[]>();
    int[][] a = {{1,2,3},{1,2,3},{1,2,3},{1,2,3},{1,2,3}};
    int[] buff = new int[a.length];

    recurse(perms, a, buff, 0);

    int[][] allPerms = perms.toArray(new int[perms.size()][]);
    for ( int[] arr : allPerms ) {
        System.out.println(Arrays.toString(arr));
    }
}

private static void recurse(List<int[]> perms, int[][] a, int[] buff, int index) {
    if ( index == a.length ) {
        perms.add(Arrays.copyOf(buff, buff.length));
    } else {
        for ( int i = 0; i < a[index].length; i++ ) {
            buff[index] = a[index][i];
            recurse(perms, a, buff, index+1);
        }
    }
}

问题的本质并不能使递归变得优雅。

答案 4 :(得分:0)

您有3^15(或14,348,907)种可能性。如果生成组合的顺序无关紧要,那么您可以尝试这样的事情:

计数器计数从0到14348906.对于每个步骤,起始数组中的索引将是计数器的base-3表示的数字。

例如,如果计数器为0,则在base-3中为000000000000000,您将使用索引Array[0][0], Array[1][0], Array[2][0],...,Array[14][0]

如果计数器是15463,那么在base-3中这是000000210012201,你可以使用索引Array[0][0],...,Array[7][2],Array[8][1],Array[9][0],...,Array[12][2],Array[13][0],Array[14][1]

要将十进制数转换为基数3,请重复将数字除以3。每次除法时,余数将是base-3表示中的下一个数字(从最低有效位开始)。例如(在伪C中):

#include <stdlib.h>
int   count, idx, quotient;
div_t result;
int   indices[15];
int   Array[15][3] = {{1,2,3},{1,2,3}, etc etc}
int*  pNewArray;
for (count = 0; count < 14348906; ++count) {
    memset(indices, 0, 15*sizeof(int));
    result.quot = count;
    idx = 0;
    while (result.quot > 0) {
        result = div(result.quot, 3);
        indices[idx++] = result.rem;
    }
    pNewArray = malloc(15 * sizeof(int));
    for (idx = 0; idx < 15; ++idx)
        pNewArray[idx] = Array[idx][indices[15-idx]];
    DoSomethingWith(pNewArray);
}