| Правила | Регистрация | Пользователи | Поиск | Сообщения за день | Все разделы прочитаны |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Как Извлечь из строки числа

Как Извлечь из строки числа

Ответ
Поиск в этой теме
Непрочитано 11.08.2008, 10:16 #1
Как Извлечь из строки числа
Kostinok
 
Инженер-электрик
 
Калининград
Регистрация: 13.10.2007
Сообщений: 151

Здравствуйте!
Пытаюсь извлечь из строки вещественные числа и сформировать из этих чисел список. Больше чем уверен, что так извлекать численные значения, как это сделал я недопустимо. Да и к тому же код неверен и "до конца" не работает.
К примеру, из строки (setq str "abc3.5dn8.056df9.3n93gh")
должен получиться результат rez -> (3.5 8.056 9.3 93.0)
Прошу подсказать как можно подкорректировать этот код:
Код:
[Выделить все]
(defun str_lst (str / i ziv)
  (setq i (strlen str))
  (while (> (strlen str)
		  (length (setq ziv (cons (substr str i 1) ziv))))
	  (setq i (1- i)))
  (progn
    (foreach item ziv
      (if
	(= 0.0 (atof item))
	(setq i (1+ i))
	(progn
	  (setq rez (cons (atof (substr str i)) rez))
	  (setq i (+ i (strlen (rtos (atof (substr str i))))))
	  (str_lst (substr str i))
	  )
	)
      )
    )
  )
Или как еще можно решить подобную задачку.
Заранее спасибо!
__________________
Можно сопротивляться вторжению армий, вторжению идей сопротивляться невозможно. /В. Гюго/

Последний раз редактировалось Kostinok, 11.08.2008 в 13:28.
Просмотров: 5883
 
Непрочитано 11.08.2008, 14:18
#2
CB

Конструирование в области нефтеразведки
 
Регистрация: 10.02.2006
Гомель
Сообщений: 321


Переделал немного из http://dwg.ru/f/showthread.php?t=15236&page=2 #28
Код:
[Выделить все]
(defun rec-pat (temp str /)
  (cond ((= str "")
  (if (/= temp "")
    (list temp)
  ) ;_ end of if
 )
 ((not (member (substr str 1 1)
        '("0" "1" "2" "3" "4" "5" "6" "7" "8" "9" ".")
       ) ;_ end of member
  ) ;_ end of not
  (if (/= temp "")
    (cons temp (rec-pat "" str))
    (rec-pat "" (substr str 2))
  ) ;_ end of if
 )
 (t
  (rec-pat (strcat temp (substr str 1 1))
    (substr str 2)
  ) ;_ end of rec-pat
 )
  ) ;_ end of cond
) ;_ end of defun
;;;(rec-pat "" "abc3.5dn8.056df9.3n93gh3.56") -> ("3.5" "8.056" "9.3" "93" "3.56")
CB вне форума  
 
Автор темы   Непрочитано 11.08.2008, 14:37
#3
Kostinok

Инженер-электрик
 
Регистрация: 13.10.2007
Калининград
Сообщений: 151


CB,
Спасибо огромное, работает!!!

