erlang - is there a way of removing characters in a sentence without using string?

I am trying to remove characters in a sentence without using the string module. For example "I want to remove characters" and I want to remove all "e" appearing in the sentence and also count how many "e" I removed.

I have done it using strings and the code is as follows:

-module(remove_count_characters).
-export([remove/2, count/2]).

remove(Sentence, Words)
->
string:split(Sentence, Words, trailing)
.

count(Sentence, Words) 
->
erlang:length(string:split(Sentence, Words, all)) - 1
.

Upvotes: 2

Views: 620

Answers (3)

alking
alking

Reputation: 91

i suggest you using list operations like below:

% remove("abcde",[],0) = {"abcd",1}

remove([],Acc,Total) -> {lists:reverse(Acc),Total};
remove([$e|L],Acc,Total) -> remove(L,Acc,Total +1 );
remove([E|L],Acc,Total ) -> remove(L,[E|Acc],Total).

Upvotes: 0

7stud
7stud

Reputation: 48599

I want to remove all "e" appearing in the sentence and also count how many "e" I removed.

Remember that in erlang a double quoted string is actually a list containing the ascii codes(integers) of the characters in the double quoted string:

1> "abc" == [97, 98, 99].
true

Using recursion with a couple of accumulator variables:

remove(TargetStr, Str) ->
    remove(TargetStr, Str, _NewStr=[], _Count=0).

remove(_TargetStr, _Str=[], NewStr, Count) -> %when there are no more characters left in Str
    {lists:reverse(NewStr), Count};
remove([Char]=TargetStr, _Str=[Char|Chars], NewStr, Count) -> %when Char matches the first character in Str
    remove(TargetStr, Chars, NewStr, Count+1);
remove(TargetStr, _Str=[Char|Chars], NewStr, Count) -> %when the other clauses don't match, i.e. when Char does NOT match the first character in Str
    remove(TargetStr, Chars, [Char|NewStr], Count).

In the shell:

57> a:remove("e", "I want to remove characters").
{"I want to rmov charactrs",3}

Using lists:foldr/3:

remove([TargetChar]=_TargetStr, Str) ->
    Remover = fun(Char, _AccIn={NewStr, Count}) when Char==TargetChar ->
                     _AccOut={NewStr, Count+1};
                 (Char, _AccIn={NewStr, Count}) when Char=/=TargetChar ->
                     _AccOut={[Char|NewStr], Count} 
              end,
    lists:foldr(Remover, _InitialAcc={_NewStr=[], _Count=0}, Str).

Upvotes: 2

vkatsuba
vkatsuba

Reputation: 1449

I suppose you can try use re:replace/3. Eg:

1> re:replace("Replaze", "z", "c", [global, {return, list}]). 
"Replace"
2> 1> re:replace("Remove word", "Remove ", "", [global, {return, list}]).
"word"

Also you can try to use list generators, eg for remove e you can try do something like:

1> [X || X <- "eeeaeeebeeeceee", X =/= $e].
"abc"

And calculate how many e was removed with getting result can looks like:

1> List = "eeeaeeebeeeceee".
"eeeaeeebeeeceee"
2> Result = [X || X <- "eeeaeeebeeeceee", X =/= $e].
"abc"
3> {Result, Count} = {Result, length(List -- Result)}.
{"abc",12}

Upvotes: 2

Related Questions