Erlang分布式反向字符串

Erlang分布式反向字符串,erlang,Erlang,我是erlang的新手,我不知道如何解决这个问题。 我需要通过将一个长字符串划分为N个子字符串来反转它,反转单个子字符串,然后将它们合并以获得原始字符串的反转。 每个子字符串都需要通过不同的进程反转 我的问题是: 1如何将字符串拆分为大小相等的N个子字符串? 2如何连接其他进程接收的字符串 有人能给我一个示例代码吗?这就是我所做的,但它缺少主要部分: % This function should split the string, spawn the processes % and recomb

我是erlang的新手,我不知道如何解决这个问题。 我需要通过将一个长字符串划分为N个子字符串来反转它,反转单个子字符串,然后将它们合并以获得原始字符串的反转。 每个子字符串都需要通过不同的进程反转

我的问题是: 1如何将字符串拆分为大小相等的N个子字符串? 2如何连接其他进程接收的字符串

有人能给我一个示例代码吗?这就是我所做的,但它缺少主要部分:

% This function should split the string, spawn the processes
% and recombine the results
reverse(Str, N) -> % ...

sub_reverse() ->
    receive
        { From, SubStr } -> From ! { self(), lists:reverse(SubStr) }
    end.

试试这样的

-module(stackoverflow).
-export([reverse/2, join/0, sub_reverse/2]).

reverse(Str, N) ->
    % A process joining the reversed substrings.
    JoinPID = spawn(stackoverflow, join, []),

    % The step size is the length of Str divided by N.
    % TODO Handle remainder.
    Step = string:length(Str) div N,

    % The split points are calculated from end to start of Str.
    SplitPoints = lists:seq(string:length(Str) - Step, 0, -Step),

    % For each split point, spwan a process that reverts the substring for the
    % split point.
    lists:foreach(fun(From) ->
                    Substr = string:slice(Str, From, Step),
                    spawn(stackoverflow, sub_reverse, [JoinPID, Substr])
                  end,
                  SplitPoints).

join() ->
    receive
        {reverse_str, ReverseStr} ->
            io:format("~s", [ReverseStr]),
            join()
    end.

sub_reverse(JoinPID, SubStr) ->
    JoinPID ! {reverse_str, lists:reverse(SubStr)}.
编辑


这种方法可行,但取决于spawend过程的顺序。如果它们返回时出现故障,join将接收故障部件。因此,一个可能的改进是使用From标记每个零件,以便join可以按照正确的顺序连接它们。这是留给读者的练习。

试试这样的方法

-module(stackoverflow).
-export([reverse/2, join/0, sub_reverse/2]).

reverse(Str, N) ->
    % A process joining the reversed substrings.
    JoinPID = spawn(stackoverflow, join, []),

    % The step size is the length of Str divided by N.
    % TODO Handle remainder.
    Step = string:length(Str) div N,

    % The split points are calculated from end to start of Str.
    SplitPoints = lists:seq(string:length(Str) - Step, 0, -Step),

    % For each split point, spwan a process that reverts the substring for the
    % split point.
    lists:foreach(fun(From) ->
                    Substr = string:slice(Str, From, Step),
                    spawn(stackoverflow, sub_reverse, [JoinPID, Substr])
                  end,
                  SplitPoints).

join() ->
    receive
        {reverse_str, ReverseStr} ->
            io:format("~s", [ReverseStr]),
            join()
    end.

sub_reverse(JoinPID, SubStr) ->
    JoinPID ! {reverse_str, lists:reverse(SubStr)}.
编辑


这种方法可行,但取决于spawend过程的顺序。如果它们返回时出现故障,join将接收故障部件。因此,一个可能的改进是使用From标记每个零件,以便join可以按照正确的顺序连接它们。这是留给读者的练习。

以下是我的答案:

-module(reverse).
-export([reverse/1, join/3, sub_reverse/3]).

reverse("") -> "";
reverse(Str) ->
    Step = ceil(string:length(Str) / 10),
    SplitPoints = lists:seq(0, string:length(Str) - 1, Step),

    JoinPid = spawn(reverse, join, [self(), [], length(SplitPoints)]),

    lists:foreach(
        fun (Start) ->
            IndexPos = Start div Step,
            SubStr = string:slice(Str, Start, Step),
            spawn(reverse, sub_reverse, [JoinPid, IndexPos, SubStr])
        end,
    SplitPoints),

    receive
        { joined, ReversedStr } -> io:format("~p", [ReversedStr])
    end.

join(ReversePid, Acc, N) ->
    case length(Acc) of
        N ->
            Parts = lists:sort(fun ({A, _}, {B, _}) -> A > B end, Acc),
            Str = string:join(lists:map(fun ({_, SubStr}) -> SubStr end, Parts), ""),
            ReversePid ! { joined, Str };
        _ ->
            receive
                {reversed, X} -> join(ReversePid, [X | Acc], N)
            end
    end.


sub_reverse(JoinPid, IndexPos, SubStr) ->
    JoinPid ! {reversed, { IndexPos, string:reverse(SubStr) } }.

以下是我的答案:

-module(reverse).
-export([reverse/1, join/3, sub_reverse/3]).

reverse("") -> "";
reverse(Str) ->
    Step = ceil(string:length(Str) / 10),
    SplitPoints = lists:seq(0, string:length(Str) - 1, Step),

    JoinPid = spawn(reverse, join, [self(), [], length(SplitPoints)]),

    lists:foreach(
        fun (Start) ->
            IndexPos = Start div Step,
            SubStr = string:slice(Str, Start, Step),
            spawn(reverse, sub_reverse, [JoinPid, IndexPos, SubStr])
        end,
    SplitPoints),

    receive
        { joined, ReversedStr } -> io:format("~p", [ReversedStr])
    end.

join(ReversePid, Acc, N) ->
    case length(Acc) of
        N ->
            Parts = lists:sort(fun ({A, _}, {B, _}) -> A > B end, Acc),
            Str = string:join(lists:map(fun ({_, SubStr}) -> SubStr end, Parts), ""),
            ReversePid ! { joined, Str };
        _ ->
            receive
                {reversed, X} -> join(ReversePid, [X | Acc], N)
            end
    end.


sub_reverse(JoinPid, IndexPos, SubStr) ->
    JoinPid ! {reversed, { IndexPos, string:reverse(SubStr) } }.

谢谢,我考虑的是纯递归方法,但是使用stdlib函数要容易得多。为了完整性,我发布了我的版本。谢谢,我考虑的是纯递归方法,但是使用stdlib函数要容易得多。我已经发布了完整的版本。