I am learning Lisp. I have implemented a common lisp function that merge two strings that are ordered alphabetically using recursion. Here is my code, but there is something wrong and I didn't figure it out.
(defun merge (F L)
(if (null F)
(if (null L)
F ; return f
( L )) ; else return L
;else if
(if (null L)
F) ; return F
;else if
(if (string< (substring F 0 1) (substring L 0 1)
(concat 'string (substring F 0 1) (merge (substring F 1 (length F)) L)))
(
(concat 'string (substring L 0 1) (merge F (substring L 1 (length L)) ))
))))
Edit : I simply want to merge two strings such as; inputs are string a = adf and string b = beg and the result or output should be; abdefg
Thanks in advance.
There were quite a few good answers, so why would I add one more? Well, the below is probably more efficient then the other answers here.
It is more efficient specifically in the sense of memory allocations - it only allocates enough memory to write the result string, never coerces anything (from list to string or from array to string etc.) It may not look very pretty, but this is because it is trying to do every calculation only once.
This is, of course, not the most efficient way to write this function, but programming absolutely w/o efficiency in mind is not going to get you far.
A recursive way to do it (fixed according to comment- other solutions can get an IF form as well).
Here's a iterative way to do it.
Note that these rely on building the string into a list of characters, then vectorizing it ( a string is a vector of characters).
You can also write a more C-esque approach...
Note that this one - unlike the other 2 - has side effects within the function. It also, imo, is more difficult to understand.
All 3 take varying numbers of cycles to execute on SBCL 56; each seems to take between 6K and 11K on most of my trials. I'm not sure why.
Using
string<
is an overkill,char<
should be used instead, as shown by Kaz. Recalculatinglength
at each step would make this algorithm quadratic, so should be avoided. Usingsort
to "fake it" makes it O(n log n) instead of O(n). Usingconcatenate 'string
all the time probably incurs extra costs of unneeded traversals too.Here's a natural recursive solution:
But, Common Lisp does not have a tail call optimization guarantee, let alone tail recursion modulo cons optimization guarantee (even if the latter was described as early as 1974, using "Lisp 1.6's
rplaca
andrplacd
field assignment operators"). So we must hand-code this as a loop:Judging by your comments, it looks like you're trying to use
if
with a series of conditions (like a series ofelse if
s in some other languages). For that, you probably want cond.I replaced that
if
withcond
and cleaned up some other errors, and it worked.Your test case came out as you wanted it to: