Форум программистов, компьютерный форум, киберфорум
F# .NET
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.55/11: Рейтинг темы: голосов - 11, средняя оценка - 4.55
3 / 3 / 2
Регистрация: 02.08.2014
Сообщений: 60
1

Разбиение списка по значению элемента

30.07.2016, 17:09. Показов 2285. Ответов 10
Метки нет (Все метки)

Доброе время суток!
Помогите с реализацией разбиения списка List по определенному элементу.

Например, у нас есть список [1,2,4,6,7,8,9,4,3,6,2]
И при использовании нашей функции относительно этого списка, мы получим списки [1,2,4] , [6,7,8,9,4], [3,6,2]
или такие [1,2], [4], [6,7,8,9], [4], [3,6,2]

Я себе представляю эту реализацию примерно такой

F#
1
2
3
4
5
let data = [1,2, 4 ,6,7,8,9, 4 ,3,6,2];
 
let listSplitter list splt = list1 |> List.map ( тут цикл с проверкой до первого элемента splt )
 
listSplitter data 4 |> printfn
Помогите с написанием функции условия для .map.
Либо, быть может, есть какие-то другие варианты реализации разбиения?
__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь
1
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
30.07.2016, 17:09
Ответы с готовыми решениями:

Удаление элемента списка по значению
Здравствуйте, доброго времени суток ... ... 5 -> - каким образом, подскажите пожалуйста! ... ...

Удаление элемента из двусвязного списка по значению
Есть такой код, который позволяет добавлять элементы в список и выводить, а мне нужно доделать еще...

Поиск элемента односвязного списка по значению поля (я в отчаянии.)
Сделал односвязный список и множество функций для него. Сама структура в виде: ФИО, должность,...

Предусмотреть вывод всех данных, поиск элемента двусвязного списка по заданному значению
Help me please!!! В динамической памяти создать двусвязный список из символов латинского алфавита....

10
5943 / 2274 / 668
Регистрация: 11.04.2015
Сообщений: 3,761
Записей в блоге: 43
30.07.2016, 20:06 2
Лучший ответ Сообщение было отмечено denis_32 как решение

Решение

F#
1
2
3
4
5
6
7
8
9
10
11
12
let data = [1; 2; 4; 6; 7; 8; 9; 4; 3; 6; 2];
 
let splitList i lst =
    let rec split item l acc  =
        let tfi = List.tryFindIndex (fun i -> i = item) l
        if tfi.IsSome
        then 
            split item (List.skip (tfi.Value + 1) l) (acc @[List.take (tfi.Value + 1) l])
        else
            acc @ [l]
    split i lst []
printfn "%A" (splitList 4 data)
1
Заблокирован
30.07.2016, 21:07 3
Лучший ответ Сообщение было отмечено denis_32 как решение

Решение

F#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
let data = [1;2;4;6;7;8;9;4;3;6;2]
 
let splitByValue value xs =
    let rec _splitBy acc nxs rest =
        match rest with 
        | [] -> 
            if nxs |> List.isEmpty then acc
            else nxs::acc
        | h::t when h = value -> 
            _splitBy ((h::nxs)::acc) [] t
        | h::t -> 
            _splitBy acc (h::nxs) t
 
    _splitBy [] [] xs
 
    |> List.map(List.rev)
    |> List.rev
 
data
|> splitByValue 2
|> printfn "%A"
https://dotnetfiddle.net/BtAPWc
1
3 / 3 / 2
Регистрация: 02.08.2014
Сообщений: 60
31.07.2016, 10:45  [ТС] 4
Спасибо большое за ответы) И еще один вопрос, функция мне возвращает список списков, верно? Как мне обратиться к каждому отдельному списку?
Вот например каждый элемент в списке несет в себе значение длины, и мне нужно посчитать суммарные длины каждого вложенного списка.
Мне следует как-то применять
Код
List.forall
?
0
5943 / 2274 / 668
Регистрация: 11.04.2015
Сообщений: 3,761
Записей в блоге: 43
31.07.2016, 11:09 5
Лучший ответ Сообщение было отмечено denis_32 как решение

Решение

