题目一
传入列表
L1=[K|]、L2=[V|]、L3=[{K,V}|_],L1和L2一一对应,L1为键列表,L2为值列表,L3为随机kv列表,
将L1和L2对应位合并成KV列表L4,再将L3和L4相加,相同key的value相加
如:L1=[a,b,c,d,e].L2=[1,2,3,4,5].L3=[{a,10},{e,20}].结果[{a,11},{b,2},{c,3},{d,4},{e,25}]
解答
merge(L1, L2, L3) ->
KVlist = mergeKV(L1, L2, []), % 将L1和L2组合成KV列表
List = mergeLists(KVlist, L3), % 将元组列表进行合并
mergeMap(List). % 将列表内元组进行合并
mergeKV(L1, L2) ->
mergeKV(L1, L2, []).
%% 组合为kv列表
mergeKV([],[], Acc) -> lists:reverse(Acc);
mergeKV([H1 | T1], [H2 | T2], Acc) ->
mergeKV(T1, T2, [{H1, H2} | Acc]).
%% 列表合并
mergeLists(L1, L2) ->
case L1 of
[] -> L2;
[H | T] -> [H | mergeLists(T, L2)]
end.
%% 合并列表内的Map对
mergeMap(List) ->
mergeMap(List, maps:new()).
mergeMap([], AccMap) -> maps:to_list(AccMap);
mergeMap([{Key, Value} | T], AccMap) ->
NewValue = case maps:is_key(Key, AccMap) of
true -> maps:get(Key,AccMap) + Value; % kv已存在则累加
false -> Value
end,
NewAccMap = maps:put(Key, NewValue, AccMap),
mergeMap(T, NewAccMap).
题目二
传入任意I1、I2、D、Tuple四个参数,检查元组Tuple在索引I1、I2位置的值V1、V2,
如果V1等于V2则删除V1,把D插入V2前面,返回新元组,如果V1不等于V2则把V2替换为V1,返回新元组,注意不能报异常,不能用try,不满足条件的,返回字符串提示
解答
fun1(I1, I2, D, Tuple) ->
V1 = element(I1, Tuple),
io:format("V1 = ~p~n", [V1]),
V2 = element(I2, Tuple),
io:format("V2 = ~p~n", [V2]),
case V1 =:= V2 of
true ->
Tuple2 = erlang:delete_element(I1, Tuple),
erlang:insert_element(I2, Tuple2, D);
false ->
Tuple1 = erlang:setelement(I1, Tuple, V2),
erlang:setelement(I2, Tuple1, V1)
end.
题目三
实现斐波拉契数列 ,如 fib(5) 应该返回 [1,1,2,3,5]
解答
fib(N) ->
if
N =:= 1 ->
[1];
N =:= 2 ->
[1, 1];
true ->
fib(N, 3, [1, 1])
end.
%% 递归结束处理
fib(N, N, Acc) ->
[X ,Y| _] = Acc,
lists:reverse([X + Y| Acc]);
fib(N, Cur, Acc) ->
[X ,Y| _] = Acc,
fib(N, Cur + 1, [X + Y | Acc]).
题目四
计算某个数的阶乘
解答
fac(N) ->
if
N =:= 0 -> 1;
true -> fac(N, N, 1)
end.
fac(_, 0, Acc) -> Acc;
fac(N, Cur, Acc) ->
fac(N, Cur - 1, Acc * Cur).
题目五
对一个字符串按指定字符划分
比如”abc-kkkk-s123“ 按照-划分,得到字符串列表[“abc”, “kkkk”, “s123”]
解答
split(_, []) ->
[];
split(Delimiter, String) when is_binary(Delimiter), is_binary(String) ->
split(binary_to_list(Delimiter), binary_to_list(String));
split(Delimiter, String) when is_list(Delimiter), is_list(String) ->
%% 将String每个字符按照fun的规则划分成两部分
case lists:splitwith(fun(C) -> C /= hd(Delimiter) end, String) of
{Part, []} -> %% 没有划分字符了
[Part];
{Part, [_ | Rest]} ->
[Part | split(Delimiter, Rest)]
end.
题目六
将列表中的integer, float, atom转成字符串并合并成一个字个字符串:[1, a, 4.9, sdfds] 结果:1a4.9sdfds
解答
conv_to_str(Value) when is_integer(Value) ->
integer_to_list(Value);
conv_to_str(Value) when is_float(Value) ->
float_to_list(Value);
conv_to_str(Value) when is_atom(Value) ->
atom_to_list(Value).
list_to_str([]) -> [];
list_to_str([H | T]) ->
ConvertedHead = conv_to_str(H),
Rest = list_to_str(T),
ConvertedHead ++ Rest.
题目七
检查一个字符串是否为回文串
解答
判断两头字符是否相等,然后判断中间字符串是否为回文串(递归)
is_palindrome(Str) ->
is_palindrome(Str, 1, length(Str)).
is_palindrome(_,Beg, End) when Beg >= End ->
true;
is_palindrome(Str,Beg, End) when Beg < End ->
case lists:nth(Beg, Str) =:= lists:nth(End, Str) of
true -> is_palindrome(Str,Beg + 1, End - 1);
_-> false
end.
题目八
将一个字符串中的所有字符翻转
解答
reverse_str(Str) ->
reverse_str(Str, "").
reverse_str([], Acc) -> Acc;
reverse_str([H|T], Acc) ->
reverse_str(T, [H | Acc]).
题目九
查找一个字符串中的最长单词
find_longest_word(Str) ->
% 使用空格分割字符串,得到单词列表
Words = string:tokens(Str, " "),
% 调用辅助函数来查找最长单词
Longest = find_longest_word(Words, ""),
% 返回最长的单词
Longest.
find_longest_word([], Longest) -> Longest;
find_longest_word([Word | Rest], Longest) ->
% 计算当前单词的长度
WordLength = string:len(Word),
OldLength = string:len(Longest),
NewLongest = if
WordLength > OldLength -> Word;
true -> Longest
end,
% 递归处理
find_longest_word(Rest, NewLongest).
题目十
查找一个字符串中出现次数最多的字符
解答
find_most_common_char(Str) ->
{CharCountMap, MostCommonChar} = find_most_common_char(Str, #{}, 0, $a),
% 返回出现次数最多的字符和出现次数
%{MostCommonChar, maps:get(MostCommonChar, CharCountMap)},
io:format("~c:~w~n", [MostCommonChar, maps:get(MostCommonChar, CharCountMap)]).
find_most_common_char([], CharCountMap, _, MostCommonChar) ->
{CharCountMap, MostCommonChar};
% 辅助函数,用于递归查找出现次数最多的字符
find_most_common_char([Char | Rest], CharCountMap, MaxCount, MostCommonChar) ->
% 更新字符出现次数
% fun(Count) -> Count + 1 end Count表示Char对应的value,并且将value改变为Count+1
NewCharCountMap = maps:update_with(Char, fun(Count) -> Count + 1 end, 1, CharCountMap),
% 获取当前字符出现次数
CharCount = maps:get(Char, NewCharCountMap),
case CharCount > MaxCount of
true ->
find_most_common_char(Rest, NewCharCountMap, CharCount, Char);
false ->
find_most_common_char(Rest, NewCharCountMap, MaxCount, MostCommonChar)
end.