1

数字の配列のすべての順列を生成し、戻り値をリストとして返そうとしています。関数は再帰的であるため、DoPermuteメソッド自体で返される List<> を宣言できないと思われるため、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);

私が間違っている場所に関する提案はありますか?

4

3 に答える 3

2

まず、順列リストをどこかに作成する必要があります: Permutations = new List<long>();.

第 2 に、パブリック プロパティを定義する代わりに、メソッドがリストを返すようにしたい場合は、次のようにすることができます。

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);
        }
    }
}
于 2013-03-10T11:04:13.080 に答える
1

リストをインスタンス化しないため、現在のコードは null 参照例外で失敗します。コンストラクターでこれを行う必要があります。

ただし、これは静的メソッドとして使用することをお勧めします。順列のリストにプロパティを使用するのは、私には間違っているように感じます。その作業を行うには、順列のリストをパラメーターとして再帰関数に追加する必要があります。そして、リストは呼び出し元によってインスタンス化される必要があります。

したがって、関数は次のように宣言する必要があると思います。

public static void DoPermute(List<long> Permutations, ref byte[] digits, 
    ref int n, ref int i)     

関数内のコードはほとんど変更されず、再帰呼び出しを行うたびにリストを渡すだけで済みます。私が言いたいことは明らかであるべきだと思うので、ここであなたのコードを繰り返すことはしません。

于 2013-03-10T10:59:07.640 に答える
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; }

}
于 2013-03-10T11:02:49.777 に答える