Еще одна просьба пояснить работу лиспа
Если в своем лиспе я не понимаю в чем ошибка,
то в твоем не понимаю - его работу((((
Объясни пожалуйста.
__________________
Можно сопротивляться вторжению армий, вторжению идей сопротивляться невозможно. /В. Гюго/

Последний раз редактировалось Kostinok, 11.08.2008 в 15:02.
Kostinok вне форума  
 
Непрочитано 11.08.2008, 14:38
#4
Alaspher


 
Регистрация: 11.10.2004
e•burg
Сообщений: 755


Вариант:
Код:
[Выделить все]
(defun demo (str / demo-pars)
 (defun demo-pars (str / fel res)
  (if (= str "")
   (list "")
   (if (vl-string-position
        (ascii (setq res (demo-pars (substr str 2))
                     fel (substr str 1 1)
               )
        )
        "0123456789."
       )
    (cons (strcat fel (car res)) (cdr res))
    (cons "" res)
   )
  )
 )
 (mapcar (function (lambda (b) (atof b)))
         (vl-remove ""
                    (mapcar (function (lambda (a) (vl-string-trim "." a)))
                            (demo-pars (vl-string-translate "," "." str))
                    )
         )
 )
)
Alaspher вне форума  
 
Автор темы   Непрочитано 11.08.2008, 15:52
#5
Kostinok

Инженер-электрик
 
Регистрация: 13.10.2007
Калининград
Сообщений: 151


Alaspher,
Большое спасибо, все работает, но ->
Попытался разобраться с твоим кодом, но не понял что такое переменная res и какие значения в ней накапливаются.
Что ищет vl-string-position... Ведь если str нигде не переопределяется, то vl-string-position выдаст одно и тоже...
Не понял лисп, по причине своей безграмотности....
Я дал свои комментарии к твоему коду, пожалуйста поясни сам и подскажи где я не так тебя понял
Код:
[Выделить все]
(defun demo (str / demo-pars); Определили функцию demo, аргумент функции str, временная переменная demo-pars
 (defun demo-pars (str / fel res); Определили функцию demo-pars, аргумент функции str, временные переменные fel и res
  (if; Если->
    (= str ""); Пустая строка, то ->
    (list ""); Если правда -> Сформируй список из пустой строки ("")
    ;; Если строка не пустая (а у нас не пустая), то ->
    (if; Если ->
      (vl-string-position; Найди символ ->
;; (vl-string-position <код> <символ> [<начало> [<обратно>]])
	
        (ascii (setq res (demo-pars (substr str 2));; Назначь переменной res НЕПОНЯЛ ЧТО?
                     fel (substr str 1 1);; Назначь переменной fel первый символ строки str, к примеру "a"
               ); При записи (setq res (substr str 1) fel (substr str 1 1))
	       ; результат отобрался - "a"
	       ; -> Значит vl-string-position ищет код "a" (97) в строке->
        )
        "0123456789."; вот в этой строке
       ); Если строка "0123456789." содержит символ "a", то ->
    (cons; добавь к ->
      (strcat fel (car res)); Сцепленной строке fel и первого элемента из списка res ->
      (cdr res)); -> остаток списка res без первого элемента
    (cons "" res); Если строка "0123456789." НЕ содержит символ "a", то добавь к res ""
   ); End of IF
  ); End of IF
 ); End of DEFUN
 (mapcar (function (lambda (b) (atof b)))
         (vl-remove ""
                    (mapcar (function (lambda (a) (vl-string-trim "." a)))
                            (demo-pars (vl-string-translate "," "." str))
                    )
         )
 )
)
Жду ответа.
Заранее спасибо!
__________________
Можно сопротивляться вторжению армий, вторжению идей сопротивляться невозможно. /В. Гюго/

Последний раз редактировалось Kostinok, 11.08.2008 в 16:01.
Kostinok вне форума  
 
Непрочитано 11.08.2008, 16:13
#6
Alaspher


 
Регистрация: 11.10.2004
e•burg
Сообщений: 755


Kostinok
Собственно, один момент видимо оказался незнакомым - рекурсивный вызов, т.е. самовызов функции - demo-pars, остальные комментарии, вполне корректные. Добавлю свои комментарии комментариев зелёным.
Код:
[Выделить все]
(defun demo (str / demo-pars); Определили функцию demo, аргумент функции str, временная переменная demo-pars
;;; Имя внутренней функции помещено в локальные переменные, чтобы она существовала
;;; только в период работы основной функции, её можно определить, как самостоятельную,
;;; ничего по сути не изменится.
 (defun demo-pars (str / fel res); Определили функцию demo-pars, аргумент функции str, временные переменные fel и res
  (if; Если->
    (= str ""); Пустая строка, то ->
    (list ""); Если правда -> Сформируй список из пустой строки ("")
;;; Всё верно, в результате работы функции demo-pars строка обязательно выродится в ""
    ;; Если строка не пустая (а у нас не пустая), то ->
    (if; Если ->
      (vl-string-position; Найди символ ->
;; (vl-string-position <код> <символ> [<начало> [<обратно>]])
 
        (ascii (setq res (demo-pars (substr str 2));; Назначь переменной res НЕПОНЯЛ ЧТО?
;;; Собственно рекурсия - функция вызывает самою себя с аргументом обрезанным
;;; на один символ, а результат будет помещён в res, т.е. начнётся он, как раз с ("").
;;; Если следующим символом в строке будет цифра или точка, то...
                     fel (substr str 1 1);; Назначь переменной fel первый символ строки str, к примеру "a"
               ); При записи (setq res (substr str 1) fel (substr str 1 1))
           ; результат отобрался - "a"
           ; -> Значит vl-string-position ищет код "a" (97) в строке->
        )
        "0123456789."; вот в этой строке
       ); Если строка "0123456789." содержит символ "a", то ->
    (cons; добавь к ->
      (strcat fel (car res)); Сцепленной строке fel и первого элемента из списка res ->
      (cdr res)); -> остаток списка res без первого элемента
;;; ... значимый символ будет сцеплен с пустой строкой и помещён обратно в список
    (cons "" res); Если строка "0123456789." НЕ содержит символ "a", то добавь к res ""
   ); End of IF
  ); End of IF
 ); End of DEFUN
 (mapcar (function (lambda (b) (atof b)))
         (vl-remove ""
                    (mapcar (function (lambda (a) (vl-string-trim "." a)))
                            (demo-pars (vl-string-translate "," "." str))
                    )
         )
 )
)
Для наглядности лучше анализировать строку с конца.
Alaspher вне форума  
 
Непрочитано 11.08.2008, 20:51
#7
CB

Конструирование в области нефтеразведки
 
Регистрация: 10.02.2006
Гомель
Сообщений: 321


1. Для начала нужно как следует почитать здесь http://www.caduser.ru/cgi-bin/f1/board.cgi?t=25113OT
2. Далее приведу чуть упрощенный вариант ф-ции (rec-pat...)
Код:
[Выделить все]
(defun rec-pat (str temp)
  (cond
    ((= str "") (if (/= temp "") (list temp)))
    ((wcmatch (substr str 1 1) "[1234567890.]")
     (rec-pat (substr str 2) (strcat temp (substr str 1 1)))
    )
    (t (if (/= temp "")
        (cons temp (rec-pat str ""))
        (rec-pat (substr str 2) "")
       ) ;_ end of if
    )
  ) ;_ end of cond
) ;_ end of defun
3. Попытаюсь подробно объяснить как она работает (ну это как получиться...)
(REC-PAT "56a78b" "") -> ("56" "78")
Как это работает:
Код:
[Выделить все]
1. Вызываем ф-цию rec-pat с параметрами str = "56a78b" temp = ""
2. Первая проверка в cond : (= str "") -> nil т.к. str = "56a78b"
   Вторая проверка : (wcmatch (substr str 1 1) "[1234567890.]") т.е. есть ли первый символ строки str (это "5")
    в образце "[1234567890.]". Да есть -> T -> вызывается функция rec-pat с параметрами
    str = (substr str 2) т.е "6a78b" (без первого символа)
    temp = (strcat temp (substr str 1 1)) т.е (strcat "" "5") -> "5" 
    Итог первого самовызова (rec-pat "6a78b" "5").
3. Начинаем сначала
   Первая проверка в cond : (= str "") -> nil т.к. str = "6a78b"
   Вторая проверка : (wcmatch (substr str 1 1) "[1234567890.]") т.е. есть ли первый символ строки str (это "6")
    в образце "[1234567890.]". Да есть -> T -> вызывается функция rec-pat с параметрами
    str = (substr str 2) т.е "a78b" (без первого символа)
    temp = (strcat temp (substr str 1 1)) т.е (strcat "5" "6") -> "56" 
    Итог второго самовызова (rec-pat "a78b" "56").
4. Начинаем сначала
   Первая проверка в cond : (= str "") -> nil т.к. str = "a78b"
   Вторая проверка : (wcmatch (substr str 1 1) "[1234567890.]") т.е. есть ли первый символ строки str (это "a")
    в образце "[1234567890.]". Такого символа нет -> nil -> переходим к третьей проверке.
   Третья проверка : T -> всегда истина -> должно выполнится одно из условий ф-ции if
    (if (/= temp "")
     (cons temp (rec-pat str ""))
     (rec-pat (substr str 2) "")
    ) ;_ end of if
    Сюда мы подошли с параметрами str = "a78b" temp = "56" т.е. (/= temp "") истина ->
    выполняем (cons temp (rec-pat str "")). ЗАПОМНИМ эту строку, т.к. именно в ней формируется
    результат и к ней мы еще не раз вернемся: (cons "56" (rec-pat "a78b" "")). Второй аргумент
    ф-ции cons снова рекурсивный самовызов функции rec-pat с параметрами
    str = "a78b"
    temp = ""
    Или (rec-pat "a78b" "")
    Смотрим отличия от вызова в п.3 (rec-pat "a78b" "56")
5. Первая проверка cond nil
   Вторая проверка cond nil
   Третья проверка - выполнение условий ф-ции if
    (if (/= temp "")
     (cons temp (rec-pat str ""))
     (rec-pat (substr str 2) "")
    ) ;_ end of if
    Сюда мы подошли с параметрами str = "a78b" temp = "" т.е. (/= temp "") ложь ->
    выполняем (rec-pat (substr str 2) "") т.е. (rec-pat "78b" "").
6. Далее идет повторение п.1 и п.2 но с параметрами (rec-pat "78b" "")
    Итог (rec-pat "8b" "7").
7. Далее идет повторение п.1 и п.2 но с параметрами (rec-pat "8b" "7")
    Итог (rec-pat "b" "78").
8. Этот пункт идентичен п.4:
   Первая проверка cond nil
   Вторая проверка cond nil
   Третья проверка - выполнение условий ф-ции if
    (if (/= temp "")
     (cons temp (rec-pat str ""))
     (rec-pat (substr str 2) "")
    ) ;_ end of if
    Сюда мы подошли с параметрами str = "b" temp = "78" т.е. (/= temp "") истина ->
    выполняем (cons temp (rec-pat str "")) или в значениях (cons "78" (rec-pat "b" "")).
    Пришло время вспомнить строку (cons "56" (rec-pat "a78b" "")) (в п.4)
    Результат выполнения (rec-pat "a78b" "") есть (cons "78" (rec-pat "b" "")), значит
    можно записать (cons "56" (cons "78" (rec-pat "b" ""))).
    Снова идет самовызов (rec-pat "b" "")
8. Первая проверка cond nil
   Вторая проверка cond nil (нет такого символа)
   Третья проверка - выполнение условий ф-ции if
    (if (/= temp "")
     (cons temp (rec-pat str ""))
     (rec-pat (substr str 2) "")
    ) ;_ end of if
    Сюда мы подошли с параметрами str = "b" temp = "" т.е. (/= temp "") ложь ->
    выполняем (rec-pat (substr str 2) "") т.е. (rec-pat "" "").
9. Первая проверка в cond : (= str "") -> T т.к. str = "" -> проверка выполнение условий ф-ции if
    (if (/= temp "") (list temp))
    Т.к. temp = "" -> nil
    Опять вспоминаем строку (cons "56" (cons "78" (rec-pat "b" "")))
    Результат выполнения (rec-pat "b" "") есть nil , значит
    можно записать (cons "56" (cons "78" nil)) -> ("56" "78").
Все - ф-ция rec-pat завершила свою работу.
4. Ну и если пока не совсем понятна рекурсия, практически тоже самое с помощью WHILE
Код:
[Выделить все]
(defun test (str / temp res)
  (setq temp "")
  (while (/= str "")
    (if (wcmatch (substr str 1 1) "[1234567890.]")
      (setq temp (strcat temp (substr str 1 1)))
      (if (/= temp "")
 (setq res  (cons temp res)
       temp ""
 ) ;_ end of setq
      ) ;_ end of if
    ) ;_ end of if
    (setq str (substr str 2))
  ) ;_ end of while
  (reverse res)
) ;_ end of defun
;;;(test "123ab wer 45 sdf456 ab3.56rt7.9  a ")  -> ("123" "45" "456" "3.56" "7.9")

Последний раз редактировалось CB, 11.08.2008 в 23:02. Причина: Добавлен п.4
CB вне форума  
 
Автор темы   Непрочитано 12.08.2008, 08:00
#8
Kostinok

Инженер-электрик
 
Регистрация: 13.10.2007
Калининград
Сообщений: 151


Alaspher, CB,
ОГРОМНОЕ СПАСИБО!!!!!
Бегло ознакомился с пояснениями, что то начало наклевываться. Надо еще немного времени.
CB,
Цитата:
3. Попытаюсь подробно объяснить как она работает (ну это как получиться...)
Получилось очень подробно и грамотно!!! Все разжевал - осталось проглотить.)))
Спасибо за ссылку. Буду читать!!!

Теперь буду разбираться с рекурсиями.
(Если ->
возникнут вопросы... (а они возникнут) ->
надеюсь на вашу помощь.)))
__________________
Можно сопротивляться вторжению армий, вторжению идей сопротивляться невозможно. /В. Гюго/
Kostinok вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Как Извлечь из строки числа

Размещение рекламы
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
DwgRuLispLib: Генератор случайных чисел VVA Библиотека функций 16 11.03.2013 21:21
Вставка блока из командной строки, но с переопределением. Mikhail AutoCAD 2 25.03.2005 16:34
Извлечение значения параметра регистра отлиного от строки AleX Программирование 13 27.01.2005 18:06
Помогите вернуть окно командной строки Елена AutoCAD 1 23.09.2004 15:38