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

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

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль

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

Ответ
 
Опции темы Поиск в этой теме
Старый 02.03.2010, 23:37   #1
leest
Пользователь
 
Регистрация: 18.01.2008
Сообщений: 22
По умолчанию Лисп сопоставить

Доброго времени суток, всем! Подскажите пожалуйста, очень нужна помощь... Дана задача: Для представления римских цифр используются символы: I – один, V – пять, X – десять, L – пятьдесят, C – сто, D – пятьсот, M – тысяча. Для изображения числа с помощью римских цифр используются общеизвестные правила: так например
482 – CDLXXXII, 1999 – MCMXCIX. Напишите функцию (f R), которая переводит число R, запис-е римскими цифрами, в десятичную запись, например ( f’ (CDLXXXII))=482. Исходное число не превышает 1999.

Сам алгоритм я понял, что берется голова списка, сравнивается с хвостом, если голова по значению больше=> числа складываются, если меньше, соответственно, отнимаются. Например: CDLXXXII, берется С=сто, сравнивается с хвостом (хвост, рекурсивно опять проверяет, только теперь сравнивает D с остальным и т.д.) Как задать сопоставление букв с цифрами, в самом теле функции? Т.е. задается же список буквами, а мне надо сравнивать эти самые буквы (только в численном значении)... Заранее спасибо всем, кто заглянул!

P.S: язык программирования Лисп
leest вне форума Ответить с цитированием
Старый 03.03.2010, 00:07   #2
Sasha_Smirnov
Особый статус
Участник клуба
 
Аватар для Sasha_Smirnov
 
Регистрация: 24.11.2008
Сообщений: 1,535
По умолчанию Сапожник без сапог

А где взять компилятор лисп? (Может, в VBA сойдёт?)
Sasha_Smirnov вне форума Ответить с цитированием
Старый 03.03.2010, 00:47   #3
leest
Пользователь
 
Регистрация: 18.01.2008
Сообщений: 22
По умолчанию

ну я xLisp скачивал...старенький правада, но там большой разницы нету..
leest вне форума Ответить с цитированием
Старый 04.03.2010, 08:32   #4
Sasha_Smirnov
Особый статус
Участник клуба
 
Аватар для Sasha_Smirnov
 
Регистрация: 24.11.2008
Сообщений: 1,535
По умолчанию

В приложенном документе — запуск через Alt-F8.
Код:
Sub Romantica(): Dim roma() As Byte
Selection.HomeKey wdStory 'курсор - в начало документа'
Do
    With Selection
            
            With .Find
            .MatchWildcards = True
             .Text = "<[MmCcСсDdLlXxХхVv1Ii]{1;3}*>": .Execute
            If .Found = False Then MsgBox "В документе [больше] не найдено цифр, похожих на римские.", vbInformation: Exit Sub
            End With
        
    roma = .Text 'считали строку в байтовый массив'
    
        For i = LBound(roma) To UBound(roma) Step 2 'читаем по 2 байта слева направо и заменяем буквы - на цифры 1 2 3 4 5 6 7'
            Select Case roma(i)
            Case AscW("i"), AscW("I"), AscW("1"):  roma(i) = 1
            Case AscW("v"), AscW("V"):  roma(i) = 2
            Case AscW("x"), AscW("X"):  roma(i) = 3
            Case AscW("l"), AscW("L"):  roma(i) = 4
            Case AscW("c"), AscW("C"):  roma(i) = 5
            Case AscW("d"), AscW("D"):  roma(i) = 6
            Case AscW("m"), AscW("M"):  roma(i) = 7
            Case Else
                            MsgBox "Это вообще не римская цифра.": Exit Do
            End Select
        Next
    
        For i = UBound(roma) - 1 To LBound(roma) Step -2  'читаем римское число справа налево - и суммируем'
        MsgBox "roma(" & i & ") = " & roma(i), vbInformation '
            Select Case roma(i)
            Case 1:   arab = arab + 1: If i < UBound(roma) - 1 Then If roma(i) < roma(i + 2) Then arab = arab - 2
            Case 2:   arab = arab + 5: If i < UBound(roma) - 1 Then If roma(i) < roma(i + 2) Then MsgBox "См. порядок цифр!"
            Case 3:   arab = arab + 10: If i < UBound(roma) - 1 Then If roma(i) < roma(i + 2) Then arab = arab - 20
            Case 4:   arab = arab + 50: If i < UBound(roma) - 1 Then If roma(i) < roma(i + 2) Then MsgBox "См. порядок цифр!"
            Case 5:   arab = arab + 100: If i < UBound(roma) - 1 Then If roma(i) < roma(i + 2) Then arab = arab - 200
            Case 6:   arab = arab + 500: If i < UBound(roma) - 1 Then If roma(i) < roma(i + 2) Then MsgBox "См. порядок цифр!"
            Case 7:   arab = arab + 1000: If i < UBound(roma) - 1 Then If roma(i) < roma(i + 2) Then arab = arab - 2000
            End Select
        Next
        
    End With
        
    MsgBox arab, vbInformation
    arab = 0
