1、将列表中的integer,float,atom转成字符串并合并成一个字个字符串:[1,a,4.9,“sdfds”] 结果:“1a4.9sdfds”(禁用++ – append concat实现)
2、得到列表或元组中的指定位的元素 {a,g,c,e} 第1位a [a,g,c,e] 第1位a(禁用erlang lists API实现)
3、根据偶数奇数过淲列表或元组中的元素
4、便用匿名函数对列表奇数或偶数过滤
5、计算数字列表[1,2,3,4,5,6,7,8,9]索引N到M的和
6、查询List1是为List2的前缀(禁用string API实现)
7、逆转列表或元组(禁用lists API实现)
8、对列表进行排序
9、对数字列表进行求和再除以指定的参数,得到商余
10、获得当前的堆栈
11、获得列表或元组中的最大最小值(禁用API实现)
12、查找元素在元组或列表中的位置
13、博主很帅
14、判断A列表([3,5,7,3])是否在B列表([8,3,5,3,5,7,3,9,3,5,6,3])中出现,出现则输出在B列表第几位开始
15、{8,5,2,9,6,4,3,7,1} 将此元组中的奇数进行求和后除3的商(得值A),并将偶数求和后剩3(得值B),然后求A+B结果
16、在shell中将unicode码显示为中文
17、传入列表L1=[K]、L2=[V]、L3=[{K,V}|_]、,L1和L2一一对应,L1为键列表,L2为值列表,将L1和L2按位置组合为[{k,v}]行式,完成后再和L3进行结合
18、删除或查询元组中第N个位置的值等于Key的tuple(禁用lists API实现)
19、对一个字符串按指定符字劈分(禁用string API实现)
20、合并多个列表或元组
21、{5,1,8,7,3,9,2,6,4} 将偶数乘以它在此元组中的偶数位数, 比如,8所在此元组中的偶数位数为1,2所在此元组中的偶数位数为2
22、排序[{“a”,5},{“b”,1},{“c”,8},{“d”,7},{“e”,3},{“f”,9},{“g”,2},{“h”,6},{“i”,4}], 以元组的值进行降序 优先用API
23、{8,5,2,9,6,4,3,7,1} 将此元组中的奇数进行求和.
24、传入任意I1、I2、D、Tuple四个参数,检查元组Tuple在索引 I1、I2位置的值V1、V2,如果V1等于V2则删除V1,把D插入V2前面,返回新元组,如果V1不等于V2则把V2替换为V1,返回新元组。注意不能报异常,不能用try,不满足条件的,返回字符串提示
25、删除列表或元组中全部符合指定键的元素
26、替换列表或元组中第一个符合指定键的元素。
27、将指定的元素插入到列表中指定的位置,列表中后面的元素依次向后挪动 需反复理解
28、对[6,4,5,7,1,8,2,3,9]进行排序(降序–冒泡排序)或API排序
29、随机打乱元组,{z,1,y,3,x,5}.
30、移除元组或列表中指定位置的元素
31、指定列表第几位之后的数据进行反转。如:指定[2,3,5,6,7,2]第3位后进行反转(谢绝一切API(lists:concat,lists:reverse等)、++、–方法) 需理解27题
32、使用“匿名函数”检查列表的每个元素是否符合传入的最大最小值(都是闭区间)
33、获得列表或元组的最大最小值
34、成生指定数量元组,每个元素为随机integer元素, 元素不能有相同的
四星难度题
35、对一个int进行位移操作,取出0到16位的数据,16到32位的数据,输出这两个数(提示:用bsr bsl实现)
36、输入A(元子列表),B(数值列表)两个相同长度的参数进行随机匹配(要求字母为Key,数值为Value),支持指定的Key和Value在一组
37、对相同类型的数据进行拼接,如binary(<<1,2>><<3,4>> =<<1,2,3,4>>) tuple({a,b},{c} ={a,b,c}) list([10],[20] =[10,20])
38、将列表中相同key的值进行合并,[{a,1},{b,2},{c,3},{b,4},{b,5},{c,6},{d,7},{d,8}]
39、Erlang程序设计(第2版)中5.3节的count_characters方法有错,自行修改证
40、使用“匿名函数”对参数列表中奇数乘以它所在奇数位。如{1,2,3,4,5} 结果 {1,2,6,4,15}
以上40道题答案:https://blog.csdn.net/qq_36337353/article/details/89054145
面试题
1、将二进制数据转为16进制表示的字符串。
博主自己写的代码
1、将列表中的integer,float,atom转成字符串并合并成一个字个字符串:[1,a,4.9,“sdfds”] 结果:“1a4.9sdfds”(禁用++ – append concat实现)
list_to_Str(L) ->
M = lists:map( fun(X) -> io_lib:format("~p", [X]) end ,L),
binary_to_list(list_to_binary(M)).
2、得到列表或元组中的指定位的元素 {a,g,c,e} 第1位a [a,g,c,e] 第2位g(禁用erlang lists API实现)
元组部分想用element取的,他说不能用这api,那就用tuple_to_list,关键是列表支持[H|T]方式,元组不能这么搞,要所有api都不能用的话,我也不知道怎么做了。
-module(t).
-export([get/2]).
get(L,Posi) ->
if
is_list(L) ->
[H|T] = L , get([H|T],[],Posi,0);
is_tuple(L)->
[H|T] = tuple_to_list(L),
get([H|T],[],Posi,0)
end.
%% Posi == Index
get(_,E,Posi,Posi) -> E;
%% 传入列表[]
get([H|T],_,Posi,Index)-> get(T,H,Posi,Index+1).
3、根据偶数奇数过淲列表或元组中的元素
-module(t).
-export([filter/2]).
filter(L,Type)->
if
is_tuple(L) -> A = tuple_to_list(L),filter_list(A,Type);
is_list(L) -> filter_list(L,Type)
end.
filter_list(L,even)-> [H || H <-L, H rem 2 == 0 ];
filter_list(L,odd) -> [H || H <-L, H rem 2 == 1 ].
4、便用匿名函数对列表奇数或偶数过滤
博主自由发挥,写法不限
-module(t).
-export([filter/2]).
filter(L,Type)->
if
Type == even ->
Filter = fun(X)-> X rem 2 == 0 end;
Type == odd ->
Filter = fun(X)-> X rem 2 == 1 end;
true ->
Filter = fun(_)-> true end
end,
[X || X <- L, Filter(X)].
5、计算数字列表[1,2,3,4,5,6,7,8,9]索引N到M的和
博主自由发挥,写法不限
-module(t).
-export([sum/3]).
sum(L,N,M)->sum(L,N,M,0).
sum(_,_,M,M)->0;
sum([H|T],N,M,Index) when ((Index+1 >= N) and (Index =< M)) ->
H + sum(T,N,M,Index+1);
sum([_|T],N,M,Index) -> sum(T,N,M,Index+1).
6、查询List1是为List2的前缀(禁用string API实现)
博主自由发挥,写法不限
-module(t).
-export([prefix/2]).
%%A是不是B的前缀
prefix([],_)->true;
prefix([H1|T1],[H2|T2])->
case H1 == H2 of
false -> false;
true -> prefix(T1,T2)
end.
7、逆转列表或元组(禁用lists API实现)
博主自由发挥,写法不限
-module(t).
-export([reverse/1]).
reverse(L)->
if
is_list(L)->
[H|T] = L,
reverse_list([H|T]);
is_tuple(L)->
[H|T] = tuple_to_list(L),
R = reverse_list([H|T]),
list_to_tuple(R)
end.
reverse_list([]) ->[];
reverse_list([H|T])-> reverse_list(T) ++ [H].
书上说 使用++要注意是个警钟,小数组没问题,大数组效率很低,所以我还写了一个版本。
%%反转列表
reverse(L) -> reverse_acc(L,[]).
reverse_acc([],Array) -> Array;
reverse_acc([H|T],Array) -> reverse_acc(T,[H|Array]).
一旦要使用reverse,应该用api版本,lists:reverse ,系统一旦发现调用这个函数,会自动调用一个效率更高的内部函数处理。
8、对列表进行排序
虽然之前已经理解过了,但是再写一遍还是有点瑕疵,没能理解到精髓,相信这次写了不会再忘记了。
-module(t).
-export([sort/1]).
sort([])->[];
sort([H|T])->
sort([A || A <-T ,A < H])
++ [H] ++
sort([A || A <-T ,A >= H]).
9、对数字列表进行求和再除以指定的参数,得到商余
博主手撸,自由发挥,写法不限,敞开写~放开写~
-module(t).
-export([custom/2]).
custom(L,N)->custom(L,N,0).
%%--返回{商数,余数}
custom([],N,Result) -> {Result/N,Result rem N};
custom([H|T],N,Result) -> custom(T,N,Result+H).
10、获得当前的堆栈
Trace = try throw(ap114) catch
ap114 -> erlang:get_stacktrace()
end,
erlang:display(Trace)
11、获得列表或元组中的最大最小值(禁用API实现)
此题可复杂可简单,同时获得列表或元组类型,涉及到类型转换,同时考虑元组嵌套元组,列表嵌套元组的会写出巨麻烦的处理逻辑,博主写了一半想了下,不用api,实在是超级复杂,不过还是写出来了。
-module(t).
-export([maxmin/1]).
maxmin(L) ->
%%传入的是列表或元组,分开处理,为什么要在这里多此一举,原因1.禁用api 2.是拿到第一个元素,作为比较,最大最小值不能用0作为初始值哦
if
is_list(L)->
[H|T] = L,
maxmin_list([H|T],H,H);
is_tuple(L)->
%%元组做成列表处理
[H|T] = tuple_to_list(L),
maxmin_list([H|T],H,H)
end.
maxmin_list([],Max,Min) ->{Max,Min};
maxmin_list([H|T],Max,Min) ->
if
%%嵌套情况,若传入的子元素是元组、列表类型
is_list(H)->
%%嵌套类型局部求最大值、最小值
{Max_item,Min_item} = maxmin_list(H,Max,Min),
%%处理剩下的列表
maxmin_list(T,Max_item,Min_item);
is_tuple(H)->
%%元组做成列表处理、局部求最大值、最小值
A = tuple_to_list(H),
{Max_item,Min_item} = maxmin_list(A,Max,Min),
%%处理剩下的列表
maxmin_list(T,Max_item,Min_item);
is_integer(H) or is_float(H) ->
if
H > Max -> maxmin_list(T,H,Min);
H < Min -> maxmin_list(T,Max,H);
true -> maxmin_list(T,Max,Min)
end
end.
如果没有嵌套的情况,例如{1,2,3}或者 [1,2,3] 那可以这样写
-module(t).
-export([maxmin/1]).
maxmin(L) ->
%%传入的是列表或元组,分开处理,为什么要在这里多此一举,原因1.禁用api 2.是拿到第一个元素,作为比较,最大最小值不能用0作为初始值哦
if
is_list(L)->
[H|T] = L,
maxmin_list([H|T],H,H);
is_tuple(L)->
%%元组做成列表处理
[H|T] = tuple_to_list(L),
maxmin_list([H|T],H,H)
end.
maxmin_list([],Max,Min) -> {Max,Min};
maxmin_list([H|T],Max,Min) ->
if
H > Max -> maxmin_list(T,H,Min);
H =< Min -> maxmin_list(T,Max,H);
true -> maxmin_list(T,Max,Min)
end.
如果题目的意思是列表或者元组随便选一个类型做,那可以这样写。
-module(t).
-export([maxmin/1]).
maxmin([H|T]) -> maxmin(T,H,H).
maxmin([],Max,Min) -> {Max,Min};
maxmin([H|T],Max,Min) ->
if
H > Max -> maxmin(T,H,Min);
H =< Min -> maxmin(T,Max,H);
true -> maxmin(T,Max,Min)
end.
12、查找元素在元组或列表中的位置
元组就用tuple_to_list实现,这里给出查列表方法
-module(t).
-export([find/2]).
find(L,E)->find(L,E,1).
find([],_,_) ->{ok,-1};
find([H|T],E,Index)->
case H == E of
true -> {ok,Index};
false -> find(T,E,Index+1)
end.
14、判断A列表([3,5,7,3])是否在B列表([8,3,5,3,5,7,3,9,3,5,6,3])中出现,出现则输出在B列表第几位开始
-module(t).
-export([find/2]).
find(A,B) -> find(A,B,1).
find(_,[],_) -> {ok,-1};
find(A,[H|T],Index)->
case equals(A,[H|T]) of
true -> {ok,Index};
false -> find(A,T,Index+1)
end.
equals(_,[]) -> false;
equals([],_) -> true;
equals([H1|T1],[H2|T2])->
case H1 == H2 of
false -> false;
true -> equals(T1,T2)
end.
15、{8,5,2,9,6,4,3,7,1} 将此元组中的奇数进行求和后除3的商(得值A),并将偶数求和后剩3(得值B),然后求A+B结果
列表归集器,好处是只用遍历一遍,节省空间。
-module(tieba).
-export([add/1,add_acc/3,sum/1]).
add(L) -> add_acc(L,[],[]).
add_acc([H|T],Odds,Evens)->
case (H rem 2) of
1 -> add_acc(T,[H|Odds],Evens);
0 -> add_acc(T,Odds,[H|Evens])
end;
add_acc([],Odds,Evens)->
sum(Evens) / 3 + sum(Odds) * 3.
sum([]) -> 0;
sum([H|T]) -> H + sum(T).
16、在shell中将unicode码显示为中文
io:format("cnkizy是个帅哥").
unicode:characters_to_list(list_to_binary("cnkizy是个帅哥")).
17、传入列表L1=[K]、L2=[V]、L3=[{K,V}|_],L1和L2一一对应,L1为键列表,L2为值列表,将L1和L2按位置组合为[{k,v}]行式,完成后再和L3进行结合
-module(t).
-export([
merge/2,
join/3
]).
join(K,V,L3) -> L3 ++ merge(K,V).
merge([],[]) -> [];
merge([KH|KT],[VH|VT]) -> [{KH,VH} | merge(KT,VT)].
18、删除或查询元组中第N个位置的值等于Key的tuple(禁用lists API实现)
这题不是很懂,一般给key求value,没见过指定N个位置的。指定位置那不就是数组了吗? key[N] == tuple ?????
这是别人写的东西,实话说我看不懂意义何在。不过理解这段代码对27题有帮助。
-export([delete/3,select/3]).
delete(List,N,Key) -> delete3(List,N,Key).
delete3([H|T],N,Key) when element(N,H) == Key -> delete(T,N,Key);
delete3([H|T],N,Key)->[H|delete(T,N,Key)];
delete3([],,)->[].
select(List,N,Key) -> select3(List,N,Key).
select3([H|T],N,Key) when element(N,H) ==Key -> [H|select(T,N,Key)];
select3([H|T],N,Key)->select(T,N,Key);
select3([],,)->[].
既然是数组操作,直接简单明了的写。
-module(t).
-export([
select/3,
delete/3
]).
select(N,K,Tuple)->
Item = element(N,Tuple),
case Item == K of
true -> Item;
false -> []
end.
delete(N,K,Tuple)->
Item = element(N,Tuple),
case Item == K of
true -> erlang:delete_element(N,Tuple);
false -> []
end.
19、对一个字符串按指定字符劈分(禁用string API实现)
捣鼓了几个小时,其他人用了正则表达式里的split,假如不用任何api,我还是有点头疼,下面这一段也有一点瑕疵,假设没有匹配的Ch,结果是L,而不是[]
-module(t).
-export([split/2]).
split(L,Ch) -> split(L,Ch,[],[]).
split([],_,Result,_) -> Result;
split([_|T],Ch,Result,Array) when T == [] -> split(T,Ch,Result ++ [Array],[]);
split([H|T],Ch,Result,Array) ->
case H == Ch of
true ->
split(T,Ch,Result ++ [Array],[]);
false ->
split(T,Ch,Result ,Array ++ [H])
end.
后记已修正,不过这么写复杂了,等后续优化:
%% 根据Ch拆分列表L 找到 -> [H|T]
%% 没找到 -> []
split(L,Ch) -> split(L,Ch,[],[]).
split([],_,R,_) when length(R) == 1 -> [];
split([],_,R,_) -> R ;
split([H|T],Ch,Result,Array) when T == [] -> split(T,Ch,Result ++ ([Array ++ [H]]),[]);
split([H|T],Ch,Result,Array) ->
case H == Ch of
true ->
split(T,Ch,Result ++ [Array],[]);
false ->
split(T,Ch,Result ,Array ++ [H])
end.
20、合并多个列表或元组
erlang里可没有c#中的params这种可变参数操作,至于题目中的多个到底是多少个就不得而知,可利用现有的lists:merge
-module(t).
-export([merge/2]).
merge(A,B) ->
if
is_tuple(A)-> T = tuple_to_list(A) , merge(T,B);
is_tuple(B)-> T = tuple_to_list(B) , merge(T,B);
true -> lists:merge(A,B)
end.
后记,题目要求其实是一个列表里的多个列表或元组:
-module(t3).
-export([
test/0
]).
test()->
A = [[1],[2],[3,4],[2],[5,6],[7]],
B = [{1},{2},{3,4},{2},{5,6},{7}],
{mergeList(A),mergeTuple(B)}.
%% 处理多个列表相加
mergeList(L)->
if
is_list(L) == true ->
mergeList(L,[]);
true ->
{"Error: no List",L}
end.
mergeList([],Output)->Output;
mergeList([H|T],Output)->
if
is_list(H) == true->
mergeList(T, Output ++ H);
true->
{"Error:This Item type no List:",H}
end.
%% 处理多个元组相加
mergeTuple(L)->list_to_tuple(mergeTuple(L,[])).
mergeTuple([],Output)->Output;
mergeTuple([H|T],Output)->
if
is_tuple(H) == true->
mergeTuple(T, Output ++ tuple_to_list(H));
true->
{"Error:This Item type no Tuple:",H}
end.
21、{5,1,8,7,3,9,2,6,4} 将偶数乘以它在此元组中的偶数位数, 比如,8所在此元组中的偶数位数为1,2所在此元组中的偶数位数为2
-module(t).
-export([mul/1]).
mul(List)->mul(List,1).
mul([],_)->[];
mul([H|T],Index) ->
if
H rem 2 == 0 ->
[H * Index | mul(T,Index+1)];
true ->
[H] ++ mul(T,Index)
end.
22、排序[{“a”,5},{“b”,1},{“c”,8},{“d”,7},{“e”,3},{“f”,9},{“g”,2},{“h”,6},{“i”,4}], 以元组的值进行降序 优先用API
-module(t).
-export([sort/1]).
sort(List) -> sort(List,2).
sort(List,2) -> lists:keysort(2,List).
23、{8,5,2,9,6,4,3,7,1} 将此元组中的奇数进行求和.
-module(t).
-export([sum/1]).
filter(List)->[X || X<-List,X rem 2 /= 0].
sum(Tuple)->lists:sum(filter(tuple_to_list(Tuple))).
24、传入任意L1、L2、D、Tuple四个参数,检查元组Tuple在索引 L1、L2位置的值V1、V2,如果V1等于V2则删除V1,把D插入V2前面,返回新元组,如果V1不等于V2则把V2替换为V1,返回新元组。注意不能报异常,不能用try,不满足条件的,返回字符串提示
不满足条件返回字符串,这里需要判断的条件有点多,稍不注意就异常了。
-module(t).
-export([
r/4
]).
r(L1,L2,D,Tuple) ->
Len = size(Tuple),
if
is_integer(L1) == false -> io:format("First parameter not a Integer");
is_integer(L2) == false -> io:format("Second parameter not a Integer");
is_tuple(Tuple) == false -> io:format("4Th parameter not a Tuple");
(L1 > Len) or (L2 > Len) -> io:format("L1 L2 Excessive Length");
(L1 < 1) or (L2 < 1) -> io:format("L1 L2 Do not less 1");
true ->
V1 = element(L1,Tuple),
V2 = element(L2,Tuple),
case V1 == V2 of
true ->
New = erlang:delete_element(L1,Tuple),
erlang:insert_element(L1,New,D);
false ->
New = erlang:delete_element(L2,Tuple),
erlang:insert_element(L2,New,V1)
end
end.
25、删除列表或元组中全部符合指定键的元素。
-module(t).
-export([
delete/2
]).
delete(K,L) ->
if
is_tuple(L)->
list_to_tuple(delete_acc(K,tuple_to_list(L),[]));
is_list(L) ->
delete_acc(K,L,[]);
true->
delete_acc(K,L,[])
end.
%% 发现 K == H 直接跳过,否则就往Array累加数据
delete_acc(_,[],Array) -> Array;
delete_acc(K,[H|T],Array) when H == K -> delete_acc(K,T,Array);
delete_acc(K,[H|T],Array) -> delete_acc(K,T,[H|Array]).
26、替换列表或元组中第一个符合指定键的元素。
-module(t).
-export([
replace/2
]).
replace({K,V},L) ->
if
is_tuple(L)->
list_to_tuple(replace_acc({K,V},tuple_to_list(L),false));
is_list(L) ->
replace_acc({K,V},L,false);
true->
replace_acc({K,V},L,false)
end.
replace_acc(_,[],_) -> [];
replace_acc({K,V},[H|T],Flag) ->
case ( H == K ) and ( Flag == false ) of
true -> [V | replace_acc({K,V},T,true)];
false -> [H | replace_acc({K,V},T,Flag)]
end.
27、将指定的元素插入到列表中指定的位置,列表中后面的元素依次向后挪动
-module(t).
-export([
insert/3
]).
insert(_,[],_) -> [];
insert(E,T,1) -> [E|T];
insert(E,[H|T],Posi) -> [H|insert(E,T,Posi-1)] .
api方法:
-module(t).
-export([
insert/3
]).
insert(List,Posi,Element)->
tuple_to_list(
erlang:insert_element(
Posi,
list_to_tuple(List),
Element)).
28、对[6,4,5,7,1,8,2,3,9]进行排序(降序–冒泡排序)或API排序
-module(t).
-compile(export_all).
sort(L) -> lists:sort(fun(A,B)-> A > B end,L).
29、随机打乱元组,{z,1,y,3,x,5}
-module(t).
-export([
disruption/1
]).
disruption(T) -> disruption(T,[],size(T)).
disruption(_,Array,0) -> Array;
disruption(T,Array,Len) ->
Random = random:uniform(Len),
H = element(Random,T),
NewTuple = erlang:delete_element(Random, T),
disruption(NewTuple,[H] ++ Array,Len - 1).
30、移除元组或列表中指定位置的元素
-module(t).
-export([
remove/2
]).
remove(L,Index) ->
if
is_list(L) ->
remove(list_to_tuple(L),Index);
true ->
erlang:delete_element(Index,L)
end.
31、指定列表第几位之后的数据进行反转。如:指定[2,3,5,6,7,2]第3位后进行反转[2,3,5,2,7,6](谢绝一切API(lists:concat,lists:reverse等)、++、--方法)
-module(t).
-export([
reverse/1,
reverseByPosition/2
]).
%%反转列表
reverse(L) -> reverse_acc(L,[]).
reverse_acc([],Array) -> Array;
reverse_acc([H|T],Array) -> reverse_acc(T,[H|Array]).
%%指定位置后,反转列表
reverseByPosition(L,Posi) -> reverseByPosition(L,Posi,[]).
reverseByPosition([],_,Array) -> Array;
reverseByPosition([H|T],1,_) -> [H | reverse(T)];
reverseByPosition([H|T],Posi,Array) -> [H | reverseByPosition(T,Posi-1,Array) ].
32、使用“匿名函数”检查列表的每个元素是否符合传入的最大最小值(都是闭区间)
单个元素,shell里匿名函数返回匿名函数
SetMaxMin =
fun(Max,Min)->
(fun(X)->
(X =< Max) and (X >= Min)
end)
end.
Check = SetMaxMin(10,1).
Check(0).
%false
Check(1).
%true
Check(10).
%true
Check(9).
%true
Check(11).
%false
Check(10.0001).
%false
列表里
-module(t).
-export([
maxmin/2
]).
maxmin(L,{Max,Min})->
lists:map(
fun(X)->
{X,(X =< Max) and (X >= Min)}
end,L).
33、获得列表或元组的最大最小值
见11题,区别是11题禁用api,这里可以使用api。
-module(t).
-export([
maxmin/1
]).
maxmin(L) -> { lists:max(L) , lists:min(L) }.
34、成生指定数量元组,每个元素为随机integer元素, 元素不能有相同的
-module(t).
-export([
random/1
]).
random(I) -> random(I,[]).
random(0,Array) -> Array;
random(I,Array) ->
{_,_,BigInt} = os:timestamp(),
Random = rand:uniform(BigInt),
case lists:member(Random , Array) of
true -> random(I , Array);
false -> random(I-1 , Array ++ [Random])
end.
35、对一个int进行位移操作,取出0到16位的数据,16到32位的数据,输出这两个数(提示:用bsr bsl实现)
在其它语言里int本身就32位,但erlang里没有int 32位概念
-module(t).
-export([
getLH/1
]).
getLH(N) ->
%% 取高位很容易
H = N bsr 16,
%% C语言的溢出技巧在此行不通,(-2147483648 << 16 ) >> 16 答案还是-2147483648,
%% erlang一旦发现溢出就把16位升级到32位,32位升级到64位。。。。(个人见解)
%% L = (N bsl 16) bsr 16,
%% 让低位左移16位后,现在的低位就全变成0,原来的低位变成高位,
%% 再与16#ffff0000进行and运算,可以过滤掉32位之后的数据,现在就只剩下16-32位有数据,其他全为0
L = ((N bsl 16) band 16#ffff0000) bsr 16,
{H,L}.
36、输入A(元子列表),B(数值列表)两个相同长度的参数进行随机匹配(要求字母为Key,数值为Value),支持指定的Key和Value在一组
-module(t).
-export([
add/2,
random/1
]).
random([])->[];
random(L)->
Rand = rand:uniform(length(L)),
Item = lists:nth(Rand,L),
[Item | random(lists:delete(Item,L))].
add(A,B)->
%%打乱A
A1 = random(A),
%%打乱B
B1 = random(B),
join(A1,B1).
join([],[]) -> [];
join([AH|AT],[BH|BT]) -> [ {AH,BH} | join(AT,BT) ].
37、对相同类型的数据进行拼接,如binary(<<1,2>><<3,4>> =<<1,2,3,4>>) tuple({a,b},{c} ={a,b,c}) list([10],[20] =[10,20])
-module(t).
-export([merge/2,test/0]).
test()->
[
merge(123,456),
merge(3.1415,5.1234),
merge(abc,def),
merge([1,2,3,4,5],[3,4,5,6,7,8,9]),
merge({1,2},{3,4}),
merge(<<1,2>>,<<3,4>>)
].
merge(A,B)->
if
is_integer(A),is_integer(B) ->
A+B;
is_float(A),is_float(B) ->
A+B;
is_atom(A),is_atom(B) ->
ConvertList = lists:append(atom_to_list(A),atom_to_list(B)),
list_to_atom(ConvertList);
is_list(A),is_list(B) ->
lists:append(A,B);
is_tuple(A),is_tuple(B) ->
ConvertList = lists:append(tuple_to_list(A),tuple_to_list(B)),
list_to_tuple(ConvertList);
is_binary(A),is_binary(B) ->
ConvertList = lists:append(binary_to_list(A),binary_to_list(B)),
list_to_binary(ConvertList);
true ->
"Unknow Type"
end.
38、将列表中相同key的值进行合并
Input=>
[
{a,1},
{b,2},
{c,3},
{b,4},
{b,5},
{c,6},
{d,7},
{d,8}
]
OutPut=>
[
{a,1},
{b,[2,4,5]},
{c,[3,6]},
{d,[7,8]}
]
大部分代码就是玩api了,还是有点费劲,是因为不熟悉api,还有些基本操作元素连接、列表、元组操作不熟练。
-module(t).
-export([
test/0,
combine/2
]).
test()->
T = [{a,1},{b,2},{c,3},{b,4},{b,5},{c,6},{d,7},{d,8}],
combine(T,#{}).
combine([],Map) ->
maps:to_list(Map);
combine([{K,V}|T],Map)->
case maps:is_key(K,Map) of
true ->
MapV = maps:get(K,Map),
case is_list(MapV) of
true ->
combine(T,maps:update(K,MapV ++ [V],Map));
false ->
combine(T,maps:update(K,[MapV] ++ [V],Map))
end;
false ->
combine(T,maps:put(K,V,Map))
end.
39、Erlang程序设计(第2版)中5.3节的count_characters方法有错,自行修改证
跟着书上的内容看,自己没有做出来(之前没做38,跳着做的),看了别人写的才醍醐灌顶。
-module(t).
-export([
count_characters/1
]).
count_characters(Str) -> count_characters(Str, #{}).
count_characters([H|T] , X) ->
case maps:is_key(H,X) of
false ->
count_characters(T,maps:put(H,1,X));
true ->
Count = maps:get(H,X),
count_characters(T,maps:update(H,Count+1,X))
end;
count_characters([],X) -> X.
40、使用“匿名函数”对参数列表中奇数乘以它所在奇数位。如{1,2,3,4,5} 结果 {1,2,6,4,15}
有种多此一举的感觉,就当是练习语法了。
-module(t).
-export([
mul/1
]).
mul(L)->mul(L,1).
mul([],_)->[];
mul(L,I)->
F = fun([H|T],Index)->
case H rem 2 == 1 of
true -> [H * Index|mul(T,Index+1)];
false -> [H|mul(T,Index)]
end
end,
F(L,I).
面试题1、将二进制数据转为16进制表示的字符串。
%% @author ping
%% @doc @todo Add description to six.
%%题目:用erlang实现,将二进制数据转为16进制表示的字符串。
%%比如输入<<204,73,62,86>>,返回"cc493e56"
-module(six).
-export([fan/1]).
fan(Bin)->
Context = binary_to_list(Bin),
lists:concat([integer_to_list(X,16) || X<-Context]).
————————————————
版权声明:本文为CSDN博主「皮卡丘来了」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/math_coder/article/details/26086665
面试题2、根据N元素为界限,拆分L列表,只拆分成两个列表 -> {[A],[B]}
2,[1,2,3,4,5] -> {[1],[3,4,5]}
%% 根据Ch第一次出现的位置拆分列表L
%% split(1,[1,2,3,4,5,6,7,8,9]) -> {[],[2,3,4,5,6,7,8,9]}
%% split(2,[1,2,3,4,2,5,6,7,8,9])-> {[1],[3,4,2,5,6,7,8,9]}
%% split(0,[1,2,3,4,2,5,6,7,8,9])-> {[1,2,3,4,2,5,6,7,8,9],[]}
split(N,L) -> split(N,L,[],[]).
split(N,L,[],[]) when is_tuple(L) -> split(N,tuple_to_list(L),[],[]);
split([],[H|T],Array1,Array2) -> split([],T,Array1, Array2 ++ [H]);
split(N,[H|T],Array1,Array2) ->
case N == H of
true -> split([],T,Array1, Array2);
false -> split(N,T,Array1 ++ [H], Array2)
end;
split(_,[],Array1,Array2) -> {Array1,Array2}.
%% 根据Ch第一次出现的位置拆分列表L 没有则返回[]
%% split(1,[1,2,3,4,5,6,7,8,9]) -> {[],[2,3,4,5,6,7,8,9]}
%% split(2,[1,2,3,4,5,6,7,8,9]) -> [[1],[3,4,5,6,7,8,9]]
%% split(0,[1,2,3,4,5,6,7,8,9]) -> []
split(Ch,L) -> split(L,Ch,[],[]).
split([],_,R,_) when length(R) == 1 -> [];
split([],_,R,_) -> R ;
split([H|T],Ch,Result,Array) when T == [] -> split(T,Ch,Result ++ ([Array ++ [H]]),[]);
split([H|T],Ch,Result,Array) ->
case H == Ch of
true ->
split(T,Ch,Result ++ [Array],[]);
false ->
split(T,Ch,Result ,Array ++ [H])
end.
字符串替换
-module(t).
-export([
test/0
]).
test()->
Str = "你好,我叫var,来自var,毕业于var,请多指教",
Replace = ["ZZZ","XXX","YYY"],
Str2 = "",
Replace2 = [],
Str3 = "____var,___var,____var___",
Replace3 = [hello,a,world],
io:format(replace_list(Str,"var",Replace)),
io:format(replace_list(Str2,"var",Replace2)),
io:format(replace_list(Str3,"var",Replace3)).
%% 根据占位符替换对应的单词
replace_list(Str,_,[]) -> Str;
replace_list(Str,ReplaceWord,[H|T])->
NewStr = replace(Str,ReplaceWord,H),
replace_list(NewStr,ReplaceWord,T).
%% 字符串替换,只替换一次,没有则返回原字符串
replace(Str,BeforeWord,AfterWord) -> replace(Str,BeforeWord,AfterWord,1).
replace(Str,BeforeWord,AfterWord,FindIndex)->
if
is_list(BeforeWord),is_list(AfterWord) ->
Index = string:str(Str, BeforeWord),
if
Index == 0 -> Str;
true ->
%% 截取指定单词之前的字符串
HeadStr = string:sub_string(Str,FindIndex,Index-1),
%% 截取指定单词之后的字符串
TailStr = string:sub_string(Str,Index+length(BeforeWord),length(Str)),
%% 拼接字符串
HeadStr ++ AfterWord ++ TailStr
end;
true->"Error: Unknow Type"
end.
2022年12月24日 17:46:57
补充 - 评论下方有人留言
请写一个函数输入输入任意包含二元组和三元组得列表与键,用列表的形式返回该键所对应得所有值(不使用API,++,--) 例如 [{a, 1}, {b, 2, 22}, {b, 3}, {c ,4, 44}] 得到[{a,[1]},{b,[2,22,3]},{c,[4,44]}]
我快一年没写erlang,生疏了不少,不过试了一下,基本语法还没忘掉。
这样写能基本满足要求,写法不唯一。
%% 请写一个函数输入 任意包含二元组和三元组得列表与键,
%% 用列表的形式返回该键所对应得所有值
%% (不使用API,++,--)
%% 例如
%% [{a, 1}, {b, 2, 22}, {b, 3}, {c ,4, 44}]
%% 得到
%% [{a,[1]},{b,[2,22,3]},{c,[4,44]}]
-module(t).
-export([test/1,test_input/0]).
test_input()->
test([{a, 1}, {b, 2, 22}, {b, 3}, {c ,4, 44}]).
test(Input)->
test_(Input,[]).
%% 循环处理输入的数据
test_([H|Tail],L)->
L2 = add_list(H,L,[]),
test_(Tail,L2);
%% 处理完毕返回结果
test_([],L) ->
L.
%% 二元组匹配上了
add_list({Key,V1},[{Key,List}|Tail],L2)->
add_list(ok,[{Key,[V1|List]}|Tail],L2);
%% 二元组没有匹配上
add_list({K1,V1},[],L2)->
add_list(ok,[],[{K1,[V1]}|L2]);
%% 三元组匹配上了
add_list({Key,V1,V2},[{Key,List}|Tail],L2)->
List2 = [V1|List],
add_list(ok,[{Key,[V2|List2]}|Tail],L2);
%% 三元组没有匹配上
add_list({K1,V1,V2},[],L2)->
add_list(ok,[],[{K1,[V1,V2]}|L2]);
%% 都没有匹配上,移交给L2
add_list(KV,[H|Tail],L2)->
add_list(KV,Tail,[H|L2]);
%% 处理完毕,合并两列表
add_list(ok,R,L2) -> merge_list(R,L2,[]).
%% 合并列表
merge_list([H|T],B,L2)->
merge_list(T,B,[H|L2]);
merge_list([],[H|T],L2)->
merge_list([],T,[H|L2]);
merge_list([],[],L)-> L.
2023年10月10日12:39:59
补充 - 评论下方有人留言
用列表输出在列表或元组中查找到的的所有重复元素
我都快两年没正经写erlang了,没想到手感还在。
-module(t).
-export([test/0, find_repeate/1]).
test()->
{
%% 测试列表,2和4重复
find_repeate([1,2,3,2,4,5,4,6,7]),
%% 测试元组,2和4重复
find_repeate({1,2,3,2,4,5,4,6,7})
}.
%% 用列表输出在列表或元组中查找到的的所有重复元素
find_repeate(MyList) when is_list(MyList)->
% 如果传入的是列表
ffind_(MyList, MyList, []);
find_repeate(MyTuple) when is_tuple(MyTuple)->
% 如果传入的是元组
MyList = tuple_to_list(MyTuple),
ffind_(MyList, MyList, []);
find_repeate(_) ->
[].
ffind_([H|T],CopyList,RepList)->
% 传入的值在列表中匹配
CopyList2 = lists:delete(H, CopyList),
case lists:member(H, CopyList2) and not lists:member(H, RepList) of
true ->
RepList2 = [H|RepList];
false ->
RepList2 = RepList
end,
ffind_(T,CopyList,RepList2);
ffind_([],_,RepList)->
RepList.
Q&A
先说说我使用了哪些“API”,如上我给出的代码,我使用了is_list、is_tuple、tuple_to_list、lists:delete、lists:member共5个方法。
再来说说不准用api,既然你参加的是考核,那么考察的是你对erlang语言的使用熟练度,
这里不让你用api,显然是不让你使用的是lists库或其他库函数。erlang语言本身就这么点东西,我们普遍认为内置函数不属于考核的api,比如:is_list、is_tuple、tuple_to_list、element等
那么剩下的就lists:delete、lists:member
这位小伙伴我实在不知道该怎么说你,或许是伸手党做习惯了,亦或许你根本没有思考的习惯,本文章第25题就有现成的lists:member方法的实现。
至于lists:delete在本题中稍加思考完全可以省去。
-module(x).
-export([test/0, find_duplicates/1]).
test()->
{
find_duplicates([1,2,3,2,4,5,4,6,7]),
find_duplicates({1,2,3,2,4,5,4,6,7})
}.
find_duplicates(List) when is_list(List)->
find_duplicates(List, []);
find_duplicates(Tuple) when is_tuple(Tuple)->
find_duplicates(tuple_to_list(Tuple), []).
find_duplicates([], Duplicates) ->
Duplicates;
find_duplicates([H | T], Duplicates) ->
case my_member(H, T) and not my_member(H, Duplicates) of
true ->
find_duplicates(T, [H|Duplicates]);
false ->
find_duplicates(T, Duplicates)
end.
my_member(E, [E | _]) ->
true;
my_member(E, [_ | T]) ->
my_member(E, T);
my_member(_, []) ->
false.
最后是lists库里的API不都开源的吗?你甚至都不愿意百度一下,但是愿意来我这留评论。
lists:delete/2 - 从列表里面删除一个元素 - Erlang/OTP 中文手册(Erldoc.com)
最后的最后我想吐槽一下,AI这么好用,你完全可以找它试一下,咱不说国外的GPT,咱就说国内的,这是百度的AI。
虽然你要进的多半是混日子公司,但是如果没有自己的学习思考能力,你可能连混日子的门槛都达不到。