使用循环填充具有所需属性的数组
Using a loop to fill up an array with desired properties
我在 java 工作,在为我需要的任务正确制定循环时遇到了一些麻烦。我想将元素添加到 3 元素数组,以便满足这些条件:
array_new[0] = f(array_old[0], array_old[1])
array_new[1] = f(array_old[0], array_old[2])
array_new[2] = f(array_old[1], array_old[2])
这里 array_new
是我希望使用我的循环填充的数组,array_old
是一个现有数组,它为 f
提供参数,这是一个先前定义的方法。请注意这里 f(a,b)=f(b,a)
,我不想重复参数或重复输出:所以没有 f(a,a)
也没有 f(b,a)
,因为循环中已经达到 f(a,b)
.所有这些单独的部分都已定义并正常工作,我的问题只是让循环的逻辑正确。这是我最初尝试的:
for (int i=0; i<array_old.length; i++) {
for (int j=0; j<array_old.length; j++) {
for (int k=0; k<array_old.length; k++) {
if (i<j) {
array_new[k]=f(array_old[i], array_old[j]);
}
}
}
}
然而我意识到这更新 array_new[0]
违背了我的意愿:首先它根据需要设置 array_new[0] = f(array_old[0], array_old[1])
,然后它设置 array_new[0] = f(array_old[1], array_old[2])
我试过以几种不同的方式处理索引,但似乎总是至少有一个重复或不正确的值。我会很感激这里的任何帮助
这可以通过以下方式实现,arr_new
的大小可以计算为从1到n
- 1的递增之和,其中n
是长度共 arr_old
个:
int[] arr_old = {1, 2, 3};
int n = arr_old.length;
int[] arr_new = new int[n * (n - 1) / 2];
for (int i = 0, k = 0; i < n - 1; i++) {
for (int j = i + 1; j < n; j++, k++) {
arr_new[k] = f(arr_old[i], arr_old[j]);
}
}
System.out.println(Arrays.toString(arr_new));
假设 f
打印其参数和 returns 总和:
static int f(int a, int b) {
System.out.println(a + " " + b);
return a + b;
}
输出结果如下:
1 2
1 3
2 3
[3, 4, 5]
第一件事是表征新数组的大小 - 对于 n > 3,它将比输入数组大(很多)。您正在寻找旧数组中两个索引的每个组合,其中顺序无关紧要,所以第一步是
new_array <- array of size (n choose 2) = 0.5*n*(n-1)
然后您需要以有序的方式生成所有数字对。我会使用一个双重嵌套的 for 循环,用一个计数器记录新数组中的当前索引:
int p = 0
for (i = 0; i < n; ++i) {
for (j = i + 1; j < n; ++j) {
new_array[p] = f(old_array[i], old_array[j])
p = p + 1
}
}
请注意如何通过正确设置初始化 j,避免浪费迭代和比较。
我在 java 工作,在为我需要的任务正确制定循环时遇到了一些麻烦。我想将元素添加到 3 元素数组,以便满足这些条件:
array_new[0] = f(array_old[0], array_old[1])
array_new[1] = f(array_old[0], array_old[2])
array_new[2] = f(array_old[1], array_old[2])
这里 array_new
是我希望使用我的循环填充的数组,array_old
是一个现有数组,它为 f
提供参数,这是一个先前定义的方法。请注意这里 f(a,b)=f(b,a)
,我不想重复参数或重复输出:所以没有 f(a,a)
也没有 f(b,a)
,因为循环中已经达到 f(a,b)
.所有这些单独的部分都已定义并正常工作,我的问题只是让循环的逻辑正确。这是我最初尝试的:
for (int i=0; i<array_old.length; i++) {
for (int j=0; j<array_old.length; j++) {
for (int k=0; k<array_old.length; k++) {
if (i<j) {
array_new[k]=f(array_old[i], array_old[j]);
}
}
}
}
然而我意识到这更新 array_new[0]
违背了我的意愿:首先它根据需要设置 array_new[0] = f(array_old[0], array_old[1])
,然后它设置 array_new[0] = f(array_old[1], array_old[2])
我试过以几种不同的方式处理索引,但似乎总是至少有一个重复或不正确的值。我会很感激这里的任何帮助
这可以通过以下方式实现,arr_new
的大小可以计算为从1到n
- 1的递增之和,其中n
是长度共 arr_old
个:
int[] arr_old = {1, 2, 3};
int n = arr_old.length;
int[] arr_new = new int[n * (n - 1) / 2];
for (int i = 0, k = 0; i < n - 1; i++) {
for (int j = i + 1; j < n; j++, k++) {
arr_new[k] = f(arr_old[i], arr_old[j]);
}
}
System.out.println(Arrays.toString(arr_new));
假设 f
打印其参数和 returns 总和:
static int f(int a, int b) {
System.out.println(a + " " + b);
return a + b;
}
输出结果如下:
1 2
1 3
2 3
[3, 4, 5]
第一件事是表征新数组的大小 - 对于 n > 3,它将比输入数组大(很多)。您正在寻找旧数组中两个索引的每个组合,其中顺序无关紧要,所以第一步是
new_array <- array of size (n choose 2) = 0.5*n*(n-1)
然后您需要以有序的方式生成所有数字对。我会使用一个双重嵌套的 for 循环,用一个计数器记录新数组中的当前索引:
int p = 0
for (i = 0; i < n; ++i) {
for (j = i + 1; j < n; ++j) {
new_array[p] = f(old_array[i], old_array[j])
p = p + 1
}
}
请注意如何通过正确设置初始化 j,避免浪费迭代和比较。