【问题标题】:Why do I cannot mutate a matrix in procedure?为什么我不能在过程中改变矩阵?
【发布时间】:2014-10-03 22:28:51
【问题描述】:

我的任务是使用 Maple 解决一个 4x4 数独难题。我构造了一个 4x4 矩阵,其每个元素都是一个列表。每个列表包含数字 1、2、3、4。 我的算法是找到一个只包含一个数字的网格,并用它来消除水平和垂直网格中列表中的相同数字。

这是我的代码: 我使用了一个名为 removeElement 的过程来从列表中消除一个数字,但消除后似乎是一样的。矩阵是不可变的吗?如何解决? 另外,我使用了一个叫做tester的计数器来检查程序,看矩阵是否可变。

solveSudoku := proc(M)
local i; local j; local goAhead; local k; local index;
local tester; 
tester:=0;
while tester<10 do
    i:=1; j:=1;
    for i from 1 to 4 do
    for j from 1 to 4 do
       if(nops(M[i,j]) = 1) then 

            # The current matrix element has only one possibility 
            # cancel all possibilities in horizontal

            for k from 1 to 4 do
                #Every element of the matrix is a list
                #I was trying to remove a number from a list
                #the statement below DOES NOT remove number at all
                index:= hasElement(M[i,k],op(M[i,j]));

                if index <> -1 and k <> j then

                     removeElement(M[i,k],index);

                end if;
            end do:

            # now the horizontal numbers are eliminated 
            # cancel all possibilities in vertical
            k:=1;
            for k from 1 to 4 do
                index:= hasElement(M[k,j],op(M[i,j]));
                if index <> -1 and k <> i then

                   removeElement(M[k,j],index);

                end if;
            end do:

        end if;

    end do;
    end do;

    tester:=tester+1;
end do:

print (M);
end proc:

这里是删除元素的过程:

removeElement := proc(L,index)
    local boundary := index;
        if nops(L) <> 0 then
            return [op(1..boundary-1,L),op(boundary+1..,L)];
        end if;
    return [];
end proc;

【问题讨论】:

  • 看起来 removeElement 正在返回一个新数组,而不是修改现有数组。每次调用该过程时都需要使用返回值。

标签: math logic sudoku discrete-mathematics maple


【解决方案1】:

列表是不可变的;矩阵是可变的。要更正您的代码,您需要替换该行 removeElement(M[k,j],index);M[k,j]:= removeElement(M[k,j],index).

如果您只是在调用该过程的代码中丢弃该值,则为该过程提供返回值是没有意义的。这就是你所做的。

【讨论】:

    【解决方案2】:

    矩阵是可变的,但列表不是。正如所发布的,solveSudoku 正在将一个列表传递给removeElement,作为后者的参数L

    solveSudoku 中你调用removeElement 的那行应该改为这样使用,

    M[k,j] := removeElement(M[k,j],index);
    

    或者,将 M 传递给 removeElement 而不是条目 M[k,j] 的值。即,

    removeElement(M, k, j, index);
    

    solveSudoku 中调用,然后在removeElement 中调用类似的东西,

    M[k,j] := [op(1..boundary-1,L),op(boundary+1..,L)]; return NULL;
    

    当然,您应该只采用以下方法之一:第一种方法是在solveSudoku 中更新条目M[k,j],或者在removeElement 中更新它的第二种方法。

    注意。当您调用像F(...,M[k,j],...) 这样的过程时,您将矩阵条目M[k,j] 的值传递给F。但是,当您像 F(...,M,...) 这样调用时,您实际上是通过引用传递了 Matrix M。

    【讨论】:

      猜你喜欢
      • 2022-01-20
      • 2022-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-30
      • 1970-01-01
      相关资源
      最近更新 更多