erlang练习题(四)

题目一

传入列表

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.
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值