Как найти все подмассивы в массиве

An array is a linear data structure in which elements are stored in contiguous memory locations.

As per problem statement, we have to find all the subarrays of a given array. Subarrays are part or a section of an array. When we talk about all subarrays of an array, we talk about the total number of combinations that can be made using all the elements of the array without repeating.

Let’s explore the article to see how it can be done by using Java programming language.

To Show you Some Instances

Instance-1

Suppose we have the below array

[10, 2, 3, -5, 99, 12, 0, -1]

The subarrays of this array would be

10
10 2
10 2 3
10 2 3 -5
10 2 3 -5 99
10 2 3 -5 99 12
10 2 3 -5 99 12 0
10 2 3 -5 99 12 0 -1
2
2 3
2 3 -5
2 3 -5 99
2 3 -5 99 12
2 3 -5 99 12 0
2 3 -5 99 12 0 -1
3
3 -5
3 -5 99
3 -5 99 12
3 -5 99 12 0
3 -5 99 12 0 -1
-5
-5 99
-5 99 12
-5 99 12 0
-5 99 12 0 -1
99
99 12
99 12 0
99 12 0 -1
12
12 0
12 0 -1
0
0 -1
-1

Instance-2

Suppose we have the below array

[55,10,29,74]

The subarrays of this array would be

55
55 10
55 10 29
55 10 29 74
10
10 29
10 29 74
29
29 74
74

Algorithm

Algorithm-1

  • Step 1 − After storing the array, run a for loop from 0 to n. This will mark our starting point of the main array.

  • Step 2 − Run another for loop that runs from the first iterator to the ending point of the main array.

  • Step 3 − Now run another loop that traverses the elements between both two iterators.

  • Step 4 − Print the elements in a sequential order.

Algorithm-2

  • Step 1 − After storing the array, check if we have reached the end, then go out of the function.

  • Step 2 − If the start index is greater than the end index, then call the function itself from 0 to end+1.

  • Step 3 − Else print the array elements between the indices inside a for loop, and call the function again from start+1 to end.

  • Step 4 − Exit.

Syntax

To get the length of an array (number of elements in that array), there is an inbuilt property of array i.e length

Below refers to the syntax of it −

array.length

where, ‘array’ refers to the array reference.

You can use Arrays.sort() method to sort the array in ascending order.

Arrays.sort(array_name);

Multiple Approaches

We have provided the solution in different approaches.

  • By Using for Loops

  • By Using Recursion

Let’s see the program along with its output one by one.

Approach-1: By Using for Loops

In this approach, we will use three for loops to find the subarrays of an array. The first loop to mark the start and the second to mark the end of the subarray, while the third prints the subarray.

Example

import java.io.*;
public class Main {
   public static void main(String[] args) {
      
      // The array elements
      int arr[] = { 10, 2, 3, 99, 12, 0 };
      System.out.println("The subarrays are-");
      
      // For loop for start index
      for (int i = 0; i < arr.length; i++)
      
      // For loop for end index
      for (int j = i; j < arr.length; j++) {
      
         // For loop to print subarray elements
         for (int k = i; k <=j; k++)
            System.out.print(arr[k] + " ");
            System.out.println("");
      }
   }
}

Output

The subarrays are-
10 
10 2 
10 2 3 
10 2 3 99 
10 2 3 99 12 
10 2 3 99 12 0 
2 
2 3 
2 3 99 
2 3 99 12 
2 3 99 12 0 
3 3 99 3 99 12 3 99 12 0 
99 
99 12 
99 12 0 
12 12 0 
0 

Approach-2: By Using Recursion

In this approach, we find all the subarrays but using recursion.

Example

import java.io.*;
public class Main {
   //main method
   public static void main(String[] args) {
      // The array elements
      int arr[] = { 10, 2, 3};
      System.out.println("The subarrays are-");
         
      // Calling the recursive function
      printSubArrays(arr, 0, 0);
   }
   
   // Recursive FUnction to Find all the subarrays
   static void printSubArrays(int[] arr, int head, int tail) {
   
      // Exits the function if we have reached the end
      if (tail == arr.length)
         return;
      
      // Increases the first index and calls itself
      else if (head > tail)
         printSubArrays(arr, 0, tail + 1);
      
      // Print the subarray and then increases the first element index
      else {
         for (int i = head; i < tail; i++)
            System.out.print(arr[i] + " ");
         System.out.println(arr[tail]);
         printSubArrays(arr, head + 1, tail);
      }
      return;
   }
}

