Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.70/37: Рейтинг темы: голосов - 37, средняя оценка - 4.70
0 / 0 / 0
Регистрация: 08.08.2019
Сообщений: 26
1

Выборка всех подматриц матрицы

15.08.2019, 10:47. Показов 6890. Ответов 28
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте, такой вопрос:
У меня есть класс матриц, в котором прописана их обработка, различные операции над ними.
Не могу понять алгоритм для написания кода, чтобы программа проходила по этой матрице (двумерный массив в моем случае) m*n, находила все квадратные подматрицы и записывала их в новые двумерные массивы.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
15.08.2019, 10:47
Ответы с готовыми решениями:

Выделение подматриц из матрицы
Всем привет, не получается решить следующую задачу: допустим есть матрица X как в цикле...

Максимальное значение суммы всех элементов на множестве указанных подматриц
3.35***(Р). Даны квадратная матрица А порядка N и число K (K<N/2), где K и N - натуральные числа....

Заменить элементы матрицы суммой элементов соответствующих подматриц
Дана вещественная матрица A размером (m x n). Обозначим A'(i,j)-верхний левый угол матрицы A до i-й...

Алгоритм поиска возможного количества подматриц матрицы А 4x6
Есть матрица А - размером 4 на 6. Каким образом можно найти максимальное количество подматриц этой...

28
879 / 558 / 291
Регистрация: 21.11.2012
Сообщений: 1,553
15.08.2019, 11:46 2
egoreq,

вот, быстро накидал.. может и не самый оптимальный вариант, но вроде делает то, что вам нужно.. исходил из того, что минимальный размер квадратной матрицы 2х2

сделал в консольном приложении, у меня есть класс для работы с матрицами. оттуда вытащил вспомогательные функции для отображения и генерации матриц) это лишь для демонстрации:

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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
    public class Programm
    {
        static void Main(string[] args)
        {
            var matrix = Ext.Create(4, 5, 0, 10);
 
            matrix.Print();
 
            var list = new List<int[,]>();
 
            for(int i = 0; i < matrix.GetLength(0) - 1; i++)
            {
                for(int j = 0; j < matrix.GetLength(1) - 1; j++)
                {
                    var min = matrix.GetLength(0) - i;
                    if (matrix.GetLength(1) - j < min) min = matrix.GetLength(1) - j;
 
                    int[,] arr = new int[min, min];
 
                    for(int k = 0; k < min; k++)
                    {
                        for(int z = 0; z < min; z++)
                        {
                            arr[k, z] = matrix[i + k, j + z];
                        }
                    }
                    list.Add(arr);
                }
            }
 
            foreach (var arrs in list) arrs.Print();
 
            Console.ReadLine();
        }
    }
 
    public static class Ext
    {
        public static ConsoleColor Farbe = ConsoleColor.Red;
 
        /// <summary>
        /// Создает матрицу заданного размера и заполняет ее случайными значениями в заданном диапазоне
        /// </summary>
        /// <param name="rows">Количество строк матрицы</param>
        /// <param name="columns">Количество столбцов матрицы</param>
        /// <param name="minValue">Нижняя граница диапазона</param>
        /// <param name="maxValue">Верхняя граница диапазона</param>
        /// <returns></returns>
        public static int[,] Create(int rows, int columns, int minValue, int maxValue)
        {
            var random = new Random();
            var matrix = new int[rows, columns];
 
            for (int i = 0; i < rows; i++)
            {
                for (int j = 0; j < columns; j++)
                {
                    matrix[i, j] = random.Next(minValue, maxValue);
                }
            }
 
            return matrix;
        }
 
        /// <summary>
        /// Выводит массив на экран
        /// </summary>
        /// <typeparam name="T">Тип элементов матрицы</typeparam>
        /// <param name="matrix">Исходная матрица</param>
        /// <param name="coloredRow">Индекс строки, для выделения другим цветом</param>
        /// <param name="coloredColumn">Индекс столбца, для выделения другим цветом</param>
        public static void Print<T>(this T[,] matrix, int[] coloredRow = null, int[] coloredColumn = null)
        {
            var maxLength = matrix.MaxLength();
 
            for (int i = 0; i < matrix.GetLength(0); i++)
            {
                Console.Write("|");
 
                if (coloredRow != null && coloredRow.Contains(i)) Console.ForegroundColor = Farbe;
 
                for (int j = 0; j < matrix.GetLength(1); j++)
                {
                    if (coloredColumn != null && coloredColumn.Contains(j)) Console.ForegroundColor = Farbe;
 
                    var anz = maxLength - matrix[i, j].ToString().Length;
                    var l = "".PadRight(anz, ' ');
 
                    if (coloredRow != null && coloredColumn != null && !coloredRow.Contains(i) && coloredColumn.Contains(j)) Console.ResetColor();
 
                    Console.Write(" " + matrix[i, j] + l + " ");
                }
 
                Console.ResetColor();
                Console.Write("|\n");
            }
            Console.WriteLine();
        }
 
        /// <summary>
        /// Преобразует элементы массива в строки и определяет максимальную длину этих строк
        /// </summary>
        /// <typeparam name="T">Тип элементов матрицы</typeparam>
        /// <param name="matrix">Исходная матрица</param>
        /// <returns></returns>
        public static int MaxLength<T>(this T[,] matrix)
        {
            int max = int.MinValue;
 
            for (int i = 0; i < matrix.GetLength(0); i++)
            {
                for (int j = 0; j < matrix.GetLength(1); j++)
                {
                    if (matrix[i, j].ToString().Length > max) max = matrix[i, j].ToString().Length;
                }
            }
 
            return max;
        }
    }
