在java中查找n个数组之间的公共元素之和

时间:2017-04-10 15:23:55

标签: java arrays algorithm data-structures array-algorithms

我有一个程序可以对两个数组的常用元素进行求和。为此,我使用了两个for循环,如果我有三个,那么我可以使用三个for循环。但是如何总结运行时n中n个数组的公共元素。

我不知道如何在运行时更改循环次数,还是有其他相关概念?

以下是我用来总结两个阵列的代码:

import java.util.Scanner;

public class Sample {
    public static void main(String... args)
    {
        Scanner sc=new Scanner(System.in);
        int arr1[]={1,2,3,4,5},arr2[]={4,5,6,7,8},sum=0;
        for (int i=0;i<arr1.length;i++)
        {
            for (int j=0;j<arr2.length;j++)
            {
                if (arr1[i]==arr2[j])
                {
                    sum+=(arr1[i]);
                }
            }
        }
    }
}

3 个答案:

答案 0 :(得分:3)

可以有不同的实现。您可以使用以下方法。这是伪代码

  1. 使用2D数组存储数组。如果数组的数量为n且大小为m,则数组将为input[n][m]
  2. 使用ArrayList commonItems存储常用项目。使用input[0]
  3. 的元素启动它
  4. 现在遍历i = 1 to n-1的数组。与每个input[i]进行比较,每个步骤只存储commonItemsinput[i]的常用项。您可以将input[i]转换为列表并使用retainAll方法来完成此操作。
  5. 在迭代结束时,commonItem列表将仅包含公共数字。现在总结一下这个清单的价值。

答案 1 :(得分:1)

假设元素的索引不重要:a [1] = 2且a [5] = 2,则只需要两个嵌套循环。

首先,您需要将n-1个数组放入集合列表中。然后遍历第n个数组并检查列表中的所有集合中是否存在每个元素。如果确实存在则添加到总数。

答案 2 :(得分:1)

实际上有一种更通用的方法,它也回答了“如何在运行时更改循环次数的问题?”。

一般问题

我们正在寻找一种方法来实现与此相当的东西:

for (i1 = 0; i1 < k1; i1++) { 
  for (i2 = 0; i2 < k2; i2++) {
    for (i3 = 0; i3 < k3; i3++) {
       ...
         for (in = 0; in < kn; in++) {
           f(x1[i1], x2[i2], ... xn[in]);
         }
       ...
     }
   }
 }

其中,n在运行时给出,f是一个函数,它采用n参数列表,处理当前的n元组。

一般解决方案

基于递归的概念,有一个通用的解决方案。

这是一个产生所需行为的实现:

void process(int idx, int n, int[][] x, int[] k, Object[] ntuple) {
    if (idx == n) {
        // we have a complete n-tuple, 
        // with an element from each of the n arrays
        f(ntuple);
        return;
    }

    // this is the idx'th "for" statement
    for (int i = 0; i < k[idx]; i++) {
        ntuple[idx] = x[idx][i];
        // with this recursive call we make sure that 
        // we also generate the rest of the for's
        process(idx + 1, n, x, k, ntuple);
    }
}

该函数假定n数组存储在矩阵x中,第一个调用应如下所示:

process(0, n, x, k, new Object[n]);

实际考虑因素

上述解决方案具有高复杂度(它是O(k 1 ⋅k 2 ⋅..⋅k n )),但有时候可以避免直到最深的循环。

实际上,在本文中提到的具体问题中(需要对所有数组中的公共元素求和),我们可以跳过生成一些元组例如如果已经x 2 [ i 2 ]≠x 1 [i 1 ]。

在递归解决方案中,可以轻松修剪这些情况。此问题的具体代码可能如下所示:

void process(int idx, int n, int[][] x, int[] k, int value) {
    if (idx == n) {
        // all elements from the current tuple are equal to "value". 
        // add this to the global "sum" variable
        sum += value;
        return;
    }

    for (int i = 0; i < k[idx]; i++) {
        if (idx == 0) {
            // this is the outer "for", set the new value
            value = x[0][i];
        } else {
            // check if the current element from the idx'th for
            // has the same value as all previous elements
            if (x[idx][i] == value) {
                process(idx + 1, n, x, k, value);
            }
        }
    }
}