Output

The subarrays are-
10
10 2
2
10 2 3
2 3
3

In this article, we explored how to find all the subarrays of a given array by using Java programming language.

Это базовый алгоритм, но он в большинстве ситуациях будет работать за O(N) операций. Понять это можно через просмотр условия внутреннего цикла, до второй итерации будет очень редко доходить, а тем более до третий и далее.

Худший случай достигается при ситуации base = [1,1,1,1,1,1,1,1,1] find = [1,1,1,1]. Но вы думаете что есть алгоритм, который в такой ситуации сработает быстрее? Ну может быть и есть, но подобные ‘долгие’ ситуации очень редки, если брать все возможности ситуаций. И возможно даже если асимптотически такой алгоритм для таких ситуаций будет работать быстрее, то скорее всего из-за его сложности он будет работать медленнее на базовых ситуациях, что в результате сделает его медленнее в среднем. Вообщем я бы не стал дальше пытаться его оптимизировать.

var base = [1, 1, 1, 2, 3, 4, 5, 6, 1, 1, 2, 3, 1, 1, 2, 3];
var find = [1, 1, 2, 3];
var rez = [];
var yes;

var max = base.length - find.length;

for (var i = 0; i <= max; i++) {
  yes = true;

  for (var j = 0; j < find.length; j++) {
    if (base[i + j] != find[j]) {
      yes = false;
      break;
    }
  }

  if (yes) {
    rez.push(i);
  }
}

console.log(rez);

Обновлено

Для максимально быстрого поиска необходимо использовать конечные автоматы.

Смотрим алгоритм Ахо — Корасик.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import java.util.stream.Collectors;

import java.util.stream.IntStream;

class Main

{

    // Вспомогательная функция для вставки <key, value> пара в multimap

    private static<K, V> void insert(Map<K, List<V>> hashMap, K key, V value)

    {

        // если ключ виден в первый раз, инициализируем список

        hashMap.putIfAbsent(key, new ArrayList<>());

        hashMap.get(key).add(value);

    }

    // Вспомогательная функция для печати подмассива `nums[i, j]`

    public static void printSubarray(int[] nums, int i, int j)

    {

        System.out.println(IntStream.range(i, j + 1)

                                    .mapToObj(k -> nums[k])

                                    .collect(Collectors.toList()));

    }

    // Функция поиска подмассивов с заданной суммой в массиве

    public static void printAllSubarrays(int[] nums, int target)

    {

        // создаем карту для хранения конечного индекса всех подмассивов с

        // сумма элементов на данный момент

        Map<Integer, List<Integer>> hashMap = new HashMap<>();

        // Для обработки случая, когда начинается подмассив с заданной суммой

        // с 0-го индекса

        insert(hashMap, 0, 1);

        int sum_so_far = 0;

        // обход заданного массива

        for (int index = 0; index < nums.length; index++)

        {

            // сумма элементов на данный момент

            sum_so_far += nums[index];

            // проверяем, существует ли хотя бы один подмассив с заданной суммой

            if (hashMap.containsKey(sum_so_far target))

            {

                List<Integer> list = hashMap.get(sum_so_far target);

                for (Integer value: list) {

                    printSubarray(nums, value + 1, index);

                }

            }

            // вставляем пару (на данный момент, текущий индекс) в карту

            insert(hashMap, sum_so_far, index);

        }

    }

    public static void main (String[] args)

    {

        int[] nums = { 3, 4, 7, 1, 3, 3, 1, 4 };

        int target = 7;

        printAllSubarrays(nums, target);

    }

}

SVD102

1 / 1 / 1

Регистрация: 12.10.2015

Сообщений: 207

1

Найти подмассив в массиве

29.10.2015, 12:59. Показов 22375. Ответов 6

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

