LINUX.ORG.RU

Не могу преобразовать string

 ,


0

2
(defun f-F-a (product lst1 lst2)
  (if (eq (car lst1) nil)
 product
    (f-F-a (cons (message "%S * %S" (car lst1) (car lst2)) product) (cdr lst1) (cdr lst2))))

(f-F-a '() '("- F1" "+ F2" "- F3")  '("a1" "a2" "a3")) ;;=>
;;=> ("\"- F3\" * \"a3\"" "\"+ F2\" * \"a2\"" "\"- F1\" * \"a1\"") получилось
;;а хочется вот так
;;"- F3 * a3 + F2 * a2 - F1 * a1"
напишите кодом, как это можно сделать, пожалуйста.
(require 'subr)
Debugger entered--Lisp error: (error "Loading file /usr/share/emacs/27.1/lisp/subr.elc f...")
  require(subr)
(string-trim "f" "jdjjfjjj") => "f"
(string-trim "jdjjfjjj" "f") => "jdjjfjjj"
(string-trim-left "f" "jdjjfjjj") => "f"
(string-trim-right "jdjjfjjj" "f") => "jdjjfjjj"

Я нихрена не понял, что ты сказал, но ты достучался до сердца. Держи ответ от чатгпт:

Вам нужно преобразовать списки строк в отформатированную строку. Давайте разберемся с вашими требованиями:

Вы хотите умножить каждый соответствующий элемент из lst1 и lst2 (в смысле форматирования строки, а не числового умножения). Вы хотите, чтобы результирующая строка имела формат: "- F3 * a3 + F2 * a2 - F1 * a1"

Это можно сделать, используя рекурсивную обработку списка, как вы начали, но без использования функции message. Вместо этого вы можете форматировать строки и объединять их. Вот код, который должен выполнить то, что вы хотите:

(defun f-F-a (lst1 lst2)
  (if (or (null lst1) (null lst2))
      ""
    (let ((current (format "%s * %s" (car lst1) (car lst2)))
          (rest (f-F-a (cdr lst1) (cdr lst2))))
      (if (string-empty-p rest)
          current
        (format "%s %s" current rest)))))

(print (f-F-a '("- F1" "+ F2" "- F3")  '("a1" "a2" "a3")))

Теперь о вашей ошибке при попытке использовать require 'subr'. Модуль subr автоматически загружается в Emacs, и вам не нужно его явно подключать. Если вы хотите использовать функции для работы со строками, такие как string-trim, вы должны знать, что эти функции предоставляются библиотекой subr-x в Emacs, а не subr.

Чтобы использовать string-trim и связанные с ней функции, сделайте так:

(require 'subr-x)

Однако в предложенном выше решении эти функции не используются, так как они не нужны для достижения желаемого результата.

unC0Rr ★★★★★
()
Ответ на: комментарий от unC0Rr

За код спасибо! И стиль такой, которым, я наверное не смогу писать. И прочувствовать его мне время надо. Клаасс!

(require 'subr-x)

где-то прочитал, что с emacs 19 надо

(require 'subr)

saufesma
() автор топика
Последнее исправление: saufesma (всего исправлений: 2)
Ответ на: комментарий от unC0Rr

Не могли бы вы подсказать как разложить код пошагово

(defun f-F-a (lst1 lst2)
  (if (or (null lst1) (null lst2))
      ""
    (let ((current (format "%s * %s" (car lst1) (car lst2)))
          (rest (f-F-a (cdr lst1) (cdr lst2))))
      (if (string-empty-p rest)
          current
        (format "%s %s" current rest)))))

(print (f-F-a '("- F1" "+ F2" "- F3")  '("a1" "a2" "a3")))
попробовал разложить код пошагово
первый шаг
current => (format "%s * %s" (car lst1) (car lst2)) => "- F1 * a1"
rest => (f-F-a (cdr lst1) (cdr lst2)) => '("+ F2" "- F3")  '("a2" "a3")
(format "%s %s" current rest) => (format "%s %s" "- F1 * a1" '("+ F2" "- F3")  '("a2" "a3")) => "- F1 * a1 (+ F2 - F3)"
второй шаг
(format "%s * %s" (car "- F1 * a1 (+ F2 - F3)") (car '("a2" "a3"))) => format: Wrong type argument: listp, "- F1 * a1 (+ F2 - F3)"
тут я споткнулся. Где вот у меня ошибка? Я не вижу, а код работает, да ещё как.

saufesma
() автор топика
Последнее исправление: saufesma (всего исправлений: 2)
Ответ на: комментарий от saufesma

Давайте попробуем разобраться с кодом и вашим попыткой пошагового разбора.

Функция f-F-a берет два списка и создает строку, где элементы из двух списков множатся друг на друга (то есть объединяются через " * ").

Если хотя бы один из списков пустой, функция возвращает пустую строку.

Если оба списка не пусты, функция создает текущую строку current (объединение первых элементов двух списков с " * ") и рекурсивно вызывает себя для оставшихся частей списков (rest).

Теперь давайте разберемся с вашей попыткой:

Первый шаг: current: "- F1 * a1" rest: f-F-a для списков («+ F2» "- F3") и («a2» «a3») Но результатом rest будет строка, а не список. Поэтому в вашем разборе есть ошибка: rest вернет строку «+ F2 * a2 - F3 * a3», а не список («+ F2» "- F3").

Второй шаг: В этом шаге вы пытаетесь взять car от строки, что приводит к ошибке. На самом деле, второй шаг не требует отдельного вызова format, потому что внутри первого вызова f-F-a происходит рекурсивный вызов, который сам по себе обрабатывает оставшиеся элементы.

Итак, чтобы увидеть результаты промежуточных вычислений, можно добавить print в код:

(defun f-F-a (lst1 lst2)
  (if (or (null lst1) (null lst2))
      ""
    (let ((current (format "%s * %s" (car lst1) (car lst2)))
          (rest (f-F-a (cdr lst1) (cdr lst2))))
      (print (list 'current current))   ; печать текущего значения
      (print (list 'rest rest))         ; печать остатка
      (if (string-empty-p rest)
          current
        (format "%s %s" current rest)))))

(print (f-F-a '("- F1" "+ F2" "- F3")  '("a1" "a2" "a3")))

Если выполнить этот код, то вы увидите промежуточные значения для current и rest на каждом шаге рекурсии.

P.S.

На этом пробный период чатгпт для вас истёк :)

unC0Rr ★★★★★
()
Ответ на: комментарий от unC0Rr

Жаль, на самом интересном месте!

Эх, душа горит, не выдержал

Так как

На самом деле, второй шаг не требует отдельного вызова format, потому что внутри первого вызова f-F-a происходит рекурсивный вызов, который сам по себе обрабатывает оставшиеся элементы.

который сам по себе обрабатывает оставшиеся элементы.

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

saufesma
() автор топика
Последнее исправление: saufesma (всего исправлений: 1)