2016-11-06 5 views
1

Я пытаюсь представить матрицу с произвольным размером в Java как 1d-массив, и я борюсь с реализацией функции, которую я пишу, чтобы вычислить правильный индекс в массиве, учитывая местоположение в матрице. Вот то, что я до сих пор:Индексирование многомерных массивов Java

private int indexOf(int... indices) { 
    assert indices.length == rank() : 
     "Number of indices does not match rank"; 
    if(indices.length == 1) return indices[0]; 
    int x = 0; 
    for(int i = 1; i < indices.length; ++i){ 
     x += indices[i] % this.dims[i]; 
    } 
    return x; 
} 

Где ранг() возвращает количество измерений в матрице и this.dims представляет собой массив с размером каждого измерения.

Я знаю, что i = y * numCols + x работает для версии 2-d, но у меня просто возникают проблемы с абстрагированием матрицы с переменными размерами.

Спасибо за помощь.

+0

Ваши размеры всегда одинакового размера? Другими словами, это 2D-массив всегда _N x N_ и массив 5D _N x N x N x N x N_? Или может ли 2D-массив быть _N x M_? – pathfinderelite

+0

Второй случай верен. Каждое измерение может быть разных размеров. –

+0

Почему вы не вставляете массивы внутри массивов, эффективно создавая многомерный массив? Дополнительные издержки памяти для этого были бы незначительными, а затем реализация стала тривиальной. И вы можете сделать что-то вроде 'int value = arr [4] [2] [87] [5]' вместо 'int value = arr.indexof (4,2,87,5)'. – MarcG

ответ

1

К сожалению, я отвечаю за мое собственное удовольствие (в JavaScript - работоспособный в инструментах Chrome Dev):

function SuperMatrix() { 
    this.ranks = [].slice.call(arguments); 
    this.rankCount = this.ranks.length; 

    this.arraySize = 
    this.ranks.reduce(function(a,b) { return a*b; }, 1); 

    this.dimensionSize = []; 

    this.dimensionSize[this.rankCount-1] = 1; 
    for (var i = this.rankCount-2; i >= 0; i -= 1) { 
    this.dimensionSize[i] = 
     this.dimensionSize[i+1]*this.ranks[i+1]; 
    } 

    this.array = new Array(this.arraySize); 
} 

SuperMatrix.prototype._index = function() { 

    var indexes = [].slice.call(arguments); 
    if (indexes.length !== this.rankCount) 
    throw new Error('invalid number of indexes'); 

    var index = 0; 
    for (var i = 0; i < this.rankCount; i += 1) { 
    index += indexes[i]*this.dimensionSize[i]; 
    } 

    if (index < 0 || index >= this.arraySize) 
    throw new Error('invalid index: ' + indexes.join(', ')); 

    return index; 
} 

SuperMatrix.prototype.get = function() { 
    var index = this._index.apply(this, arguments); 
    return this.array[index]; 
}; 

SuperMatrix.prototype.set = function(value) { 
    var indexes = [].slice.call(arguments, 1); 

    var index = this._index.apply(this, indexes); 
    this.array[index] = value; 

    return value; 
}; 


var foo = new SuperMatrix(2,3,5); 

for (var i = 0; i < 2; i+=1) { 
    for (var j =0; j < 3; j+=1) { 
    for (var k = 0; k < 5; k+= 1) { 
     foo.set([i,j,k].join(':'), i,j,k); 
    } 
    } 
} 

for (var i = 0; i < 2; i+=1) { 
    for (var j =0; j < 3; j+=1) { 
    for (var k = 0; k < 5; k+= 1) { 
     console.log(foo.get(i,j,k)); 
    } 
    } 
} 


console.log(foo); 

Для более высоких размерностей индексов: когда индекс увеличивается на 1 вы должны двигаться в массиве основы по размеру подмассива ,

+0

Прохладный бобы. Работает отлично! еще раз спасибо –

Смежные вопросы