Надо найти в массиве не один элемент, а целый подмассив! Если подмассив найден в массиве, то вернуть нужно минимальный индекс, с которого начинается подмассив в исходном массиве. Например, поиск подмассива «3,4» в массиве «1,2,3,4,3,4» должен вернуть 2. Не могу придумать алгоритм.(

Добавлено через 19 минут

C#
1
2
3
4
5
6
public static int FindSubarrayStartIndex(int[] array, int[] subArray)
{
    for (int i = 0; i < array.Length - subArray.Length + 1; i++)
        if (ContainsAtIndex(array, subArray, i)) return i;
    return -1;
}

Нужно дописать функцию ContainsAtIndex(array, subArray, i)



0



Programming

Эксперт

94731 / 64177 / 26122

Регистрация: 12.04.2006

Сообщений: 116,782

29.10.2015, 12:59

Ответы с готовыми решениями:

Найти в массиве подмассив 3 х 3, сумма элементов которого максимальна
Всем Доброго времени суток, у меня возникла проблема с лабораторной работой, помогите пожалуйста,…

В массиве чисел найти подмассив длины m с максимальной суммой
Ребят помогите.
В массиве чисел найти подмассив длины m с максимальной суммой. Запрещается…

Выделить подмассив в двумерном массиве
Здравствуйте, формучане!

Значит, имеется массив
string array = new string {{&quot;a&quot;,&quot;b&quot;,&quot;c&quot;},…

В массиве чисел найдите самый длинный подмассив из одинаковых чисел
Помогите делать задание, пожалуйста: в массиве чисел найдите самый длинный подмассив из одинаковых…

6

Даценд

Эксперт .NET

5863 / 4740 / 2940

Регистрация: 20.04.2015

Сообщений: 8,361

29.10.2015, 14:06

2

Лучший ответ Сообщение было отмечено Памирыч как решение

Решение

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public static int FindSubarrayStartIndex(int[] array, int[] subArray)
{
    int index = -1;
    for (int i = 0; i < array.Length - subArray.Length + 1; i++)
    {
        index=i;
        for (int j = 0; j < subArray.Length; j++)
        {
            if (array[i + j] != subArray[j])
            {
                index = -1;
                break;
            }
        }
        if (index >= 0) 
            return index;
    }
    return -1;
}



3



Komaryan

16 / 16 / 10

Регистрация: 23.03.2010

Сообщений: 103

29.10.2015, 14:33

3

Лучший ответ Сообщение было отмечено Памирыч как решение

Решение

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] array = { 1, 6, 2, 3, 4, 3, 4 };
            int[] subarray = { 3, 4, 9 };
            Matrix mt = new Matrix();
            int i = mt.IndexArr(array, subarray);
            if (i > -1)
            {
                Console.WriteLine(Convert.ToString(i));
            }
            else
            {
                Console.WriteLine("Not found");
            }
            Console.ReadLine();
        }
  
    }
 
    public class Matrix
    {
        public int IndexArr(int[] array, int[] subarray)
        {
            int index = 0;
            int count = 0;
            for (int i = 0; i < array.Length; i++)
            {
                if (array[i] == subarray[count])
                {
                    count++;
                }
                else
                {
                    count = 0;
                }
                if (count == subarray.Length)
                {
                    index = i - count + 1;
                    return index;
                }
            }
            return -1;
        }
    }
}



0



Bein

0 / 0 / 0

Регистрация: 17.09.2016

Сообщений: 99

25.09.2016, 15:44

4

Даценд, а как создать отдельный метод ContainsAtIndex, то есть как оформить метод, чтобы след код был корректен?

C#
1
2
3
4
5
6
public static int FindSubarrayStartIndex(int[] array, int[] subArray)
{
    for (int i = 0; i < array.Length - subArray.Length + 1; i++)
        if (ContainsAtIndex(array, subArray, i)) return i;
    return -1;
}

То есть нам нужен еще один метод ContainsAtIndex, чтобы в нем был алгоритм поиска подмассива в массиве. Как это сделать?



0



Даценд

Эксперт .NET

5863 / 4740 / 2940

Регистрация: 20.04.2015

Сообщений: 8,361

25.09.2016, 16:08

5

Bein,
Метод FindSubarrayStartIndex из сообщения #2 ищет индекс без использования дополнительного метода ContainsAtIndex.
Если же нужен именно отдельный метод, вызываемый из FindSubarrayStartIndex, то вот он:

C#
1
2
3
4
5
6
7
8
9
10
11
static bool ContainsAtIndex(int[] array, int[] subArray, int index)
{
    for (int j = 0; j < subArray.Length; j++)
    {
        if (array[index + j] != subArray[j])
        {
            return false;
        }
    }
    return true;
}



3



afront

1493 / 1208 / 821

Регистрация: 29.02.2016

Сообщений: 3,597

25.09.2016, 16:09

