我試圖讓,使用回溯在迷宮找到哈密爾頓路徑的程序。它應該返回數字編碼的迷宮路徑。問題是當一個堆棧回退時,其中一個變量(這是迷宮的表示)從調用繼承,而其他變量(即使它們被聲明爲相同的方式)不(這是好的)。我嘗試了幾個解決方法,包括通過製作一個單獨的類來實例化,並且包含調試消息。這裏的代碼有一些意見可以幫助。C#遞歸函數棧共享變量無處
using System;
namespace ConsoleApplication1
{
//I made a separate class for the function
class btr
{
public short[,] mz = new short[,] { };//tried to pull the variable out of the function, no success
public void bt(int i, int j, int l)
{
bool ok;
ok = true;
Console.WriteLine("in" + '\n' + Program.print(mz, l) + 'i' + i + 'j' + j + '\n'); //debug message for entering
if (i > 0 && mz[i - 1, j] == 0)
{
ok = false;
mz[i, j] = 1; // 1 aka go up
var x = new btr { };
//my attempt to avoid the problem by instantiating the function, no success...
x.mz = mz;
x.bt(i - 1, j, l);
//When this function exits the mz variable is copied to this one. Same for all the ifs below
}
if (j > 0 && mz[i, j - 1] == 0)
{
ok = false;
mz[i, j] = 2; //2 aka go left
var x = new btr { };
x.mz = mz;
x.bt(i, j - 1, l);
}
if (i < l && mz[i + 1, j] == 0)
{
ok = false;
mz[i, j] = 3;//3 aka go down
var x = new btr { };
x.mz = mz;
x.bt(i + 1, j, l);
}
if (j < l && mz[i, j + 1] == 0)
{
ok = false;
mz[i, j] = 4;//4 aka go right
var x = new btr { };
x.mz = mz;
x.bt(i, j + 1, l);
}
Console.WriteLine("out" + '\n' + Program.print(mz, l) + 'i' + i + 'j' + j + '\n'); //debug message for exiting
if (ok) //this is for printing the solution when it is found
{
mz[i, j] = 8;// 8 aka the end
foreach (int x in mz)
{
if (x == 0) { ok = false; break; }
}
if (ok)
Console.WriteLine("result" + '\n' + Program.print(mz, l));
}
}
}
class Program
{//this is just for preparing the first call
static short[,] test = new short[2, 2] { { 0, 0}, { 0, 0} };
static void Main(string[] args)
{
var x= new btr { };
x.mz = test;
x.bt(0,0,1);
}
public static string print(short[,] vr,int l)//casts my array into a string that can be printed
{
string s = "";
for (int i = 0; i <= l; i++)
{
for (int j = 0; j <= l; j++)
{
s += vr[i,j];
}
s += '\n';
}
return s;
}
}
}
我給作爲測試一個2x2迷宮沒有任何障礙(由試驗爲代表宣佈所有0),它應該輸出2個解決方案中,僅輸出一個和該溶液被「注入」到堆棧。這裏的輸出:
in
00
00
i0j0
in
30
00
i1j0
in
30
40
i1j1
in
30
41
i0j1
out
30
41
i0j1
result
38
41
out
38
41
i1j1
out
38
41
i1j0
out
38
41
i0j0
當函數退出迷宮,你可以看到保持38 41,而不是逐漸回落至00 00,以便更多的解決方案可以計算出來。我和j不受影響。
你正在改變相同的數組實例。 – SLaks
遞歸和不可變對於這些類型的算法都很有用,它們讓所有的事情都變得輕而易舉。您遇到的問題是由於您正在使用(可變)數組。您可以使用不可更改的不可變類型,也可以在每次將它遞交給新的遞歸調用時創建數組的新副本。 – InBetween
那麼我該如何創建一個新的實例呢? – LightningShock