1
Заблокирован
15.08.2019, 11:51 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
static void Print(int[,] a)
    {
        for (int i = 0; i < a.GetLength(0); i++)
        {
            for (int j = 0; j < a.GetLength(1); j++)
                Console.Write("{0,3}", a[i, j]);
            Console.WriteLine();
        }
        Console.WriteLine();
    }
    static List<int[,]> GetList(int[,] a)
    {
        int m = a.GetLength(0);
        int n = a.GetLength(1);
        int s = 2;//2*2
        List<int[,]> lA = new List<int[,]>();
        for (int i = 0; m - i >= s; i++)
            for (int j = 0; n - j >= s; j++)
                for (int h = s; i + h <= m && j + h <= n; h++)
                {
                    int[,] b = new int[h, h];
                    for (int k = i; k - i < h; k++)
                        for (int l = j; l - j < h; l++)
                            b[k - i, l - j] = a[k, l];
                    lA.Add(b);
                }
        return lA;
    }
    public static void Main()
    {
        int m = 3, n = 4;
        int[,] a = new int[m, n];
        for (int i = 0; i < m * n; i++)
            a[i / n, i % n] = i;
        Print(a);
        Console.WriteLine();
        List<int[,]> lA = GetList(a);
        foreach (int[,] b in lA)
        {
            Print(b);
            Console.WriteLine();
        }
2
879 / 558 / 291
Регистрация: 21.11.2012
Сообщений: 1,553
15.08.2019, 11:59 4
Лучший ответ Сообщение было отмечено Элд Хасп как решение

Решение

нашел маленький баг, не все матрицы охватывал.. чуть переделал:

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
static void Main(string[] args)
        {
            var matrix = Ext.Create(4, 5, 0, 10);
 
            matrix.Print();
 
            var list = new List<int[,]>();
 
            for(int i = 0; i < matrix.GetLength(0) - 1; i++)
            {
                for(int j = 0; j < matrix.GetLength(1) - 1; j++)
                {
                    var min = matrix.GetLength(0) - i;
                    if (matrix.GetLength(1) - j < min) min = matrix.GetLength(1) - j;
 
                    for(int m = 2; m <= min; m++)
                    {
                        var arr = matrix.GetSubMatrix(i, j, m);
                        list.Add(arr);
                    }
                }
            }
 
            foreach (var arrs in list) arrs.Print();
 
            Console.ReadLine();
        }
 
//ну и функция: GetSubMatrix:
 
public static int[,] GetSumMatrix(this int[,] matrix, int row, int col, int length)
        {
            var result = new int[length, length];
 
            for(int i = 0;i < length; i++)
            {
                for(int j = 0; j < length; j++)
                {
                    result[i, j] = matrix[row + i, col + j];
                }
            }
 
            return result;
        }
1
Эксперт .NET
17785 / 12936 / 3381
Регистрация: 17.09.2011
Сообщений: 21,211
15.08.2019, 12:07 5
Лучший ответ Сообщение было отмечено Элд Хасп как решение

Решение

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
static class MatrixExtensions
{
    public static IEnumerable<T[,]> EnumerateSquares<T>(this T[,] m)
    {
        int min = Math.Min(m.GetLength(0), m.GetLength(1));
        for (int w = 1; w < min; w++)
            for (int i = 0; i < m.GetLength(0) - w + 1; i++)
                for (int j = 0; j < m.GetLength(1) - w + 1; j++)
                {
                    T[,] z = new T[w, w];
                    for (int k = 0; k < w; k++)
                        for (int t = 0; t < w; t++)
                            z[k, t] = m[k + i, t + j];
                    yield return z;
                }
    }
 
    public static void Print(this int[,] m)
    {
        int max = m.Cast<int>().Max();
        int len = max == 0 ? 1 : (int)Math.Log10(max) + 1;
 
        var fmt = "{0," + len + "} ";
        for (int i = 0; i < m.GetLength(0); i++)
        {
            for (int j = 0; j < m.GetLength(1); j++)
                Console.Write(fmt, m[i, j]);
            Console.WriteLine();
        }
        Console.WriteLine();
    }
}
Использование:
C#
1
2
3
int[,] m = ...
foreach (var m1 in m.EnumerateSquares())
   m1.Print();
3
0 / 0 / 0
Регистрация: 08.08.2019
Сообщений: 26
15.08.2019, 12:16  [ТС] 6
Спасибо, сегодня попробую сделать.
0
0 / 0 / 0
Регистрация: 08.08.2019
Сообщений: 26
20.08.2019, 11:49  [ТС] 7
hamin, потестил ваш код, но есть проблема в том, что, например, возьмем матрицу 3*3, код отлавливает только матрицы с индексами (11,12,21,22), (12,13,22, 23) и еще 2 такие же матрицы, но он не отлавливает подматрицу, например с индексами (11, 13, 31, 33). Как это можно исправить. В общем проблема в том, что все ровно не все подматрицы видит

Добавлено через 31 минуту
Pvt, В вашем случае тоже, к сожалению, не все подматрицы отлавливает
0
Эксперт .NET
17785 / 12936 / 3381
Регистрация: 17.09.2011
Сообщений: 21,211
20.08.2019, 12:04 8
egoreq, с моим вариантом какие-то проблемы имеются?
0
Заблокирован
20.08.2019, 12:18 9
egoreq, и что же там не ловит?
0
0 / 0 / 0
Регистрация: 08.08.2019
Сообщений: 26
20.08.2019, 12:21  [ТС] 10
kolorotur, Ваш вариант пока еще не проверял
0
0 / 0 / 0
Регистрация: 08.08.2019
Сообщений: 26
20.08.2019, 12:24  [ТС] 11
Pvt, Например берем матрицу 3 на 3, вот такую подматрицу он не отловит, также не отловит матрицу (11, 13, 21, 23)
Извиняюсь за такие рисунки))
Миниатюры
Выборка всех подматриц матрицы  
0
Заблокирован
20.08.2019, 12:29 12
угу, и 11,12,13,21 не найдет
0
0 / 0 / 0
Регистрация: 08.08.2019
Сообщений: 26
20.08.2019, 12:30  [ТС] 13
kolorotur, В вашем случае аналогичная ошибка)
0
0 / 0 / 0
Регистрация: 08.08.2019
Сообщений: 26
20.08.2019, 12:34  [ТС] 14
Pvt, Такую и не должен найти, по моим представлениям, в случае с матрицей 3*3 должны быть такие подматрицы, а у Вас отлавливает только первые 4
Миниатюры
Выборка всех подматриц матрицы  
0
Эксперт .NET
17785 / 12936 / 3381
Регистрация: 17.09.2011
Сообщений: 21,211
20.08.2019, 12:40 15
Цитата Сообщение от egoreq Посмотреть сообщение
В вашем случае аналогичная ошибка
А, так не подряд идущие элементы и не рассматривались.
Потому да, такое искать не будет.
0
0 / 0 / 0
Регистрация: 08.08.2019
Сообщений: 26
20.08.2019, 12:43  [ТС] 16
kolorotur, Вот в этом то и заключается сложность, я не понимаю алгоритм решения задачи в общем виде, сам в голове могу у себя в частном виде перебрать 3*3 или 4*4, например, а вот общий алгоритм не понимаю
0
Эксперт .NET
17785 / 12936 / 3381
Регистрация: 17.09.2011
Сообщений: 21,211
20.08.2019, 13:28 17
egoreq, какие в принципе ограничения есть?

