如何有效地将变量转换为模式中的数组
How to convert variables to an array in a pattern efficiently
抱歉措辞笨拙,我正在为如何描述这个问题而苦苦挣扎。
我的目标是编写一个接受三个变量并输出具有以下模式的二维数组的函数:
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;
}
这就是我想应用于我的原始问题的那种 "optimization"。再次抱歉,我缺乏足够的词汇来描述这个问题。
虽然我认为您的第一个定义是最好的,但可以定义公式:
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
您可以使用递归方法来解决您的问题:
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);
}
这是您要查找的内容吗(在 c# 代码中)。
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
)。从中间对称设置行,因为它们遵循相同的模式,只有 +
或 -
作为差异:
x
值是二的倍数,x+2*counter
和 x-2*counter
y
值是 2 的幂,pow(2,counter)=2<<counter
z
值是十的倍数,x+10*counter
和 x-10*counter
抱歉措辞笨拙,我正在为如何描述这个问题而苦苦挣扎。
我的目标是编写一个接受三个变量并输出具有以下模式的二维数组的函数:
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;
}
这就是我想应用于我的原始问题的那种 "optimization"。再次抱歉,我缺乏足够的词汇来描述这个问题。
虽然我认为您的第一个定义是最好的,但可以定义公式:
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
您可以使用递归方法来解决您的问题:
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);
}
这是您要查找的内容吗(在 c# 代码中)。
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
)。从中间对称设置行,因为它们遵循相同的模式,只有 +
或 -
作为差异:
x
值是二的倍数,x+2*counter
和x-2*counter
y
值是 2 的幂,pow(2,counter)=2<<counter
z
值是十的倍数,x+10*counter
和x-10*counter