Цитата Сообщение от denis_32 Посмотреть сообщение
Как мне обратиться к каждому отдельному списку?
Каждый отдельный список - это просто элемент другого списка, стало быть обращайся к нему так как обращался бы к элементу списка. Обычно их перебирают, "откусывая" самый верхний, хотя можно и по индексу, если есть необходимость.
Цитата Сообщение от denis_32 Посмотреть сообщение
Вот например каждый элемент в списке несет в себе значение длины, и мне нужно посчитать суммарные длины каждого вложенного списка
F#
1
printfn "%A" (List.map List.sum (splitList 4 data))
1
3 / 3 / 2
Регистрация: 02.08.2014
Сообщений: 60
31.07.2016, 12:09  [ТС] 6
Забавно как-то получилось с
Код
(List.map List.sum (splitList 4 data))
А можно уточнить, это выполняется как
List.map (mapping_function: List.sum) (list: splitList 4 data)
Или как List.map (mapping_function: List.sum (list: splitList 4 data) )

В первом варианте, получается мы оставляем List.sum без параметра, и используем его исключительно как функцию для модификации?
0
5943 / 2274 / 668
Регистрация: 11.04.2015
Сообщений: 3,761
Записей в блоге: 43
31.07.2016, 12:29 7
Цитата Сообщение от denis_32 Посмотреть сообщение
это выполняется как
List.sum передаестя как первый аргумент List.map. То есть мы применяем эту функцию к каждому элементу списка, а поскольку элементы сами являются списками, то в результате получаем список сумм списков, входящих в первоначальный список. Вычисление выполняется слева-направо.

Добавлено через 15 минут
Кстати, вот еще решение первоначальной задачи. Мне кажется, оно малость получше первого. Все-таки без конкатенаций списков, явной рекурсии и в одну строчку, хоть и длинную. ))
F#
1
2
let splitList i lst = 
    List.foldBack (fun t state -> if t = i then [t]::state else (t::(List.head state))::(List.tail state)) lst (if List.last lst = i then [] else [[]])
2
3 / 3 / 2
Регистрация: 02.08.2014
Сообщений: 60
31.07.2016, 12:55  [ТС] 8
Очень хорошее решение) А вот еще вопрос) Выше Вы написали, что обращение к элементам может быть перебором с откусыванием и по индексу.
По индексу это List.nth, а как реализуется перебором?
0
Заблокирован
31.07.2016, 13:01 9
denis_32, если вы хотите обращаться по индексу, то лучше использовать массив (Array), а не список.

Цитата Сообщение от denis_32 Посмотреть сообщение
а как реализуется перебором?
обычный рекурсивный обход.
1
5943 / 2274 / 668
Регистрация: 11.04.2015
Сообщений: 3,761
Записей в блоге: 43
31.07.2016, 13:02 10
Цитата Сообщение от denis_32 Посмотреть сообщение
а как реализуется перебором?
В любом руководстве по началу работы с языком или в документации по работе со списками есть примеры. Ну вот, например
Списки (F#)
Взять отсюда пример вычисления суммы списка
F#
1
2
3
4
let rec sum list =
   match list with
   | head :: tail -> head + sum tail
   | [] -> 0
Здесь весь список обходится поэлементно. Аналогичным образом можно находить нужный элемент или делать все что угодно.
Ну и соответственно, помимо обхода списка желательно максимально использовать существующие фукнции.
1
3 / 3 / 2
Регистрация: 02.08.2014
Сообщений: 60
31.07.2016, 13:07  [ТС] 11
Всё, разобрался) Очень благодарен за ответы)
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
31.07.2016, 13:07

Тема: Списки. (разбиение списка на два списка одинаковой длины)
Сдрасти. Прошу помочь решить следующую задачу. Буду очень благодарен. Написать программу...

Найти номер элемента в массиве, который наиболее близок по значению к среднему значению
Написать программу поиска среднего значения элементов заданного одномерного массива. Найти номер...

Задача на разбиение списка чисел на три списка
Определите предикат split(+Numbers,?Pozitives,?Negatives,?Zeroes) который разбивает список чисел...

Разбиение списка на два списка одинаковой длины
Помогите пожалуйста!!! НЕ оставьте в беде!!!!! Срочно нужна помощь!!!!!!!!!!!!!!!!! Написать...


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

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru