为什么我不能在程序中改变矩阵?

问题描述:

我的任务是使用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: 

这里是remove元素过程:

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; 
+1

它看起来像removeElement返回一个新的数组,而不是修改现有的。每次调用该过程时都需要使用返回值。 – 2014-10-03 22:45:41

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

如果您只是在调用该过程的代码中丢弃该值,那么将过程的返回值没有意义。这就是你在做的。

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

solveSudoku,你叫removeElement线或许应该这样来使用,而不是,

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

另外,通过对MremoveElement不是入门M[k,j]的价值。即,

removeElement(M, k, j, index); 

solveSudoku通话,然后里面removeElement类似,

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

当然,你应该只把这些方法中的一种:其中,项M[k,j]solveSudoku被更新的第一种方式,或者在removeElement更新的第二种方式。

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