一道Erlang测试题的多种解法

题目:

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>"



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值