6

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication
{
 
    static class ArrayExtensions
    {
        public static IEnumerable<int> StartingIndex(this int[] x, int[] y)
        {
            IEnumerable<int> index = Enumerable.Range(0, x.Length - y.Length + 1);
            for (int i = 0; i < y.Length; i++)
            {
                index = index.Where(n => x[n + i] == y[i]).ToArray();
            }
            return index;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            int[] x = { 1, 2, 3, 4};
            int[] y = { 3, 4 };
            foreach (int i in x.StartingIndex(y))
            {
                Console.WriteLine(i);
            }
        }
    }
}



0



Ren Trapnest

36 / 34 / 13

Регистрация: 03.06.2010

Сообщений: 215

12.12.2017, 14:11

7

SVD102,

C#
1
2
3
4
5
6
7
        private static bool ContainsAtIndex(int[] array, int[] subArray, int i)
        {
            foreach (var element in subArray)
                if (array[i] != element) return false;
                else i++;
            return true;
        }



0



Как эффективно найти все возможные подмассивы массива?

5 ответов

Лучший ответ

Подмассив массива A равен A[i..j], где 0 <= i <= j < n, где n — длина массива.

На языке C это можно рассчитать так:

#include <stdio.h>

int main(){
    int A[] = {1,2,3,4,5};
    int len=sizeof(A)/sizeof(int);
    for( int i=0; i<len; i++ ){
        for( int j=i; j<len; j++ ){   // Now A[i..j] is the subarray
            for( int k=i; k<=j; k++ )
                printf("%d ", A[k]);
            printf("n");
        }
    }
    return 0;
}


4

Ankit Vallecha
29 Сен 2019 в 15:15

Возьмите первый элемент. У вас есть первый подмассив. У вас есть второй элемент? Добавьте и этот, вот и второй. Если есть третий, добавьте его и так далее. Мы делаем это до тех пор, пока не получим последний подмассив, который технически представляет собой весь массив размера n. Но теперь мы возвращаемся на две позиции назад и пропускаем элемент n-1, и вы добавляете n-й элемент … вы получаете новый подмассив.

Обратите внимание, как это включает в себя включение некоторых элементов, но пропуск других. Угадайте, рекурсия — это именно то, что вам нужно. Постройте постепенно, пропуская элементы после того, как они были использованы (и есть другие, которые можно использовать).

< Сильный > псевдокод :

Array x;
collection SubArrays= {0}
SubArrays.AddSubArrays(x,0);

collection AddSubArrays(array, init,next){
 if(next>array.limit){
  return {0};
 }
 collection c.Add(array[init]
 while return not {0}
 i=init+1;
 while return not {0}
 c.AddSubArrays(array,init+1,i)
 i= i+1
 endwhile
 return c
}


4

Neeraj Kumar
26 Окт 2017 в 12:02

Мы можем использовать функцию substr, чтобы найти все возможные подмассивы.

Фрагмент кода:

       #include<bits/stdc++.h>
       using namespace std;


       void generateSubstring(string str)
       {
            if(str.size()==0)
            {
                return;
            }
            else
            {
                for(int i=0; i<str.size(); i++)
                {
                    for(int j=1; j<=str.size()-i; j++)
                    {
                        cout<<str.substr(i, i+j)<<endl;
                    }
                }
            }
        }


        int main()
        {
            ios::sync_with_stdio(false);
            string str;
            getline(cin, str);
            generateSubstring(str);
            return 0;
        }


3

rashedcs
8 Июл 2017 в 13:13

Попробуйте следующий код:

def subarray(a, n) :
      for i in range(0,n):
             for j in range(i, n) :
                   for k in range(i, j+1) :
                          print(a(k), end=" ")
                   print("n", end=" ")
a=[1, 2,3,4,5]
n=len(a)
print( all non - empty subarrays are:-)
subarray(a, n) 


2

Subhodeep Chandra
27 Дек 2019 в 12:09

В JavaScript

function subarray(arr){
  let sub = []
  for(let i=0;i<=arr.length-1;i++){
    for(let j=arr.length-1;j>=i;j--){
      sub.push(arr.slice(i,j+1))
    }
  }
  return sub
}


0

David Buck
6 Июн 2020 в 18:32

Понравилась статья? Поделить с друзьями:

Не пропустите также:

  • Как найти абонента его местоположение по телефону
  • Как найти длину ребра ромба
  • Как найти выход хлеба
  • Как найти площадь всех граней куба формула
  • Онк 160 ошибка е55 как исправить

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии