Erlang 无法使用huffman对示例文本进行正确编码

Erlang 无法使用huffman对示例文本进行正确编码,erlang,pattern-matching,Erlang,Pattern Matching,问题出现在find函数中,erlang shell告诉我发生了异常错误,它说: 异常错误:没有与函数seminar1:encode/3(seminar1.erl,第113行)中的seminar1:find(“t”,[])(seminar1.erl,第117行)匹配的函数子句。 我相信现在发生的事情是,在第一个find函数中完成的模式匹配总是失败,尽管我不理解为什么手动进行比较的尝试已经成功 -module(seminar1). -compile(export_all). sample() -&

问题出现在
find
函数中,erlang shell告诉我发生了异常错误,它说:

异常错误:没有与函数seminar1:encode/3(seminar1.erl,第113行)中的seminar1:find(“t”,[])(seminar1.erl,第117行)匹配的函数子句。

我相信现在发生的事情是,在第一个
find
函数中完成的模式匹配总是失败,尽管我不理解为什么手动进行比较的尝试已经成功

-module(seminar1).
-compile(export_all).

sample() -> "the quick brown fox jumps over the lazy dog
this is a sample text that we will use when we build
up a table we will only handle lower case letters and
no punctuation symbols the frequency will of course not
represent english but it is probably not that far off".

text() -> "this is something that we should encode".

test() ->
Sample = sample(),
Tree = tree(Sample),
Encode = encode_table(Tree),
Decode = decode_table(Tree),
Text = text(),
Seq = encode(Text, Encode),
Text = decode(Seq, Decode).


tree(Sample) -> Freq = freq(Sample),

            F = fun({node,N1,V1,_,_}, {node,N2,V2,_,_}) -> 
                    if
                        V1 > V2 -> false;
                        V1 == V2 -> if
                                    N1 > N2 -> false;
                                    true -> true
                                    end;
                        true -> true
                    end 
                end,
            %lists:sort(F,Freq).
            huffman(lists:sort(F,Freq)).


% Calculate the frequency of each letter in the Sample and return a 
datastructure of nodes containing the letter involved,
% frequency of it in the sample.
% datastructure {node, Key, Value, Left, Right}
freq(Sample) -> freq(Sample, []).

freq([], Freq) -> Freq;
freq([Char|Rest], Freq) ->  freq(Rest, check(Char, Freq)).

% Check function complements the Freq function, it takes the current input 
and pattern matches it with the frequency datastructue being built.
% If it scores a hit that particular node has its frequency incremented and 
then the whole datastructure is returned.
check(Key, []) -> [{node, [Key], 1, nil, nil}];
check(Key, [{node, [Key], Value, nil, nil}| Tail]) -> [{node, [Key], Value + 
1, nil, nil}| Tail];
check(Key, [H|T]) -> [H |check(Key, T)].

% Creates the Huffman tree that is later used to encode a sample.
% The input is the SORTED datastructure derived from the freq-function.
% The leaves of the huffman tree are where actual values reside, branches 
are just nodes containing information.
huffman( [ Tree | [] ] ) -> Tree;

huffman([{node, LeftKey, LeftValue, _L1, _R1}, 
     {node, RightKey, RightValue, _L2, _R2} |Tail]) ->

    % Creating a branch node
    BranchNode = {node, LeftKey ++ RightKey, LeftValue + RightValue, {node, 
LeftKey, LeftValue, _L1, _R1}, {node, RightKey, RightValue, _L2, _R2}},

    huffman(insert(BranchNode, Tail)).

% A complementary function to the huffman function, inserts the newly made 
branchnode into the already sorted tail.
% This is to prevent the sorted tail from becoming unsorted when turning the 
tail list into a tree.
% It is inserted as such that the branchnode is the first selection of its 
current value, 
% meaning that if you have 4 nodes of value 5 ( one being a branchnode) then 
the branch node will be the first option.
% This will make the Tree structure left leaning.
%
%             N
%         N       N
%      N    N   
%     N N   N N
insert(Node, []) -> [Node|[]];

insert(Node, [H|T]) ->
    {_, _, Nvalue, _, _} = Node,
    {_, _, Hdvalue, _, _} = H,
    if
        Nvalue =< Hdvalue -> [ Node | [H|T]];
        true -> [H | insert(Node, T)]
    end.



% Takes the tree created by the huffman-function as input and traverses said 
tree.
% Returns a list containing the letters found and their position in the 
tree, Left = 0, Right = 1.
% {"e"/[101], [0,0,0]} -- {[Key], [pathway]}
% Traversal method used: Left based traversal.
encode_table(RootNode) -> encode_table(RootNode, [], []).

