Лабораторна робота №7

Обробка рядків та файлів мовами функціонального програмування

Мета

Опанувати теоретичні основи обробки рядків та текстових файлів мовами функціонального програмування та розробити програми їх реалізації.

Виконав: студент групи ІПЗ-42
Лавріненко В.В.


Умова завдання

Варіант №14

Записати в текстовий файл n рядків тексту, що задаються програмою на функціональній мові програмування. Зчитати рядки із створеного програмою файлу, вивести їх на екран. Замінити слово з найбільшою кількістю голосних літер на послідовність цифр відповідно до довжині слова. Наприклад, знайдене слово "moloko", замінене слово "123456". Записати в новий текстовий файл результат обробки тексту.


Обгрунтування вибору середовища та мови функціонального програмування

Для розв'язку завдання було обрано мову Scheme та середовище DrRacket. Основними критеріями, за якими було зроблено вибір, є:

  • Наявність доволі великої кількості довідникових джерел інформації з синтаксису та поведінки даної мови. Це, в свою чергу, забезпечено й тим, що дана мова є діалектом розповсюдженої мови - LISP.

  • Відносна простота даної мови у засвоєнні, а середовища - використані, завдяки зрозумілому мінімалістичному користувацьому інтерфейсу, що надає найпоширеніший функціонал для написання та відлагоджування коду.


Структура програми (НІРО - діаграма)


Код програми

Завдання 14
#lang racket
; Лавріненко В.В.
; ІПЗ-42
; Л.р. 7, завдання 14

