Problems with Strings

Ulf Wiger <>
Fri Mar 28 10:15:02 CET 2003


Raimo has given one answer. Here's a suggestion on how to
write your inversa/1 function in order to get the desired
effect. The common trick is to use an accumulator:

-module(demo).
-export([inversa/1]).

inversa(Str) ->
    inversa(Str, []).

inversa([], Acc) ->
    Acc;
inversa([H|T], Acc) ->
    inversa(T, [H|Acc]).



Eshell V5.2.3.1  (abort with ^G)

1> demo:inversa("abc").
"cba"
2>


The accumulator is often useful when writing list iterator
functions (if you don't want to use the map, fold et al in
lists.erl). The thing to bear in mind is that the
accumulator will be reversed at the end of the iteration. In
your case, it's what you want. The most common situation is:

iter(List, F) ->
  iter(List, F, Acc = []).

iter([H|T], F, Acc) ->
   iter(T, F, [F(H)|Acc]);
iter([], F, Acc) ->
   %% return the accumulator, after reversing it.
   lists:reverse(Acc).

Semantically, this is the same as

iter([H|T], F) ->
   [F(H)|iter(T,F)];
iter([], _) ->
   [].

But the former tends to be more efficient, despite the extra
reverse() at the end, because you make more efficient use of
the call stack.


As Raimo pointed out, lists:reverse("abc") is certainly the
most straightforward (and efficient!) way of reversing a
string.

Using lists:foldl/3 is a more contrived way:


2> lists:foldl(fun(Char,Acc) -> [Char|Acc] end, [], "abc").
"cba"

(That is, lists:foldl/3 with a function that only
"saves" each item works exactly like lists:reverse/1)

3> lists:foldr(fun(Char,Acc) -> [Char|Acc] end, [], "abc").
"abc"

(That is, lists:foldr/3 with the same function does not
produce a reversed list.)


The only point of showing this is to point out that there
are many ways to iterate over a list. Some approaches
naturally produce reversed output, while others don't.
The natural way to simply reverse a list is lists:reverse/1.


Hopefully, this didn't just increase your confusion. (:

/Uffe


On Fri, 28 Mar 2003, Pablo Dejuan wrote:

>Hi. I'm new in this and I have dificulties using strings. I
>tried to do an "inverese" function that should turn "bac"
>into "cab" but instead of this I get [98,[97,[99,[]]]]
>which I noticed that are tha Ascii codes for c, a, and b.
>
>Here is the code:
>inversa("") -> "";
>inversa([Ini|Cont]) -> Inv= inversa(Cont), [Ini,Inv].
>
>Thanks In Advance.
>
>

-- 
Ulf Wiger, Senior Specialist,
   / / /   Architecture & Design of Carrier-Class Software
  / / /    Strategic Product & System Management
 / / /     Ericsson AB, Connectivity and Control Nodes




More information about the erlang-questions mailing list