% When traversing the Tree I need to know the branchnode I am in, the result 
list as I am adding letters to it and a PathwayList which is the current 
binary path to the branchnode I am in.
encode_table({_, Key, _, nil, nil}, AccList, PathwayList) ->
    [AccList | [{Key, reverse(PathwayList)}]];
encode_table({_, _, _, Left, Right}, AccList, PathwayList) ->
    encode_table(
        Right, 
        encode_table(Left, AccList, [0| PathwayList]), 
        [1|PathwayList]).

% Complementary function for the encode_table/3 function, when traversing 
the tree the the pathway gets reversed so it needs to be corrected.
reverse(L) -> reverse(L, []).
reverse([], Rev) -> Rev;
reverse([H|T], Rev) -> reverse(T, [H|Rev]).


% Takes a sample text and encodes it in accordance to the encoding table 
supplied
encode(Text, Table) -> encode(Text, Table, []).

encode([], _, EncodedText) -> EncodedText;
encode([Letter|Rest], Table, EncodedText) ->
    encode(Rest, Table, [find([Letter], Table) | EncodedText]).

% Complementary function to encode/3, searches the Table for the related 
Letters binary path.
%find(Letter, []) -> Letter;
find(Letter, [{Letter, BinaryPath} | _Rest]) -> 
    BinaryPath;
find(Letter, [ _ | Rest]) -> 
    find(Letter, Rest).

decode_table(tree) -> ok.
decode(sequence, table) -> ok.

test(Letter, [{Letter, Asd} | []]) ->
    true;
