【erlang】 40道语法基础练习题

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等

参考erlang内置函数

那么剩下的就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。

虽然你要进的多半是混日子公司,但是如果没有自己的学习思考能力,你可能连混日子的门槛都达不到。

  • 8
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 21
    评论
评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值