Loop
End Sub
Вложения
Тип файла: doc MDCLat.doc (42.0 Кб, 10 просмотров)

Последний раз редактировалось Sasha_Smirnov; 05.03.2010 в 00:49. Причина: убрал вариант с русскими буквами (ХХ — не ха-ха, а всё-таки икс-икс), тем более такие «цифры», как ХШ.
Sasha_Smirnov вне форума Ответить с цитированием
Старый 04.03.2010, 08:44   #5
Utkin
Старожил
 
Аватар для Utkin
 
Регистрация: 04.02.2009
Сообщений: 17,351
По умолчанию

Цитата:
Сообщение от leest Посмотреть сообщение
Сам алгоритм я понял, что берется голова списка, сравнивается с хвостом, если голова по значению больше=> числа складываются, если меньше, соответственно, отнимаются. Например: CDLXXXII, берется С=сто, сравнивается с хвостом (хвост, рекурсивно опять проверяет, только теперь сравнивает D с остальным и т.д.) Как задать сопоставление букв с цифрами, в самом теле функции? Т.е. задается же список буквами, а мне надо сравнивать эти самые буквы (только в численном значении)... Заранее спасибо всем, кто заглянул!
Я бы не стал это делать в теле функции - это не по фень-шую. Составьте правильно список. Ну например - I V X 10 5 1
Теперь составьте функу, которая методом отсечения головы и хвоста находила бы такой хвост (нужная Вам цифра), который бы соответствовал бы Вашей букве .
Допустим Вам нужна буква V - смотрите голову, раз I значит откидываем из списка голову и хвост, если совпало, то читаем хвост. Думаю не очень сложно.
Маньяк-самоучка
Utkin появился в результате деления на нуль.
Осторожно! Альтернативная логика
Utkin вне форума Ответить с цитированием
Старый 05.03.2010, 15:54   #6
leest
Пользователь
 
Регистрация: 18.01.2008
Сообщений: 22
По умолчанию

спасибо большое, буду пробовать. а алгоритм, Саши Смирнова что-то не совсем понял... он видимо на другом компиляторе, увы, мне не знаком... Но за помощь, преогромнейшее спасибо!!!
leest вне форума Ответить с цитированием
Старый 05.03.2010, 18:31   #7
Sasha_Smirnov
Особый статус
Участник клуба
 
Аватар для Sasha_Smirnov
 
Регистрация: 24.11.2008
Сообщений: 1,535
По умолчанию

Всё же, если у вас есть Word, испытайте мой код. А то зря старался.

Алгоритм там прост: читаю справа налево — и прибавляю либо вычитаю (в зависимоcти от того, какая следующая) римскую цифру.

Если, например, число IX — прибавляем 10, а 1 — вычитаем (ибо за ним идёт 10, а 10 > 1).
Sasha_Smirnov вне форума Ответить с цитированием
Старый 08.03.2010, 12:59   #8
leest
Пользователь
 
Регистрация: 18.01.2008
Сообщений: 22
По умолчанию

ребята, подскажите пожалуйстаааа(( вот без, сопоставления римских числе и арабских, алгоритм получился вроде так:

(defun f (n)
(let ((a (reverse n)))
(cond
((null a) 0)
((> (first a) (f (rest a))) (- (first a) (f (rest a))))
(t (+ (first a) (f (rest a))))
))
)


но почему-то не всегда считает правильно... т.е. чтобы задать 482 = CDLXXXI, задаем в списке (100 500 50 10 10 10 1 1). что не правильно? заранее, спасибо
leest вне форума Ответить с цитированием
Старый 09.03.2010, 17:01   #9
leest
Пользователь
 
Регистрация: 18.01.2008
Сообщений: 22
По умолчанию

вот что получилось, без сопоставления:

(defun f (n)
(cond
((null n) 0)
((< (first n) (f (rest n))) (- (f (rest n)) (first n)))
(t (+ (first n) (f (rest n))))
)
)

единственное, что теперь надо, это заменить подряд идущие цифры на сумму этих цифр, например: 100 500 50 10 10 10 1 1 = 100 500 50 30 2, и тогда все будет считаться правильно. Подскажите пожалуйста, как это можно осуществить в лиспе.
leest вне форума Ответить с цитированием
Старый 09.03.2010, 23:13   #10
Sasha_Smirnov
Особый статус
Участник клуба
 
Аватар для Sasha_Smirnov
 
Регистрация: 24.11.2008
Сообщений: 1,535
По умолчанию

А нельзя сразу — суммировать? Замена видится мне лишней.

(Ну нет компилятора!)
Цитата:
Сообщение от leest Посмотреть сообщение
482 = CDLXXXI
Опечаточка!.. А вдруг они и в коде — как без копилятора проверить?
Sasha_Smirnov вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как сопоставить ячейки hunter05 Microsoft Office Excel 2 05.04.2009 14:37
Как сопоставить 2 файла exel? yasya22 Microsoft Office Excel 2 22.04.2008 22:48