test(_, _) -> false.
-模块(seminar1)。
-编译(全部导出)。
sample()->“敏捷的棕色狐狸跳过了懒狗
这是一个示例文本,我们将在构建时使用它
在表格上,我们只处理小写字母和
没有标点符号的频率当然不会
代表英语,但可能并不遥远”。
text()->“这是我们应该编码的东西”。
测试()->
Sample=Sample(),
树=树(样本),
Encode=编码表(树),
解码=解码表(树),
Text=Text(),
Seq=编码(文本,编码),
Text=解码(Seq,decode)。
树(样本)->Freq=Freq(样本),
F=fun({node,N1,V1,{node,N2,V2,{,})->
如果
V1>V2->false;
V1==V2->if
N1>N2->false;
真->真
结束;
真->真
结束
完,,
%列表:排序(F,Freq)。
哈夫曼(列表:排序(F,Freq))。
%计算样本中每个字母的频率并返回
包含相关字母的节点的数据结构,
%它在样本中的频率。
%数据结构{节点,键,值,左,右}
频率(样本)->频率(样本,[])。
freq([],freq)->freq;
freq([Char | Rest],freq)->freq(Rest,check(Char,freq))。
%检查功能是对Freq功能的补充,它接受当前输入
模式将其与正在构建的频率数据结构相匹配。
%如果它获得了命中率,则该特定节点的频率将增加,并且
然后返回整个数据结构。
检查(Key,[])->[{node,[Key],1,nil,nil}];
检查(键,[{node,[Key],Value,nil,nil}| Tail])->[{node,[Key],Value+
1,零,零}|尾];
检查(键[H | T])->[H |检查(键,T)]。
%创建哈夫曼树,稍后用于对样本进行编码。
%输入是从freq函数派生的排序数据结构。
%哈夫曼树的叶子是实际值所在的地方,分支
只是包含信息的节点。
哈夫曼([Tree |[])->Tree;
哈夫曼([{node,LeftKey,LeftValue,_L1,_R1},
{node,RightKey,RightValue,_L2,_R2}| Tail])->
%创建分支节点
BranchNode={node,LeftKey++RightKey,LeftValue+RightValue,{node,
LeftKey,LeftValue,_L1,_R1},{node,RightKey,RightValue,_L2,_R2},
哈夫曼(插入(分支节点,尾部))。
%作为哈夫曼函数的补充函数,插入了新生成的
将branchnode插入已排序的尾部。
%这是为了防止已分拣的尾部在转弯时变为未分拣
将尾部列表放入树中。
%插入时,branchnode是其分支的第一个选择
当前值,
%这意味着如果有4个值为5的节点(一个是branchnode),那么
分支节点将是第一个选项。
%这将使树结构向左倾斜。
%
%N
%N N
%N N
%不
插入(节点,[])->[节点|[];
插入(节点[H | T])->
{{uu,{uu,Nvalue,{uu,}=Node,
{{uu,{uu,Hdvalue,{uu,}=H,
如果
Nvalue=[Node |[H | T]];
true->[H |插入(节点,T)]
结束。
%将huffman函数创建的树作为输入并遍历
树。
%返回一个列表,其中包含找到的字母及其在列表中的位置
树,左=0,右=1。
%{“e”/[101],[0,0,0]}--{[Key],[path]}
%使用的遍历方法:基于左的遍历。
编码_表(RootNode)->编码_表(RootNode,[],[])。
%当遍历树时,我需要知道我所在的分支节点,以及结果
列表,因为我正在向其中添加字母和当前路径的PathwayList
我所在分支节点的二进制路径。
编码_表({uu,Key,u,nil,nil},AccList,PathwayList)->
[AccList |[{键,反向(路径列表)}];
编码表({{{},{,},左,右},AccList,PathwayList)->
编码表(
正确的,
编码_表(左,AccList,[0|路径列表]),
[1 |路径列表])。
%遍历时,encode_table/3函数的补充函数
这棵树的路径颠倒了,所以需要纠正。
反向(L)->反向(L,[])。
反向([],Rev)->Rev;
反向([H | T],Rev)->反向(T[H | Rev])。
%获取示例文本并根据编码表对其进行编码
提供
编码(文本,表格)->编码(文本,表格,[])。
encode([],[编码文本)->EncodedText;
编码([Letter | Rest],表,EncodedText)->
编码(Rest,Table,[find([Letter],Table)| EncodedText])。
%编码的补充功能/3,在表格中搜索相关的
字母的二进制路径。
%查找(字母,[])->字母;
查找(字母,[{Letter,BinaryPath}|_Rest])->
二进制路径;
查找(字母,[[u124; Rest])->
找到(信,其余)。
解码表(树)->确定。
解码(序列、表格)->正常。
测试(字母,[{字母,Asd}|[])->
是的;
测试(,)->错误。

我试图按照您的代码进行操作,但是我被困在函数
解码表(树)->上了。
。使用这种拼写,它会失败(
tree
是一个原子,除了
tree
本身之外,它不会匹配任何东西)。当我了解到解码功能尚未编写或未提供时,更改为
\u Tree
以忽略该问题

对于编码,问题在于函数encode_table返回一个嵌套列表,不适合find函数。如果你更换
-module(seminar1).
-compile(export_all).

sample() -> "the quick brown fox jumps over the lazy dog
this is a sample text that we will use when we build
up a table we will only handle lower case letters and
no punctuation symbols the frequency will of course not
represent english but it is probably not that far off".

text() -> "this is something that we should encode".

test() ->
Sample = sample(),
Tree = tree(Sample),
Encode = encode_table(Tree),
%Decode = decode_table(Tree),
Text = text(),
Seq = encode(Text, Encode),
%Text = decode(Seq, Decode).
Seq.

tree(Sample) -> Freq = freq(Sample),

            F = fun({node,N1,V1,_,_}, {node,N2,V2,_,_}) ->
                    if
                        V1 > V2 -> false;
                        V1 == V2 -> if
                                    N1 > N2 -> false;
                                    true -> true
                                    end;
                        true -> true
                    end
                end,
            %lists:sort(F,Freq).
            huffman(lists:sort(F,Freq)).


% Calculate the frequency of each letter in the Sample and return a
% datastructure of nodes containing the letter involved,
% frequency of it in the sample.
% datastructure {node, Key, Value, Left, Right}
freq(Sample) -> freq(Sample, []).

freq([], Freq) -> Freq;
freq([Char|Rest], Freq) ->  freq(Rest, check(Char, Freq)).

% Check function complements the Freq function, it takes the current input
% and pattern matches it with the frequency datastructue being built.
% If it scores a hit that particular node has its frequency incremented and
% then the whole datastructure is returned.
check(Key, []) ->
    [{node, [Key], 1, nil, nil}];
check(Key, [{node, [Key], Value, nil, nil}| Tail]) ->
    [{node, [Key], Value + 1, nil, nil}| Tail];
check(Key, [H|T]) ->
    [H |check(Key, T)].

% Creates the Huffman tree that is later used to encode a sample.
% The input is the SORTED datastructure derived from the freq-function.
% The leaves of the huffman tree are where actual values reside, branches
% are just nodes containing information.
huffman( [ Tree | [] ] ) -> Tree;

huffman([{node, LeftKey, LeftValue, _L1, _R1},
         {node, RightKey, RightValue, _L2, _R2} |Tail]) ->

    % Creating a branch node
    BranchNode = {node, LeftKey ++ RightKey, LeftValue + RightValue, {node, LeftKey, LeftValue, _L1, _R1}, {node, RightKey, RightValue, _L2, _R2}},

    huffman(insert(BranchNode, Tail)).

% A complementary function to the huffman function, inserts the newly made
% branchnode into the already sorted tail.
% This is to prevent the sorted tail from becoming unsorted when turning the
% tail list into a tree.
% It is inserted as such that the branchnode is the first selection of its
% current value,
% meaning that if you have 4 nodes of value 5 ( one being a branchnode) then
% the branch node will be the first option.
% This will make the Tree structure left leaning.
%
%             N
%         N       N
%      N    N
%     N N   N N
insert(Node, []) -> [Node|[]];

insert(Node, [H|T]) ->
    {_, _, Nvalue, _, _} = Node,
    {_, _, Hdvalue, _, _} = H,
    if
        Nvalue =< Hdvalue -> [ Node | [H|T]];
        true -> [H | insert(Node, T)]
    end.



% Takes the tree created by the huffman-function as input and traverses said tree.
% Returns a list containing the letters found and their position in the
% tree, Left = 0, Right = 1.
% {"e"/[101], [0,0,0]} -- {[Key], [pathway]}
% Traversal method used: Left based traversal.
encode_table(RootNode) -> lists:flatten(encode_table(RootNode, [], [])).

% When traversing the Tree I need to know the branchnode I am in, the result
% list as I am adding letters to it and a PathwayList which is the current
% binary path to the branchnode I am in.
encode_table({_, Key, _, nil, nil}, AccList, PathwayList) ->
    [AccList | [{Key, reverse(PathwayList)}]];
encode_table({_, _, _, Left, Right}, AccList, PathwayList) ->
    encode_table(
        Right,
        encode_table(Left, AccList, [0| PathwayList]),
        [1|PathwayList]).

% Complementary function for the encode_table/3 function, when traversing
% the tree the the pathway gets reversed so it needs to be corrected.
reverse(L) -> reverse(L, []).
reverse([], Rev) -> Rev;
reverse([H|T], Rev) -> reverse(T, [H|Rev]).


% Takes a sample text and encodes it in accordance to the encoding table supplied
encode(Text, Table) -> encode(Text, Table, []).

encode([], _, EncodedText) -> EncodedText;
encode([Letter|Rest], Table, EncodedText) ->
    encode(Rest, Table, [find([Letter], Table) | EncodedText]).

% Complementary function to encode/3, searches the Table for the related
% Letters binary path.
find(Letter, []) -> Letter;
find(Letter, [{Letter, BinaryPath} | _Rest]) ->
    BinaryPath;
find(Letter, [ _ | Rest]) ->
    find(Letter, Rest).

decode_table(_Tree) -> ok.
decode(sequence, table) -> ok.

test(Letter, [{Letter, _Asd} | []]) ->
    true;
test(_, _) -> false.
64> c(seminar1).             
{ok,seminar1}
65> rp(seminar1:test()).
[[0,0,0],
 [1,0,0,0,1,0],
 [0,1,1,1],
 [1,0,1,1,0,0],
 [0,1,0,0],
 [0,0,0],
 [1,1,1],
 [1,0,0,0,1,0],
 [1,0,0,1],
 [1,1,0,1,0],
 [0,1,1,1],
 [1,0,1,0,0],
 [0,1,0,1],
 [1,1,1],
 [0,0,0],
 [1,0,1,0,1],
 [1,1,1],
 [1,1,0,0],
 [0,0,1,1],
 [1,0,1,0,0],
 [1,1,0,0],
 [1,1,1],
 [1,0,0,0,0,0,0],
 [0,1,0,0],
 [1,1,0,1,1],
 [1,0,1,0,0],
 [1,1,0,0],
 [0,0,0],
 [1,0,0,0,1,1,1],
 [0,1,1,1],
 [0,1,0,1],
 [1,1,1],
 [0,1,0,1],
 [1,1,0,1,1],
 [1,1,1],
 [0,1,0,1],
 [1,1,0,1,1],
 [1,0,1,0,0],
 [1,1,0,0]]
ok
66>
encode_table({_, Key, _, nil, nil}, AccList, PathwayList) ->
    [AccList | [{Key, reverse(PathwayList)}]];
encode_table({_, Key, _, nil, nil}, AccList, PathwayList) ->
    [{Key, reverse(PathwayList)} | AccList];