You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Erlang中交换矩阵首行第二个元素与末行倒数第二个元素?

Erlang矩阵元素交换实现思路与代码修改

需求回顾

给定N阶方阵(N≥2),实现两种交换逻辑:

  • 多进程版本:通过独立进程执行子任务,遍历矩阵行共N次
  • 单进程版本:顺序编程,遍历矩阵行共2N次
    核心任务:交换首行第二个元素与末行倒数第二个元素,且全程不得使用计数器。

多进程实现(遍历N次)

修改思路

  1. 主进程拆分首行,提取需要交换的第二个元素B,保留首行剩余部分
  2. 启动子进程遍历剩余N-1行(加上主进程处理首行,总遍历次数N),找到末行后拆分出倒数第二个元素Y
  3. 子进程将Y发送给主进程,同时把末行的倒数第二个元素替换为B,再将处理后的行列表返回主进程
  4. 主进程用Y替换首行的第二个元素,拼接得到新矩阵

修改后的代码

mtr模块

-module(mtr).
-export([main1/1, main2/1, swap1/1, swap2/1, mtr_gn1/1]).

%% ver.1 多进程版本
main1(N) when N >= 2 ->
    timer:tc(mtr, swap1, [mtr_gn1(N)]).

swap1([[A|R1]|Rs]) when R1 /= [] ->
    B = hd(R1),
    RestOfFirstRow = tl(R1),
    Pid = self(),
    spawn(mtr1, ch, [Rs, B, Pid]),
    receive
        {y, Y} -> Y
    end,
    receive
        {list, L1} -> L1
    end,
    [[A, Y | RestOfFirstRow] | L1].

%% ver.2 单进程版本(后续补充)
main2(N) when N >= 2 ->
    timer:tc(mtr, swap2, [mtr_gn1(N)]).

swap2(Matrix) when is_list(Matrix), length(Matrix) >= 2 ->
    {B, Y} = first_pass(Matrix),
    second_pass(Matrix, B, Y).

% 矩阵生成函数
mtr_gn1(N) ->
    [lists:map(fun(X) -> X/100 end, lists:seq(1, N)) |
     [[R || R <- lists:seq(1, N)] || _K <- lists:seq(1, N-1)]].

mtr1模块

-module(mtr1).
-export([ch/3]).

ch(L, B, Pid) ->
    Pid ! {list, ch1(L, B, Pid)}.

ch1([LastRow], B, Pid) ->
    {InitOfLastRow, Y, Last} = split_last_two(LastRow),
    Pid ! {y, Y},
    [InitOfLastRow ++ [B, Last]];
ch1([X|L], B, Pid) ->
    [X|ch1(L, B, Pid)].

% 辅助函数:拆分列表为前置部分、倒数第二个元素、最后一个元素
split_last_two([X, Y]) ->
    {[], X, Y};
split_last_two([H|T]) ->
    {Init, SecondLast, Last} = split_last_two(T),
    {[H|Init], SecondLast, Last}.

单进程实现(遍历2N次)

修改思路

  1. 第一次遍历所有N行,提取首行第二个元素B和末行倒数第二个元素Y
  2. 第二次遍历所有N行,将首行第二个元素替换为Y,末行倒数第二个元素替换为B
  3. 两次遍历总次数为2N,符合题目要求

修改后的代码(补充到mtr模块)

% 第一次遍历:获取交换所需元素
first_pass([[A|R1]|Rs]) ->
    B = hd(R1),
    Y = get_last_second(Rs),
    {B, Y}.

get_last_second([LastRow]) ->
    {_, Y, _} = split_last_two(LastRow),
    Y;
get_last_second([_|Rs]) ->
    get_last_second(Rs).

% 第二次遍历:完成元素交换
second_pass([[A|R1]|Rs], B, Y) ->
    RestOfFirstRow = tl(R1),
    ModifiedFirstRow = [A, Y | RestOfFirstRow],
    ModifiedRs = modify_last_second(Rs, B),
    [ModifiedFirstRow | ModifiedRs].

modify_last_second([LastRow], B) ->
    {Init, _, Last} = split_last_two(LastRow),
    [Init ++ [B, Last]];
modify_last_second([R|Rs], B) ->
    [R|modify_last_second(Rs, B)].

% 复用拆分辅助函数
split_last_two([X, Y]) ->
    {[], X, Y};
split_last_two([H|T]) ->
    {Init, SecondLast, Last} = split_last_two(T),
    {[H|Init], SecondLast, Last}.

关键说明

  • 所有操作均通过列表拆分/拼接实现,未使用任何计数器
  • 多进程版本通过子进程处理剩余行,主进程负责首行修改,总遍历次数为N
  • 单进程版本通过两次完整遍历矩阵行,总遍历次数为2N,完全符合题目要求

内容的提问来源于stack exchange,提问作者Ted Mosby

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 23:37:03