题目一
合并列表,[{a,1},{b,2},{c,3},{b,1}],[{b,4},{c,5},{d,6},{d,2}],结果:[{a,1},{b,7},{c,8},{d,8}]
解答
merge_lists(List1, List2) ->
MergedMap = lists:foldl(fun merge_tuple/2, maps:new(), List1 ++ List2),
lists:sort(maps:to_list(MergedMap)).
merge_tuple({Key, Value}, AccMap) ->
% 在AccMap中查找是否存在键为Key的KV对
NewValue = case maps:is_key(Key, AccMap) of
true -> maps:get(Key, AccMap) + Value;
false -> Value
end,
io:format("~p~n",[AccMap]),
maps:put(Key, NewValue, AccMap).
% 注意这里不能使用update, update要求AccMap不能为空
题目二
{5,1,8,7,3,9,2,6,4}元组内的数字依次乘以自己的下标位,结果 {5*1,1*2,8*3,7*4,3*5,9*6,2*7,6*8,4*9}
解答
multiply_with_index(Tuple) ->
multiply_with_index(erlang:tuple_to_list(Tuple), 1, []).
multiply_with_index([], _, Result) ->
lists:reverse(Result);
multiply_with_index([Value | Rest], Index, Result) ->
NewValue = Value * Index,
multiply_with_index(Rest, Index + 1, [NewValue | Result]).
题目三
排序[{“a”,5},{“b”,1},{“c”,8},{“d”,7},{“e”,3},{“f”,9},{“g”,2},{“h”,6},{“i”,4}] 禁用API(例如lists:sort,lists:usort等)
结果 :[{“b”,1}, {“g”,2},{“e”,3}, {“i”,4},{“a”,5},{“h”,6},{“d”,7},{“c”,8}, {“f”,9}]
解答
quick_sort(List) when length(List) > 1 ->
{Pivot, Rest} = select_pivot(List),
Less = [X || X <- Rest, less_than(X, Pivot)],
Greater = [X || X <- Rest, not less_than(X, Pivot)],
quick_sort(Less) ++ [Pivot] ++ quick_sort(Greater);
quick_sort(List) ->
List.
less_than({_, Value1}, {_, Value2}) ->
Value1 < Value2.
select_pivot([X | Rest]) ->
{X, Rest}.
题目四
获得数字列表或元组中的最大最小值
解答
getMax([Max | Rest]) ->
getMax(Rest, Max);
getMax(Tuple) ->
List = tuple_to_list(Tuple),
getMax(List).
getMax([X | Rest], Max) ->
case X > Max of
true -> getMax(Rest, X);
false -> getMax(Rest, Max)
end;
getMax([], Max) -> Max.
题目五
计算数字列表或元组中所有值的和
解答
getSum([X | Rest]) ->
getSum(Rest, X);
getSum(Tuple) ->
List = tuple_to_list(Tuple),
getSum(List, 0).
getSum([X | Rest], Acc) -> getSum(Rest, Acc + X);
getSum([], Acc) -> Acc.
题目六
计算数字列表或元组索引N到M的和
解答
%% base case
getRangeSum(List, N, M) when is_list(List) or is_tuple(List)->
io:format("===>getRangeSum(~p, ~p, ~p)~n", [List,N, M]),
getRangeSum(List, 1, N, M, 0).
getRangeSum(_, Index ,_, M, Acc) when Index > M ->
io:format("===>getRangeSum(_, ~p, _, ~p, ~p)~n", [Index,M, Acc]),
Acc;
%% 列表的处理
getRangeSum([Value | Rest], Index, N, M, Acc) when Index >= N ->
io:format("===>getRangeSum(~p, ~p, ~p, ~p, ~p)~n", [[Value | Rest], Index, N, M, Acc]),
getRangeSum(Rest, Index + 1, N, M, Acc + Value);
%% 元组的处理
getRangeSum(Tuple, Index, N, M, Acc) when Index >= N ->
io:format("===>getRangeSum(~p, ~p, ~p, ~p, ~p)~n", [Tuple, Index, N, M, Acc]),
Element = element(Index, Tuple),
getRangeSum(Tuple, Index + 1, N, M, Acc + Element);
%% 跳过元素的处理
getRangeSum([Value | Rest], Index, N, M, Acc) ->
io:format("===>getRangeSum(~p, ~p, ~p, ~p, ~p)~n", [[Value | Rest], Index, N, M, Acc]),
getRangeSum(Rest, Index + 1, N, M, Acc).
题目七
对数字列表中的奇数进行求和,后除以3的商得值为A,并将偶数求和后除以3的余数得值为B,然后求A+B结果,输出A、B、A+B
解答
getSum([X | Rest]) ->
getSum(Rest, X);
getSum(Tuple) ->
List = tuple_to_list(Tuple),
getSum(List, 0).
getSum([X | Rest], Acc) -> getSum(Rest, Acc + X);
getSum([], Acc) -> Acc.
getoeSum(List) ->
Odds = [X || X <- List, X rem 2 /= 0],
Evens = [X || X <- List, X rem 2 == 0],
io:format("Odds = ~p, Evens = ~p ~n", [Odds,Evens]),
getSum(Odds) div 3 + getSum(Evens) rem 3.
题目八
查找元素在元组或列表中的位置
解答
findIdx(Tuple, Val) when is_tuple(Tuple)->
findIdx(tuple_to_list(Tuple), 1, Val);
findIdx(List, Val) ->
findIdx(List, 1, Val).
%% Base
findIdx([], _, _) -> -1;
findIdx([Head | Rest], Index, Val) ->
case Head == Val of
true -> Index;
false -> findIdx(Rest, Index + 1, Val)
end.
题目九
查找在元组或列表中某个位置的元素
解答
findVal(Tuple, Index) when is_tuple(Tuple)->
findVal(tuple_to_list(Tuple), 1, Index);
findVal(List, Index) ->
findVal(List, 1, Index).
findVal([],_,_) -> io:format("index is invalid~n");
findVal([Head | Rest], CurIdx, Index) ->
case CurIdx == Index of
true -> Head;
false -> findVal(Rest, CurIdx + 1, Index)
end.
题目十
移除元组或列表中指定位置的元素
解答
%% 思路:重新构建列表,将移除元素后面的元素往前补上去
remove_at(List, Index) when is_list(List) ->
remove_at(List, Index, 1, []);
remove_at(List, Index) when is_tuple(List) ->
remove_at(tuple_to_list(List), Index, 1, []).
remove_at([], _, _, Acc) ->
lists:reverse(Acc);
remove_at([_ | Rest], Index, Index, Acc) ->
remove_at(Rest, Index, Index + 1, Acc);
remove_at([Element | Rest], Index, CurrentIndex, Acc) ->
remove_at(Rest, Index, CurrentIndex + 1, [Element | Acc]).