繁体   English   中英

如何创建 java 程序来查找数组中连续数字的数量?

[英]How can I create a java program to find the amount of consecutive numbers in an array?

我正在尝试制作一个 Java 程序来查找数组中连续数字的数量。 例如,如果一个数组具有值 1,8,10,4,2,3,则有 4 个连续的数字 (1,2,3,4)。 我已经创建了这个程序,但是在第 28 行和第 31 行出现 ArrayIndexOutOfBoundsException 错误,我该如何解决这个错误? (如果错误得到修复,我什至不确定我制作的程序是否可以工作)。 注意:我知道网上有很多解决方案,但我是一名初学者程序员,我正在尝试以更简单的方式做到这一点。

import java.util.Arrays;

class Main {
  public static void main(String[] args) {
    
    consec();
    

  }
    
    static void consec()
    {
            
      int[] nums = {16, 4, 5, 200, 6, 7, 70, 8};
      int counter=0;
      
      Arrays.sort(nums);
      for (int i=0; i < nums.length; i++)
        if (i != nums.length - 1)
          System.out.print(nums[i] + ", ");
        else
          System.out.print(nums[i]);

      for (int i=0; i < nums.length; i++)
        
        for (int j=i; j < nums.length - i; j++)
          if (nums[j + 1] - 1 == nums[j])
            counter++;
          
            else if (nums[j+1]==counter)
              System.out.print("Consective amount is" + counter);
            
   
    }  
}

异常的问题在于nums[j + 1]的访问。 请注意,由于 for 循环, j 可以与nums.length - 1一样大。 因此 j + 1 可以是 nums.length ,它是 OutOfBounds 数组索引。

其次,我认为您的代码不能解决任务 - 例如,如果您计算的连续数字的数量出现在数组中,您只会打印结果。 但是我不明白这些事情应该如何相关。 您可以这样解决问题:

for (int i = 1; i < nums.length; i++) {
  if (nums[i-1] == nums[i] - 1) 
    counter+= 2;
  int j = i + 1;
  while (j < nums.length && nums[j] - 1 == nums[j-1]) {
    j++;
    counter++;
  i = j;
}
System.out.print("Consective amount is" + counter);

请注意,索引 i 从 1 开始,因此我们可以确定 nums[i-1] 存在。 如果 nums 只有一个元素,我们不应该遇到任何问题,因为条件i < nums.length不会被满足。 我们为序列的每个开始计算两个结果,为每个后续结果(while 循环)计算一个添加元素。 当序列结束时,我们尝试通过将索引 i 移动到最后一个序列的末尾 (j = i) 来找到它后面的新序列。

上面的代码将对多个不同的连续数字序列求和。 例如数组 [17,2,20,18,4,3] 有五个结果数(2,3,4 和 17,18)

该算法在 O(n) 内具有时间复杂性,因为我们将 i 或 j 至少增加 on 并在每个序列之后跳过 i 到 j。

我建议重新考虑您扫描阵列的方法。 理想情况下,您应该只需要一个 for 循环来解决这个问题。

我个人创建了一个 HashSet of Numbers,它不能包含重复项。 从那里,您可以从1迭代到nums.length-1 ,并检查nums[i] - 1 == nums[i-1] (即:它们是否是连续的)。 如果它们相等,您可以将两个数字添加到 HashSet。

最后,您实际上有一组连续数字,但是对于这个问题,您可以简单地返回该组的大小。

强烈建议你尝试这个问题并按照我的解释。 如果您只需要代码,这就是我想出的方法。

public static int countConsecutive(int[] nums) {
    Set<Integer> consecutive = new HashSet<>();

    if (nums.length <= 1)
        return 0;
    Arrays.sort(nums);

    for (int i = 1; i < nums.length - 1; i++) {
        if (nums[i] != nums[i - 1] + 1)
            continue;
        consecutive.add(nums[i]);
        consecutive.add(nums[i - 1]);
    }
    return consecutive.size();
}

这是另一种不需要排序的方法。 它使用一个位集。 和你的例子一样,是假设正数。

int[] values = {4, 3, 10, 11, 6, 1, 4, 8, 7};

根据值设置相应的位位置。

BitSet bits = new BitSet();
for (int i : values) {
    bits.set(i);
}

初始化 output 的一些值、起始位 position 和设置长度。

BitSet out = new BitSet();
int start = 0;
int len = bits.length();

现在遍历位集,找到占据相邻位置的位范围。 这些将表示填充原始 BitSet 时生成的连续序列。 仅显示两个或更多的序列。

while (start < len) {
    start = bits.nextSetBit(start);
    int end = bits.nextClearBit(start+1);
    if (start != end-1) {
        // populate the subset for output.
        out.set(start,end);
        System.out.println(out);
    }
    out.clear();
    start = end;
}

印刷

{3, 4}
{6, 7, 8}
{10, 11}

如果您只想要最大的计数,而与实际值无关,那就更简单了。 只需在初始化位集后使用它来代替上述内容。

int start = 0;
int len = bits.length();
int total = 1;
while (start < len) {
    start = bits.nextSetBit(start);
    int end = bits.nextClearBit(start + 1);
    total = Math.max(total, end-start);
    start = end;
}
System.out.println(total);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM