Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > C# (си шарп)
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 11.06.2016, 10:34   #1
Дима85
Пользователь
 
Регистрация: 11.06.2016
Сообщений: 20
По умолчанию Поиск повторяющихся чисел c#

Задачка сложная, сам не могу решить. Есть массив текстбоксов tb, в каждом из них есть, допустим, по 5 не повторяющихся чисел (не повторяющихся только для каждого бокса, а не для всех). Нужно по нажатию кнопки подсчитать во всех боксах САМУЮ ЧАСТО повторяющуюся, допустим, тройку чисел, вывести эти числа, например, в один лэйбл, а во втором лэйбле показать сколько раз эта тройка чисел повторяется, а если нету ничего, то вывести 0. Приведу пример для наглядности. Пять текстбоксов, в каждом введено по пять чисел, через пробел: 1 2 3 4 5, 1 2 3 6 7, 1 2 3 8 9, 15 16 17 18 19, 15 16 17 20 21. Здесь две повторяющиеся тройки чисел 1-2-3 и 15-16-17, но 1-2-3 выпадает чаще, чем другая, точнее 3 раза. Старался попроще привести пример. Понимаю, что задачка сложная, но надеюсь, что поможете. С кодом мне помогли, но он не работает. Вот код:
Код:
var arrays = new List<int[]>();
        arrays.Add(new int[] { 1,2,3,4,5});
        arrays.Add(new int[] { 1,2,3,6,7 });
        arrays.Add(new int[] { 1,2,3,8,9 });
        arrays.Add(new int[] { 15,16,17,18,19 });
        arrays.Add(new int[] { 15,16,17,20,21 });

        //create dictionary of fragments создать словарь фрагментов
        var count = new Dictionary<Fragment, int>();

        //enumerate all triples перечислить все тройки
        foreach(var arr in arrays)
        for(int i=0;i<arr.Length - 3;i++)
        {
            //create fragment создать фрагмент
            var f = new Fragment(arr[i], arr[i+1], arr[i+2]);
            //get and set count of same fragments получать и               устанавливать подсчет одинаковых фрагментов
            var c = 0;
            count.TryGetValue(f, out c);
            count[f] = c + 1;
        }
        //find max count найти максимальное количество
        var best = count.OrderByDescending(p => p.Value).First();

        //most frequently чаще всего
        Console.WriteLine("Тройка чисел: {0} Повторений: {1}", best.Key, best.Value);
....

class Fragment
{
    private int[] items;

    public Fragment(params int[] items)
    {
        this.items = items;
    }

    public override int GetHashCode()
    {
        var res = items[0];
        for (int i = 0; i < items.Length; i++)
            res ^= items[i];

        return res;
    }

    public override bool Equals(object obj)
    {
        var other = (Fragment)obj;

        for (int i = 0; i < items.Length; i++)
            if (items[i] != other.items[i])
                return false;

        return true;
    }

    public override string ToString()
    {
        return string.Join(",", items.Select(i=>i.ToString()).ToArray());
    }
}
Сначала консоль выдала правильно - тройки с числами 1 2 3 и повторений 3. Но потом я поменял числа на другие:
Код:
var arrays = new List<int[]>();
        arrays.Add(new int[] { 1, 10, 15, 20, 41 });
        arrays.Add(new int[] { 1, 9, 15, 14, 73 });
        arrays.Add(new int[] { 2, 1, 3, 15, 41 });
        arrays.Add(new int[] { 66, 15, 41, 55, 1 });
        arrays.Add(new int[] { 56, 15, 73, 4, 11 });
Здесь только одна тройка чисел, которая повторяется в этих пяти массивах - 1, 15, 41 и она повторяется 3 раза, это визуально можно проверить. Консоль мне выдала результат:
Код:
Тройка чисел: 1, 10, 15 Повторений: 1
Этот код не работает, вообще (((. Похоже он может сравнивать только первые три числа в каждом массиве. Подскажите, что не так в этом коде. Хотя, мне нужен код для Windows Forms, а не для консоли. Я вообще не вижу смысла работать с консолью, постоянно вводить кучу массивов и т.д. Проще сделать массив Textbox-ов, по нажатию кнопки перебрать все числа в боксах и результаты вывести в текст лейблов. Надеюсь, кто-нибудь поможет. Заранее огромное спасибо.
Дима85 вне форума Ответить с цитированием
Старый 11.06.2016, 10:49   #2
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Цитата:
Я вообще не вижу смысла работать с консолью, постоянно вводить кучу массивов и т.д.
Причем тут ввод? В текстбоксы тоже вводить надо. Но никто не мешает читать из файла, генерировать рандомно и т.п.
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 11.06.2016, 11:02   #3
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Код:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication4
{
    class Program
    {
        class Fragment
        {
            public int[] Data { get; private set; }
            public override string ToString()
            {
                return string.Join(", ", Data);
            }
            public Fragment(int[] data)
            {
                Data = data;
            }
        }
        static void Main(string[] args)
        {
            var arrays = new List<int[]>();
            arrays.Add(new int[] { 1, 2, 3, 4, 5 });
            arrays.Add(new int[] { 1, 2, 3, 6, 7 });
            arrays.Add(new int[] { 1, 2, 3, 8, 9 });
            arrays.Add(new int[] { 15, 16, 17, 18, 19 });
            arrays.Add(new int[] { 15, 16, 17, 20, 21 });
            var most = arrays.SelectMany(a =>
                {
                    var res = new Fragment[a.Length - 2];
                    for (int i = 0; i < a.Length - 2; i++)
                    {
                        res[i] = new Fragment(a.Skip(i).Take(3).ToArray());
                    }
                    return res;
                }).GroupBy(f => f.Data.ToString()).
                Select(g => new { Count = g.Count(), Key = g.Key, Fragment = g.First() }).
                OrderByDescending(g => g.Count).
                First().Fragment;
            Console.WriteLine(most);
        }
    }
}
не самое оптимизированное решение, но должно работать отлично
Цитата:
Проще сделать массив Textbox-ов, по нажатию кнопки перебрать все числа в боксах и результаты вывести в текст лейблов. Надеюсь, кто-нибудь поможет. Заранее огромное спасибо.
алгоритму пофиг откуда ему данные пришли.
просто консоль чаще проще в экспериментах.
а так хоть один текстбокс можно сделать.
кстати в общем алгоритм не зависит от количества элементов в одной строке.

PS: от класса Fragment можно избавится в принципе.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.

Последний раз редактировалось Пепел Феникса; 11.06.2016 в 11:08.
Пепел Феникса вне форума Ответить с цитированием
Старый 11.06.2016, 11:11   #4
Дима85
Пользователь
 
Регистрация: 11.06.2016
Сообщений: 20
По умолчанию

Спасибо за ответ, проверю.
Дима85 вне форума Ответить с цитированием
Старый 11.06.2016, 11:33   #5
Дима85
Пользователь
 
Регистрация: 11.06.2016
Сообщений: 20
По умолчанию

Результат тот же. Ввёл числа, которые я приводил во втором примере:
Код:
var arrays = new List<int[]>();
            arrays.Add(new int[] { 1, 10, 15, 20, 41 });
            arrays.Add(new int[] { 1, 9, 15, 14, 73 });
            arrays.Add(new int[] { 2, 1, 3, 15, 41 });
            arrays.Add(new int[] { 66, 15, 41, 55, 1 });
            arrays.Add(new int[] { 56, 15, 73, 4, 11 });
            var most = arrays.SelectMany(a =>
Консоль выдала 1, 10, 15. Код выдаёт первые три числа первого массива. Результат должен быть другой 1, 15, 41, можете сами проверить. Это три разных числа, которые попадаются вместе, в трёх массивах - в первом, третьем и четвёртом. Похоже эта задачка слишком сложная. Но всё равно спасибо за ответ.
P.S. Видно код может искать только 3 числа расположенные рядом и только в одном порядке, а не в разных местах и раскиданных рандомно.

Последний раз редактировалось Дима85; 11.06.2016 в 11:39.
Дима85 вне форума Ответить с цитированием
Старый 11.06.2016, 11:51   #6
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Код:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication4
{
    class Program
    {
        class Fragment
        {
            public int[] Data { get; private set; }
            public override string ToString()
            {
                return string.Join(", ", Data);
            }
            public Fragment(int[] data)
            {
                Data = data;
            }
        }
        static void Main(string[] args)
        {
            var arrays = new List<int[]>();
            arrays.Add(new int[] { 1, 10, 15, 20, 41 });
            arrays.Add(new int[] { 1, 9, 15, 14, 73 });
            arrays.Add(new int[] { 2, 1, 3, 15, 41 });
            arrays.Add(new int[] { 66, 15, 41, 55, 1 });
            arrays.Add(new int[] { 56, 15, 73, 4, 11 });
            var sorted = arrays.SelectMany(a =>
                {
                    var res = new List<Fragment>();
                    for (int i = 0; i < a.Length - 2; i++)
                        for (int j = i + 1; j < a.Length - 1; j++)
                            for (int k = j + 1; k < a.Length; k++)
                            {
                                var dat = new int[] { a[i], a[j], a[k] };
                                dat = dat.Distinct().OrderBy(v => v).ToArray();
                                if (dat.Length < 3)
                                    continue;
                                res.Add(new Fragment(dat));
                            }
                    return res;
                }).GroupBy(f => f.ToString()).
                Select(g => new { Count = g.Count(), Key = g.Key, Fragment = g.First() }).
                OrderByDescending(g => g.Count).ToArray();
            Console.WriteLine(sorted.First().Fragment);
        }
    }
}
еще опечатался случайно в первом коде
ToString надо было от f брать, а не от f.Data.

исправил опечатку и поправил для перебора всех вариантов.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.

Последний раз редактировалось Пепел Феникса; 11.06.2016 в 12:04.
Пепел Феникса вне форума Ответить с цитированием
Старый 11.06.2016, 12:05   #7
Дима85
Пользователь
 
Регистрация: 11.06.2016
Сообщений: 20
По умолчанию

Тройки никак не формируются. Массивов с числами может быть и штук 100. В каждом одинаковое количество разных не повторяющихся чисел и их вводит пользователь. Нужно просто выявить все комбинации троек чисел и сравнить их между собой и определить наибольшее количество повторяющихся. Тройки - это не обязательное требование, можно сравнивать и находить самые часто повторяющиеся пары чисел или допустим по четыре числа. Поэтому я и обращаюсь за помощью, так как самому это не решить, сложновато для новичка. )
Дима85 вне форума Ответить с цитированием
Старый 11.06.2016, 12:10   #8
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

ну я код предоставил.
он для троек, как вы и просили.

для произвольного количества чисел тоже в принципе можно сделать
Цитата:
Тройки никак не формируются.
Цитата:
Нужно просто выявить все комбинации троек чисел
вы уж определитесь
но я сделал все комбинации в пределах групп.
или нужно не по группам, а абсолютно везде?

там основное было это моя опечатка, в ином случае надо просто поменять способ формирования групп
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.

Последний раз редактировалось Пепел Феникса; 11.06.2016 в 12:12.
Пепел Феникса вне форума Ответить с цитированием
Старый 11.06.2016, 12:15   #9
Дима85
Пользователь
 
Регистрация: 11.06.2016
Сообщений: 20
По умолчанию

Числа сравниваются не в каждом массиве, а комбинации массивов между собой. Допустим, два массива с числами 1 2 3 4 и 1 2 3 5. В первом массиве комбинации из трёх чисел (троек) будут такие 1 2 3, 1 3 4, 1 2 4, 2 3 4, во втором 1 2 3, 1 3 5, 1 2 5, 2 3 5 (кстати 2 3 4 и 3 4 2 это одно и то же, только числа расположены в разных порядках). В обоих массивах есть одинаковая комбинация из 3 чисел - это 1 2 3, но они будут тоже одинаковы, даже если бы располагались так 1 2 3 и 2 3 1.

Мне самому не разобраться. Ладно, буду искать, может кто ещё поможет.

Последний раз редактировалось Пепел Феникса; 11.06.2016 в 13:04.
Дима85 вне форума Ответить с цитированием
Старый 11.06.2016, 12:20   #10
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

вообще то это и сделано. пост 6, а именно все комбинации троек в пределах одной группы берет.
я его начал обновлять до того как вы написали пост 7 просто.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.

Последний раз редактировалось Пепел Феникса; 11.06.2016 в 12:23.
Пепел Феникса вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Вывод случайных не повторяющихся чисел в Stringgrid Heng Помощь студентам 12 07.10.2012 16:59
Поиск повторяющихся символов RNR Общие вопросы Delphi 1 25.06.2012 02:43
Определение количества повторяющихся чисел в строке Tidus Microsoft Office Excel 11 13.12.2010 23:36
поиск повторяющихся элементов в матрице I_newbie Помощь студентам 2 15.03.2010 22:44
Поиск повторяющихся значений Flangini Microsoft Office Excel 23 22.02.2008 15:57