Преобразование трехмерного массива в одномерный и обратно
Имеем трехмерный массив, в котором содержатся циферки или буковки. Не суть. Главное, мы знаем его размерность, например 3х3х3.
Всего 27 элементов.
В одной части проекта мы преобразуем этот массив в одномерный длиной 27 элементов и передаем эти элементы в другую часть проекта. *Так надо.*
Например:
/** * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann * (http://qbnz.com/highlighter/ and http://geshi.org/) */ .javascript.geshi_code {font-family:monospace;} .javascript.geshi_code .imp {font-weight: bold; color: red;} .javascript.geshi_code .kw1 {color: #000066; font-weight: bold;} .javascript.geshi_code .kw2 {color: #003366; font-weight: bold;} .javascript.geshi_code .kw3 {color: #000066;} .javascript.geshi_code .co1 {color: #006600; font-style: italic;} .javascript.geshi_code .co2 {color: #009966; font-style: italic;} .javascript.geshi_code .coMULTI {color: #006600; font-style: italic;} .javascript.geshi_code .es0 {color: #000099; font-weight: bold;} .javascript.geshi_code .br0 {color: #009900;} .javascript.geshi_code .sy0 {color: #339933;} .javascript.geshi_code .st0 {color: #3366CC;} .javascript.geshi_code .nu0 {color: #CC0000;} .javascript.geshi_code .me1 {color: #660066;} .javascript.geshi_code span.xtra { display:block; }
var a = [][][]; // это наш большой массив, определен заранее
var b = [];
for( i=0; i<3; i++) {
for( j=0; j<3; j++) {
for( k=0; k<3; k++) {
b[] = a[i][j][k];
}
}
}
Совместно с этим передаем и размерность массива.
Теперь на другой стороне нам нужно, зная размерности и одномерный массив, собрать обратно данные в трехмерный массив.
То ли время позднее, то ли отпуск сказывается, но не придумывается. Можете подсказать? Желательно сразу программным кодом (на любом языке из типовых).
***
Наступило утро, посетили мысли. Думаю, как-то вот так:
/** * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann * (http://qbnz.com/highlighter/ and http://geshi.org/) */ .javascript.geshi_code {font-family:monospace;} .javascript.geshi_code .imp {font-weight: bold; color: red;} .javascript.geshi_code .kw1 {color: #000066; font-weight: bold;} .javascript.geshi_code .kw2 {color: #003366; font-weight: bold;} .javascript.geshi_code .kw3 {color: #000066;} .javascript.geshi_code .co1 {color: #006600; font-style: italic;} .javascript.geshi_code .co2 {color: #009966; font-style: italic;} .javascript.geshi_code .coMULTI {color: #006600; font-style: italic;} .javascript.geshi_code .es0 {color: #000099; font-weight: bold;} .javascript.geshi_code .br0 {color: #009900;} .javascript.geshi_code .sy0 {color: #339933;} .javascript.geshi_code .st0 {color: #3366CC;} .javascript.geshi_code .nu0 {color: #CC0000;} .javascript.geshi_code .me1 {color: #660066;} .javascript.geshi_code span.xtra { display:block; }
var a = [][][]; // это наш большой массив, еще пустой
var b = []; // А это заполненный одномерный массив с 9 элементами
var x = 0; // А это счетчик в одномерном массиве
for( i=0; i<3; i++) {
for( j=0; j<3; j++) {
for( k=0; k<3; k++) {
a[i][j][k] = b[x];
x++;
}
}
}
Кажется, должно работать.
Всего 27 элементов.
В одной части проекта мы преобразуем этот массив в одномерный длиной 27 элементов и передаем эти элементы в другую часть проекта. *Так надо.*
Например:
/** * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann * (http://qbnz.com/highlighter/ and http://geshi.org/) */ .javascript.geshi_code {font-family:monospace;} .javascript.geshi_code .imp {font-weight: bold; color: red;} .javascript.geshi_code .kw1 {color: #000066; font-weight: bold;} .javascript.geshi_code .kw2 {color: #003366; font-weight: bold;} .javascript.geshi_code .kw3 {color: #000066;} .javascript.geshi_code .co1 {color: #006600; font-style: italic;} .javascript.geshi_code .co2 {color: #009966; font-style: italic;} .javascript.geshi_code .coMULTI {color: #006600; font-style: italic;} .javascript.geshi_code .es0 {color: #000099; font-weight: bold;} .javascript.geshi_code .br0 {color: #009900;} .javascript.geshi_code .sy0 {color: #339933;} .javascript.geshi_code .st0 {color: #3366CC;} .javascript.geshi_code .nu0 {color: #CC0000;} .javascript.geshi_code .me1 {color: #660066;} .javascript.geshi_code span.xtra { display:block; }
var a = [][][]; // это наш большой массив, определен заранее
var b = [];
for( i=0; i<3; i++) {
for( j=0; j<3; j++) {
for( k=0; k<3; k++) {
b[] = a[i][j][k];
}
}
}
Совместно с этим передаем и размерность массива.
Теперь на другой стороне нам нужно, зная размерности и одномерный массив, собрать обратно данные в трехмерный массив.
То ли время позднее, то ли отпуск сказывается, но не придумывается. Можете подсказать? Желательно сразу программным кодом (на любом языке из типовых).
***
Наступило утро, посетили мысли. Думаю, как-то вот так:
/** * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann * (http://qbnz.com/highlighter/ and http://geshi.org/) */ .javascript.geshi_code {font-family:monospace;} .javascript.geshi_code .imp {font-weight: bold; color: red;} .javascript.geshi_code .kw1 {color: #000066; font-weight: bold;} .javascript.geshi_code .kw2 {color: #003366; font-weight: bold;} .javascript.geshi_code .kw3 {color: #000066;} .javascript.geshi_code .co1 {color: #006600; font-style: italic;} .javascript.geshi_code .co2 {color: #009966; font-style: italic;} .javascript.geshi_code .coMULTI {color: #006600; font-style: italic;} .javascript.geshi_code .es0 {color: #000099; font-weight: bold;} .javascript.geshi_code .br0 {color: #009900;} .javascript.geshi_code .sy0 {color: #339933;} .javascript.geshi_code .st0 {color: #3366CC;} .javascript.geshi_code .nu0 {color: #CC0000;} .javascript.geshi_code .me1 {color: #660066;} .javascript.geshi_code span.xtra { display:block; }
var a = [][][]; // это наш большой массив, еще пустой
var b = []; // А это заполненный одномерный массив с 9 элементами
var x = 0; // А это счетчик в одномерном массиве
for( i=0; i<3; i++) {
for( j=0; j<3; j++) {
for( k=0; k<3; k++) {
a[i][j][k] = b[x];
x++;
}
}
}
Кажется, должно работать.
1 ответов
Вышло что-то похожее на бред, но все же выставляю на всеобщей осмотр :)
Работать будет только для квадратных матриц :)
$arr = array();
for( $i=0; $i<3; $i++) {
for( $j=0; $j<3; $j++) {
for( $k=0; $k<3; $k++) {
$arr[$i][$j][$k] = $i.$j.$k;
}
}
}
print_r($arr);
echo "<hr>";
$oneDimension = array();
for( $i=0; $i<3; $i++) {
for( $j=0; $j<3; $j++) {
for( $k=0; $k<3; $k++) {
$oneDimension[] =$arr[$i][$j][$k];
}
}
}
$depth = 0;
$curr = 0;
$outArr = array();
$howMuch = pow(count($oneDimension),1/3);
for ($i=0; $i<$howMuch; $i++){
$outArr[$i] = array();
doArray($depth,$howMuch, $curr,$oneDimension, $outArr[$i]);
}
print_r($outArr);
function doArray(&$depth = 0, $howMuch, &$currentIndex,$oneDimension, &$outArray){
$depth++;
$arrayTemp = array();
for ($i=0; $i<$howMuch; $i++){
$arrayTemp[] = $oneDimension[$currentIndex];
$currentIndex++;
}
$outArray[] = $arrayTemp;
if ($depth < $howMuch ){
doArray($depth, $howMuch, &$currentIndex,$oneDimension, &$outArray);
}else{
$depth = 0;
}
}
Ага, вот и пригодился мой сериализатор/десериализатор :) Сериализует массив любой размерности и, что очень приятно, восстанавливает его обратно. Рабочий пример для матрицы размером 3х3х3.
function Serialize(in_obj)
{
var elem_c = 0; // Для чисел, строк - длина строки, для массивов и объектов кол-во елементов
var elem = ""; // Само значение
var prefix = ""; // s - строка, n - число, o - объект
switch (typeof(in_obj))
{
case "string":
{
prefix = "s";
elem_c = in_obj.length;
elem = in_obj;
break;
}
case "object":
{
prefix = "o";
var obj_str = "";
for (var ind in in_obj)
{
var obj_t = typeof(in_obj[ind]);
if (obj_t != "function")
{
var elem_str = Serialize(in_obj[ind]);
obj_str = obj_str + ind.toString().length + ":" + ind + elem_str;
elem_c++;
}
}
elem = obj_str;
break;
}
case "number":
{
prefix = "n";
elem = in_obj.toString();
elem_c = elem.length;
break;
}
}
var ret_str = prefix + ":" + elem_c + ":" + elem;
return ret_str;
}
function Unserialize(in_str)
{
function p_unsrlz(in_str)
{
var pref = in_str.substring(0, 1);
var stop_me = false;
var cur_symb = "";
var data_len = ""; // Длинна строки с данными или количество элементов массива (объекта)
var read_len = 0; // Длинна прочитанной части
var counter = 1; // Указатель текущего символа
while (!stop_me)
{
counter++;
cur_symb = in_str.substring(counter, parseInt(counter)+1);
if (cur_symb != ":")
data_len = data_len + cur_symb;
else
stop_me = true;
}
// counter указывает на двоеточие перед началом данных
switch (pref)
{
case "n":
case "s":
{
var data = new String;
data = in_str.substring(parseInt(counter)+1, parseInt(counter) + 1 + parseInt(data_len));
if (pref == "n")
data = parseFloat(data);
read_len = 3 + parseInt(data_len) + parseInt(data_len.length);
break;
}
case "o":
{
var data = new Array(parseInt(data_len));
read_len = 3 + data_len.length;
for (var i = 0; i < parseInt(data_len); i++)
{
var my_key = p_unsrlz("s:" + in_str.substring(parseInt(counter)+1, in_str.length));
counter = counter + parseInt(my_key.data_len) - 1;
var my_obj_data = p_unsrlz(in_str.substring(parseInt(counter), in_str.length));
data[my_key.data] = my_obj_data.data;
counter = counter + parseInt(my_obj_data.data_len) - 1;
read_len = read_len + (my_key.data_len - 2) + my_obj_data.data_len;
}
break;
}
}
return {data: data, data_len: read_len};
}
var unsrlz = p_unsrlz(in_str);
return unsrlz.data;
}
Единственное условие - в массиве не должно быть циклических ссылок. Подробности - здесь.
Если надо, готов ответить на вопросы по самому алгоритму.
Для С++ что-то типа:
int l = 0;
T*** a = static_cast<T***>(new T[in]);
for(int i=0; i<in; i++) {
a[i] = static_cast<T**>(new T[jn]);
for(int j=0; j<jn; j++) {
a[i][j] = new T[kn];
for(int k=0; k<kn; k++, l++) {
a[i][j][k] = b[l];
}
}
}
T - тип элементов, in, jn, kn - размерности, b - входящий одномерный массив, a - реузльтирующий 3-х мерный массив.