; функція, що визначає, чи є поточний символ голосною літерою 
(define (is-vowel char)  
  (cond
    [(eq? char #\a) #t]
    [(eq? char #\e) #t] 
    [(eq? char #\i) #t]
    [(eq? char #\o) #t]
    [(eq? char #\u) #t]
    [(eq? char #\y) #t]
    [else #f]
  )
)

; функція, що визначає кількість голосних у поточному слові
(define (count-vowels word current-count index)
  ; якщо за поточним індексом - голосна, збільшити лічильник на 1
  (cond [(and (< index (string-length word)) (is-vowel (string-ref word index)) )
         (count-vowels word (+ 1 current-count) (+ 1 index))
         ]
         ; якщо за поточним індексом - не голосна, розглянути наступний символ з незмінним лічильником 
        [(and (< index (string-length word)) (not (is-vowel (string-ref word index))))
         (count-vowels word current-count (+ 1 index))
         ]
        ; по закінченню слова повернути значення лічильника
        [else
         current-count]
  )
)

; функція для пошуку слова з найбільшою кількістю голосних у рядку
(define (find-maximum-vowel-word line index maximum-vowel-word)
  ; якщо за поточним індексом - слово з більшою кількістю голосних, ніж поточна, зберегти даний індекс і кількість голосних як поточні
  (cond [(and (< index (length line)) (> (count-vowels (list-ref line index) 0 0) (cdr maximum-vowel-word)) )
         (find-maximum-vowel-word line (+ 1 index) (cons index (count-vowels (list-ref line index) 0 0)))
         ]
        ; якщо за поточним індексом - слово не з більшою кількістю голосних, ніж поточна, не робити змін поточним значеннями
        [(and (< index (length line)) (not (> (count-vowels (list-ref line index) 0 0) (cdr maximum-vowel-word))))
         (find-maximum-vowel-word line (+ 1 index) maximum-vowel-word)
         ]
        ; по закінченню рядка повернути індекс та кількість голосних знайденого слова
        [else
         maximum-vowel-word]
  )
)

; функця створення підрядку з цифр заданої довжини
(define (create-number-string length [current-string ""])
  ; на кожній ітерації поточний рядок доповнюється нгаступною цифрою (залишком від ділення поточного числа на 10)
  (cond [(< (string-length current-string) length)
         (create-number-string length (string-append current-string (number->string (modulo (+ 1 (string-length current-string)) 10))))]
        [else
         current-string]
  )
)

; функція створення результуючого рядка
(define (create-modified-string line)
  (begin
    ; знаходження слова з найбільшою кількістю голосних
    (define maximum-vowel-word (find-maximum-vowel-word line 0 (cons 0 0)))
    ; знаходження кількості символів у вищезгаданому слові
    (define character-count (string-length (list-ref line (car maximum-vowel-word))))
    ; формування "слова" з послідовності цифр 
    (define number-string (create-number-string character-count))
    ; створення кінцевого рядка як списка з усіх слів до знайденого, слова з цифр і решти слів - після знайденого
    (define modified-string (append (take line (car maximum-vowel-word)) (list number-string) (list-tail line (+ 1(car maximum-vowel-word)))))
    modified-string
  )
)

(delete-file "E:\\FP-files\\output.txt")
(delete-file "E:\\FP-files\\output1.txt")

(define output-port-initial (open-output-file "E:\\FP-files\\input.txt"))
(write '(The preach like a lullaby) output-port-initial)
(write '(A dark shadow equals an apocalyptic catastrophe) output-port-initial)
(write '(Distressed at the future disaster) output-port-initial)
(write '(The whole world is a fireball) output-port-initial)
(close-output-port output-port-initial)

(display "The initial rows:\n")
(define in (open-input-file "E:\\FP-files\\input.txt"))
(define str1 (map symbol->string (read in)))
(display (string-join str1 " "))
(newline)
(define str2 (map symbol->string (read in)))
(display (string-join str2 " "))
(newline)
(define str3 (map symbol->string (read in)))
(display (string-join str3 " "))
(newline)
(define str4 (map symbol->string (read in)))
(display (string-join str4 " "))
(newline)
(close-input-port in)

(delete-file "E:\\FP-files\\input.txt")

(display "================================\n")
(display "The modified rows:\n")
(define str1-modified (create-modified-string str1))
(display (string-join str1-modified " "))
(newline)
(define str2-modified (create-modified-string str2))
(display (string-join str2-modified " "))
(newline)
(define str3-modified (create-modified-string str3))
(display (string-join str3-modified " "))
(newline)
(define str4-modified (create-modified-string str4))
(display (string-join str4-modified " "))
(newline)

(define output-port-result (open-output-file "E:\\FP-files\\output.txt"))
(write (map string->symbol str1-modified) output-port-result)
(write (map string->symbol str2-modified) output-port-result)
(write (map string->symbol str3-modified) output-port-result)
(write (map string->symbol str4-modified) output-port-result)
(close-output-port output-port-result)

(display "================================\n")
(display "The combined initial rows:\n")
(define str-combined (append str1 str2 str3 str4))
(display str-combined)
(newline)
(display "================================\n")
(display "The modified combination of rows:\n")
(define str-combined-modified (create-modified-string str-combined))
(display str-combined-modified)

(define output-port-result-combined (open-output-file "E:\\FP-files\\output1.txt"))
(write (map string->symbol str-combined-modified) output-port-result-combined)
(close-output-port output-port-result-combined)
					


Скріншоти результатів


Оцінка достовірності результатів

Правильність виконання задачі було перевірено для рядків:

  • The preach like a lullaby
  • A dark shadow equals an apocalyptic catastrophe
  • Distressed at the future disaster
  • The whole world is a fireball

При розгляді рядків окремо, слова, що в кожному з рядків мають найбільше голосних, - це "lullaby" (3 голосні), "apocalyptic" (5 голосних), "distressed" (3 голосні), "fireball" (3 голосні), відповідно. Їх слід замінити на рядки: "1234567", "12345678901", "1234567890", "12345678".

Водночас, якщо розглядати всі рядки як суцільний, найбільше голосних матиме слово "apocalyptic" - 5. І його слід замінити на рядок: "12345678901".

Як бачимо зі скріншоту результату роботи, для обох випадків кінцеві рядки мають очікуваний вигляд.


Висновки

В лабораторній роботі було реалізовано завдання, що передбачає маніпуляції з рядками, їх запис і зчитування з файлів.

В цілому, завдання є доволі тривіальним, щоправда труднощі виникли з розумінням умови завдання. Так, у ній зазначено, що необхідно замінити "слово", а не "слова" - через що невідомо, необхідно заміну робити в кожному окремому рядку чи у всіх, об'єднаних. Отже, було витрачено додатковий час на виконання обох варіантів умови.