题目:
Remove '<','>' in "<XXXXXX>"?
"<XXXXXX>" -> "XXXXXX"
"XXXXXX>" -> "XXXXXX>"
"<XXXXXX" -> "<XXXXXX"
"<XX<XXXX>" -> "XX<XXXX"
"<<<XXX>>>" -> "XXX"
题目解读:要求编程将一个字符串中首尾配对的<>去掉。如"<Zhongsan Hu>" -> "Zhongsan Hu"
有两种解法:
1、采用递归算法。先比较首尾是否配对,如果不配对则打印出整个队列,如果配对,则去掉首尾,再对子队列继续进行递归计算。(遍历次数多,效率偏低)
2、计算首部'<'个数,再计算尾部'>'个数,然后得到这两都的最小值,根据队列的长度及这首尾两个数的最小值,可以得到所需要的队列。
解法一源码如下:
-module(test).
-export([remove/1]).
remove(L) when is_list(L) =:= true ->
remove_pair(L, "<", ">");
remove(_L) -> "Argument Error: You should test a list!".
%% 递归删除列表中首尾配对的两个元素
remove_pair(L, Head, End) ->
case check_list_tail_end(L, End) of
true when [hd(L)] =:= Head
-> remove_pair(remove_list_head_and_tail(L), Head, End);
_Other -> L
end.
%% 删除列表的头尾两个元素
remove_list_head_and_tail(L) when length(L) >= 2 ->
remove_list_head_and_tail(tl(L), []);
remove_list_head_and_tail(_L) -> [].
remove_list_head_and_tail([_H|T], Result) when T =:= [] ->
lists:reverse(Result);
remove_list_head_and_tail([H|T], Result) when T =/= []
-> remove_list_head_and_tail(T,[H|Result]).
%%判断尾部
check_list_tail_end([H|T], CompareEndList) when H =/= [] ->
if
T =:= [],[H] =:= CompareEndList -> true;
T =:= [],[H] =/= CompareEndList -> false;
T =/= [] -> check_list_tail_end(T, CompareEndList)
end;
check_list_tail_end(L, _) when L =:= [] -> false.
解法二源码如下:
-module(test).
-export([remove/1]).
remove([]) -> [];
remove(L) ->
remove(L, $<, $>).
remove(L, Head, End) ->
HeadCount = get_HeadCount(L, Head),
EndCount = get_EndCount(L, End),
TotalCount = length(L),
remove_HeadEnd(L, min(HeadCount, EndCount),TotalCount).
get_HeadCount(L, Head) ->
get_HeadCount(L, Head, 0).
get_HeadCount([H|T], Head, Count) ->
if
T =:= [], H =:= Head -> Count+1;
T =:= [], H =/= Head -> Count;
Head =/= H -> Count;
Head =:= H -> get_HeadCount(T, Head, Count+1);
true -> erlang:error("get_HeadCount Error")
end.
get_EndCount(L, End) ->
get_EndCount(L, End, 0).
get_EndCount([H|T], End, Count) ->
if
T =:= [], H =:= End -> Count+1;
T =:= [], H =/= End -> 0;
H =:= End -> get_EndCount(T, End, Count+1);
H =/= End -> get_EndCount(T, End, 0);
true -> erlang:error("get_EndCount Error")
end.
remove_HeadEnd(L, Count,TotalCount) ->
L1 = cut_Head(L, Count),
L2 = cut_End(L1, TotalCount-2*Count),
lists:reverse(L2).
cut_Head(L, Count) ->
cut_Head(L, Count, []).
cut_Head([], _Count, _L) -> [];
cut_Head([H|T], Count, L) ->
if
Count =/= 0 -> cut_Head(T, Count-1, [H|L]);
true -> [H|T]
end.
cut_End(L, ReserveCount) ->
cut_End(L, ReserveCount, []).
cut_End([], _ReserveCount, ResultList) -> ResultList;
cut_End([H|T], ReserveCount, ResultList) ->
if
ReserveCount =/= 0 -> cut_End(T, ReserveCount-1, [H|ResultList]);
true -> ResultList
end.
测试:
"<XXXXXX>" -> "XXXXXX"
"XXXXXX>" -> "XXXXXX>"
"<XXXXXX" -> "<XXXXXX"
"<XX<XXXX>" -> "XX<XXXX"
"<<<<hzhsan>>>>>" -> "hzhsan>"