Вот такая подматрица считается правильной?
Название: m1.png
Просмотров: 102

Размер: 2.8 Кб

А такая?
Название: m2.png
Просмотров: 102

Размер: 2.9 Кб

Хотелось бы точные правила.

Добавлено через 44 секунды
Ого, знатно редактор покорежило! Вставил картинками.
0
0 / 0 / 0
Регистрация: 08.08.2019
Сообщений: 26
20.08.2019, 13:53  [ТС] 18
kolorotur, Думаю да, первый вариант рабочий, второй не прокатит
0
899 / 554 / 275
Регистрация: 26.11.2015
Сообщений: 1,758
Записей в блоге: 2
20.08.2019, 14:11 19
У меня тут был метод, вычисляющий все сочетания в массиве по заданной длине сочетания. Приспособил его для этой задачи.

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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
static void Main(string[] args)
        {
            int[,] arr = new int[5, 5]
                {
                    { 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 }
                };
 
            List<int[,]> res = GetSubSquareMatrix(arr).ToList();
 
        }
 
        static IEnumerable<T[,]> GetSubSquareMatrix<T>(T[,] arr)
        {
            int n = arr.GetLength(0);
            int m = arr.GetLength(1);
 
            int[] nIndxs = Enumerable.Range(0, n).ToArray();
            int[] mIndxs = Enumerable.Range(0, m).ToArray();
 
            for (int i = 2; i < Math.Min(n, m); i++)
            {
                foreach (var sub_N_Indxs in GetCombinations(nIndxs, i))
                {
                    foreach (var sub_M_Indxs in GetCombinations(mIndxs, i))
                    {
                        T[,] res = new T[i, i];
                        for (int k = 0; k < i; k++)
                        {
                            for (int j = 0; j < i; j++)
                            {
                                res[k,j] = arr[sub_N_Indxs[k], sub_N_Indxs[j]];  
                            }
                        }
                        yield return res;
                    }
                }
            }
        }
 
        /// <summary>
        /// Получение всех сочетаний из n (количество элементов массива arr) по k (combinationSize)
        /// </summary>
        static IEnumerable<T[]> GetCombinations<T>(T[] arr, int combinationSize)
        {
            if (arr == null || arr.Length == 0) yield break;
            if (combinationSize > arr.Length || combinationSize <= 0) throw new ArgumentException();
 
            T[] res = new T[combinationSize];
            int[] indxs = new int[combinationSize];
            for (int i = 0; i < combinationSize; i++)
                indxs[i] = i;
            res = indxs.Select(x => arr[x]).ToArray();
            yield return res;
            while (indxs[0] < arr.Length - combinationSize)
            {
                NextIndexes(indxs, arr.Length - 1);
                res = indxs.Select(x => arr[x]).ToArray();
                yield return res;
            }
        }
 
        /// <summary>
        /// Вычисляет индексы элементов, составляющих еще пока непройденную комбинацию
        /// </summary>
        /// <param name="arr">Массив с индексами</param>
        /// <param name="maxIndx">Максимальный возможный индекс</param>
        static void NextIndexes(int[] arr, int maxIndx)
        {
            for (int i = 0; i < arr.Length; i++)
            {
                int temp = arr.Length - 1 - i;
                if (arr[temp] < maxIndx - i)
                {
                    arr[temp]++;
                    for (int j = temp + 1; j < arr.Length; j++)
                    {
                        arr[j] = arr[j - 1] + 1;
                    }
                    break;
                }
            }
        }
Не мгновенно начинает выполняться уже после входного размера 10X10, так что на производительность не претендую)
0
0 / 0 / 0
Регистрация: 08.08.2019
Сообщений: 26
20.08.2019, 14:30  [ТС] 20
Toros1992, спасибо большое, но все еще не работает)). постараюсь сам посидеть поразбираться еще
0
20.08.2019, 14:30
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
20.08.2019, 14:30
Помогаю со студенческими работами здесь

В заданной матрице найти максимальную сумму элементов прямоугольной подматрицы среди всех возможных подматриц
Дан массив A. Необходимо найти с помощью функции максимальную сумму элементов прямоугольного...

Для заданной матрицы порядка N вывести на экран все пары квадратных подматриц порядка К
Даны целочисленная квадратная матрица А порядка N, где N - заданное натуральное число, и число К &lt;...

Выборка всех последних сообщений из всех диалогов
У меня есть таблица Message: Как мне выбрать все последние сообщения из диалогов. То есть из...

Выборка всех символов
Строка: { Любые символы:{ } }


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru