我正在尝试为数组数组生成所有排列,并将返回值作为List返回。我认为因为函数是递归的,所以我不能声明List<>要在DoPermute
方法本身返回,所以我已经定义了List<>作为Permutation
的财产。该类的代码如下所示:
class Permutation
{
// Constructors
public Permutation()
{
}
// build permutations of input array
public void DoPermute(ref byte[] digits, ref int n, ref int i)
{
if (i == n)
{
long temp = Numbers.JoinDigits(digits);
Permutations.Add(temp);
}
else
{
for (int j = i; j < n; j++)
{
SwapValues(ref digits, ref i, ref j);
int temp = i + 1;
DoPermute(ref digits, ref n, ref temp);
SwapValues(ref digits, ref i, ref j);
}
}
}
public List<long> Permutations { get; set; }
}
我使用以下行调用代码,但是出现错误。
byte[] num = { 1, 2, 3, 4, 5 };
int len = num.Length;
int zero = 0;
Permutation p = new Permutation();
p.DoPermute(ref num, ref len, ref zero);
List<long> permuts = p.Permutations;
但是,如果将DoPermute
方法重新声明为静态,并使用简单Permutations.Add(temp);
替换Debug.WriteLine(temp);
,我会获得正确的排列列表。
关于我哪里出错的任何建议?
答案 0 :(得分:2)
首先,您需要在某处创建排列列表:Permutations = new List<long>();
。
其次,如果您希望让方法返回列表而不是定义公共属性,您可以这样做:
public static List<long> DoPermute(ref byte[] digits, ref int n, ref int i)
{
List<long> permuts = new List<long>();
DoPermuteWorker(permuts, ref digits, ref n, ref i);
return permuts;
}
private static void DoPermuteWorker(List<long> permuts, ref byte[] digits, ref int n, ref int i)
{
if (i == n)
{
long temp = Numbers.JoinDigits(digits);
permuts.Add(temp);
}
else
{
for (int j = i; j < n; j++)
{
SwapValues(ref digits, ref i, ref j);
int temp = i + 1;
DoPermuteWorker(permuts, ref digits, ref n, ref temp);
SwapValues(ref digits, ref i, ref j);
}
}
}
答案 1 :(得分:1)
您当前的代码因空引用异常而失败,因为您从未实例化该列表。你应该在你的构造函数中这样做。
但是,我更喜欢这个作为静态方法。使用属性作为排列列表对我来说感觉不对。为了完成这项工作,您需要将排列列表作为参数添加到递归函数中。并且列表需要由调用者实例化。
所以我认为你的函数应该像这样声明:
public static void DoPermute(List<long> Permutations, ref byte[] digits,
ref int n, ref int i)
函数内部的代码可以保持基本不变,并且只要它进行递归调用就需要在列表中传递。我不会在这里重复你的代码,因为我认为应该明白我的意思。
答案 2 :(得分:0)
我认为您获得NullReferenceException
,因为您的列表未初始化。
这段代码应该解决它;
/// <summary>
/// Computes a permutation of ...
/// </summary>
class Permutation
{
/// <summary>
/// Initializes a new instance of the <see cref="Permutation"/> class.
/// </summary>
public Permutation()
{
Permutations = new List<long>(20); // you can set here your capacity.
}
/// <summary>
/// Builds permutations of a byte array.
/// </summary>
/// <param name="digits">The digits</param>
/// <param name="n">The n</param>
/// <param name="i">The i</param>
public void DoPermute(ref byte[] digits, ref int n, ref int i)
{
if (i == n)
{
long temp = Numbers.JoinDigits(digits);
Permutations.Add(temp);
}
else
{
for (int j = i; j < n; j++)
{
SwapValues(ref digits, ref i, ref j);
int temp = i + 1;
DoPermute(ref digits, ref n, ref temp);
SwapValues(ref digits, ref i, ref j);
}
}
}
/// <summary>
/// Gets the permuation result.
/// </summary>
public List<long> Permutations { get; private set; }
}