Как эффективно преобразовать переменные в массив в шаблоне - PullRequest
0 голосов
/ 30 января 2019

Извиняюсь за неуклюжую формулировку, я изо всех сил пытаюсь описать эту проблему.

Моя цель - написать функцию, которая принимает три переменные и выводит двумерный массив с таким шаблоном:

var foo = function(x, y, z) {
    array = [
        [x + 8, y + 16, z + 35],
        [x + 6, y +  8, z + 30],
        [x + 4, y +  4, z + 20],
        [x + 2, y +  2, z + 10],
        [x    , y     , z     ],
        [x - 2, y +  2, z - 10],
        [x - 4, y +  4, z - 20],
        [x - 6, y +  8, z - 30],
        [x - 8, y + 16, z - 35]
    ]
    return array;
}

Очевидно, что такой способ написания функции кажется довольно неэффективным.

Один из способов, который я попытался решить, - это цикл.Но мое решение представляет три массива и также довольно неэлегантно.

var x_mod = [8,   6,  4,  2, 0, -2,   -4,  -6,  -8];
var y_mod = [16,  8,  4,  2, 0,  2,    4,   8,  16];
var z_mod = [35, 30, 20, 10, 0, -10, -20, -30, -35];

for(let i = 0; i < 9; i++) {
    array[i] = [x + x_mod[i], y + y_mod[i], z + z_mod[i]);
}

Есть ли лучший способ написания этого алгоритма?Я также был бы признателен за любые подсказки относительно того, как называется эта проблема, или что я должен изучить, чтобы решить ее.

Спасибо!

РЕДАКТИРОВАТЬ

Это пример оптимизации, о которой я думал.

Следующая функция

var bar = function(x, y, z) {
    array = [
        [x + 1, y + 2, z + 3],
        [x + 2, y + 4, z + 6],
        [x + 3, y + 6, z + 9]
    ]
    return array;
}

также может быть написана следующим образом:

var bar = function(x, y, z) {
    array = [];
    for(var i = 1; i < 4; i++)
        array[i] = [x + i, x + i*2, x + i*3];
    return array;
}

Это та разновидность «оптимизации», которую я хотел применить к моей исходной проблеме.Опять же, я прошу прощения, что мне не хватает словарного запаса, чтобы адекватно описать эту проблему.

Ответы [ 3 ]

0 голосов
/ 30 января 2019

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

  var your_array = []
  function myFun(x, y, z, count){
        //base case
        if(count = 4)
           return;

        // head recursion
        temp = [];
        temp.push(x); temp.push(y); temp.push(z);
        your_array.push(temp);

        myFun(x-2, y/2, z-10, count+1)

        //tail recursion
        temp = []
        temp.push(x); temp.push(y); temp.push(z);
        your_array.push(temp);            
  }
0 голосов
/ 01 февраля 2019

Это то, что вы ищете (в коде).

static class Program
{
    static void Main(string[] args)
    {
        var m_2 = GenerateMatrix(2, 0.0, 0.0, 0.0);
        // result:
        // |  2.0   2.0   10.0 | + span = 2
        // |  0.0   0.0    0.0 | + 
        // | -2.0  -2.0  -10.0 |
        var m_3 = GenerateMatrix(3, 0.0, 0.0, 0.0);
        // result:
        // |  4.0   4.0   20.0 | +
        // |  2.0   2.0   10.0 | | span = 3
        // |  0.0   0.0    0.0 | +
        // | -2.0  -2.0  -10.0 |
        // | -4.0  -4.0  -20.0 |
        var m_5 = GenerateMatrix(5, 0.0, 0.0, 0.0);
        // result:
        // |  8.0  16.0   40.0 | +
        // |  6.0   8.0   30.0 | |
        // |  4.0   4.0   20.0 | | span = 5
        // |  2.0   2.0   10.0 | | 
        // |  0.0   0.0    0.0 | +
        // | -2.0  -2.0  -10.0 |
        // | -4.0  -4.0  -20.0 |
        // | -6.0  -8.0  -30.0 | 
        // | -8.0 -16.0  -40.0 | 
    }

    static double[][] GenerateMatrix(int span, double x, double y, double z)
    {
        var result = new double[2*(span-1)+1][];
        result[span-1] = new double[] { x, y, z };
        for (int i = 0; i < span-1; i++)
        {
            result[span-2-i] = new double[] { x+2*(i+1), y + (2<<i), z + 10*(i+1) };
            result[span+i] = new double[] { x-2*(i+1), y - (2<<i), z - 10*(i+1) };
        }
        return result;
    }

Я использую следующие правила (используйте counter=1..span-1).Установите строки симметрично от середины, так как они следуют одному и тому же шаблону только с разницей + или -:

  1. x значения кратны двум, x+2*counter и x-2*counter
  2. y значения являются степенью двойки, pow(2,counter)=2<<counter
  3. z значения кратны десяткам, x+10*counter и x-10*counter
0 голосов
/ 30 января 2019

Хотя я считаю, что ваше первое определение является лучшим, могут быть определены формулы:

 diff =  (4 - i)
 ad = abs(diff)
 x +  diff * 2
 y +  (1 << abs(ad)) - trunc((4 - ad) / 4)
     //using bit shift to compose power of two if possible 
 z + 10 * diff - 5 * trunc(diff / 4)         
     //rounding towards zero!

Проверка Python:

import math
for i in range(0, 9):
     diff =  (4 - i)
     ad = abs(diff)
     print(i, diff * 2, (1 << abs(ad)) - (4 - ad) // 4,  10 * diff - 5 * math.trunc(diff / 4))

0 8 16 35
1 6 8 30
2 4 4 20
3 2 2 10
4 0 0 0
5 -2 2 -10
6 -4 4 -20
7 -6 8 -30
8 -8 16 -35
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...