【问题标题】:How to extract longest consecutive sequence of integers from array in Java?如何从Java数组中提取最长的连续整数序列?
【发布时间】:2023-03-07 03:20:01
【问题描述】:

我想要显示ints 的给定数组中的所有连续序列。 最后我想用文字显示最长的

我尝试了什么

  • 我对数组进行了排序,找到了所有序列。
  • 我将找到的序列存储到一个新的 ArrayList 中。

下面只是一小段代码,因为我知道其余的都行不通:

int[] myArray = {202,203,204,205,206, 100, 1, 3, 200, 2, 4, 201, 5};
ArrayList<Integer> secuence = new ArrayList<>();
Arrays.sort(myArray);

for (int i = 0; i < myArray.length - 1; i++) {
  if ((myArray[i] + 1) == myArray[i + 1] || (myArray[i] - 1) == myArray[i - 1]) {
    secuence.add(myArray[i]);
  }
}

我尝试了很多不同的方法,但无法弄清楚。

【问题讨论】:

  • 能否请您 edit 您的帖子并添加结果输出您使用提供的示例(例如System.out.println(secuence)。也许if condition 中存在问题。

标签: java arrays integer sequence


【解决方案1】:

几点意见,建议:

  • sort() 按升序对数组进行排序,实际上您不必检查递减的元素
  • 要查找“任何”最接近的事物,您需要存储目前找到的“任何”最接近的事物以及当前候选对象。这也适用于查找最大元素或最长的连续元素序列
  • 为了处理数组的子部分,不需要制作元素的实际副本,存储开始索引和结束索引或长度就足够了。

把它们放在一起:

var myArray = [202,203,204,205,206, 100, 1, 3, 200, 2, 4, 201, 5];
myArray.sort((a,b)=>a-b);
console.log("Sorted array:",...myArray);

var longstart=0;
var longlength=0;

var currstart=0;
while(currstart<myArray.length){
  var currlength=0;
  while(currstart+currlength<myArray.length
    && myArray[currstart]+currlength==myArray[currstart+currlength])
    currlength++;
  if(currlength>longlength){
    longlength=currlength;
    longstart=currstart;
  }
  console.log("Sequence:",...myArray.slice(currstart,currstart+currlength));
  currstart+=currlength;
}
console.log("Longest:",...myArray.slice(longstart,longstart+longlength));

此代码是 JavaScript,因此可以在此处运行,Java 变体(只是打印较少)看起来非常相似:

int[] myArray = {202,203,204,205,206, 100, 1, 3, 200, 2, 4, 201, 5};
Arrays.sort(myArray);

int longstart=0;
int longlength=0;

int currstart=0;
while(currstart<myArray.length){
  int currlength=0;
  while(currstart+currlength<myArray.length
    && myArray[currstart]+currlength==myArray[currstart+currlength])
    currlength++;
  if(currlength>longlength){
    longlength=currlength;
    longstart=currstart;
  }
  currstart+=currlength;
}
for(int i=0;i<longlength;i++)
  System.out.print((i==0?"Longest: ":", ")+myArray[longstart+i]);

关键是让检查工作的距离越来越远,所以初始代码中固定的[i]+1==[i+1]检查变为[i]+distance==[i+distance]

【讨论】:

    【解决方案2】:

    我的解决方法如下:

    数据结构

    1. 连续的sequence我们想要找到的)是至少2连续的Integers(对)的List
    2. 要返回全部 foundSequences,您需要一个结果List 包含0 个或更多 Lists
    3. 要检查连续性,您需要currentprevious 元素

    算法

    应用逻辑(如果):

    1. 如果current == previous + 1连续性被发现,否则现有的连续序列被破坏
    2. 如果一个序列至少有 2 个元素,即sequence.size() &gt; 1,则应将其添加到结果列表中(即foundSequences
    3. first 元素之前和每个 broken 序列之后,previous == null
    4. last 元素之后可能有一个带有sequence.size() &gt; 1 的开放序列。如果是这样,那么这个序列没有被破坏,而是完整的并且应该被添加到结果列表中(即foundSequences

    迭代元素(循环):

    1. 使用 for-each 循环处理(已排序!)数组的所有元素
    2. for循环自动填充current元素(迭代变量)
    3. 您必须跟踪previous 元素(因此在循环之前初始化null)。它必须归档每个循环的当前元素,以便我们可以将下一个元素与它进行比较。
    4. 除非当前元素不再连续(发生中断),否则previous 将变为null 以开始新的收集。
    5. 如果出现中断,当前找到的序列可能会添加到结果中。然后需要将sequence 重置为null 以开始新的收集。
    6. 检查最后一个元素并结束循环后,可能还有一个序列(尚未中断)。这需要添加到结果中。 8.

    来源

    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    
    class ConsecutiveSequenceFinder {
    
        private int[] unsortedNumbers;
    
        public ConsecutiveSequenceFinder(int[] numbers) {
            this.unsortedNumbers = numbers;
        }
    
        public int[] sorted() {
            int[] sortedNumbers = Arrays.copyOf(this.unsortedNumbers, this.unsortedNumbers.length);
            Arrays.sort(sortedNumbers);
            return sortedNumbers;
        }
    
        public List<List<Integer>> findSequences() {
            // one sequence is List of integers; thus list of sequences is list of list of integers
            List<List<Integer>> foundSequences = new ArrayList<>();
            // first we sort the array
            int[] ascending = this.sorted();
            // this working variable will hold the currently found sequence
            List<Integer> sequence = new ArrayList<Integer>();
            Integer previous = null;
            System.out.println("Finding sequences ..");
            for (int current : ascending) {
                // check if current value is first or one more than (consecutive to) previous
                if (previous == null || current == previous + 1) {
                    sequence.add(current);
                    previous = current;
                } else {
                    System.out.printf("\tsequence of %d consecutive is broken at: %d\n", sequence.size(), current);
                    // if sequence found (at least a pair) then add
                    if (sequence.size() > 1) {
                        foundSequences.add(sequence);
                    }
                    // and finally prepare a new sequence, to collect fresh again
                    sequence = new ArrayList<>();
                    previous = null;
                }
            }
            // if sequence left, then add
            if (sequence.size() > 1) {
                System.out.printf("\tsequence of %d consecutive was completed with last array element\n", sequence.size());
                foundSequences.add(sequence);
            }
            return foundSequences;
        }
    
        public static void main (String[] args) throws java.lang.Exception {
            // demo numbers
            int[] values = {202,203,204,205,206, 100, 1, 3, 200, 2, 4, 201, 5};
            // starting demo
            System.out.println("Input: " + Arrays.toString(values));
            ConsecutiveSequenceFinder finder = new ConsecutiveSequenceFinder(values);
            System.out.println("Sorted: " + Arrays.toString(finder.sorted()));
            List<List<Integer>> foundSequences = finder.findSequences();
            System.out.println("Found sequences: " + foundSequences.size());
            // print for each sequence the size and its elements
            for (List<Integer> sequence : foundSequences) {
                System.out.printf("\t %d elements: %s\n",sequence.size(), sequence.toString());
            }
            // check for each sequence if it is the longest
            List<Integer> longestSequence = new ArrayList<>();
            for (List<Integer> sequence : foundSequences) {
                if (sequence.size() > longestSequence.size()) {
                    longestSequence = sequence;
                }
            }
            System.out.printf("Longest sequence has %d elements: %s\n",longestSequence.size(), longestSequence.toString());
        }
    }
    

    实际输出

    Input: [202, 203, 204, 205, 206, 100, 1, 3, 200, 2, 4, 201, 5]
    Sorted: [1, 2, 3, 4, 5, 100, 200, 201, 202, 203, 204, 205, 206]
    Finding sequences ..
        sequence of 5 consecutive is broken at: 100
        sequence of 7 consecutive was completed with last array element
    Found sequences: 2
         5 elements: [1, 2, 3, 4, 5]
         7 elements: [200, 201, 202, 203, 204, 205, 206]
    Longest sequence has 7 elements: [200, 201, 202, 203, 204, 205, 206]
    
    Process finished with exit code 0
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-19
    • 1970-01-01
    • 2015-03-21
    • 1970-01-01
    • 2021-06-23
    • 1970-01-01
    相关资源
    最近更新 更多