8

それが質問をする最善の方法だと思います。詳細は以下のとおりです。質問の仕方を理解するだけで 1 時間かかりました。

5 種類 (またはそれ以上) のテキスト ファイルがあるとします。これらは科学機器によって生成され、それぞれに特定の結果が含まれています。これらの「タイプ」を A、B、C、D、E と呼びましょう。テキスト ファイルの実際の名前はこれを示していないため、ユーザーは名前だけでそれらが何であるかを簡単に確認できません。それが簡単なら、「文字列」のリストを考えることができます。{ replcate 型についてどうすればよいかわかりませんが、後で心配します)

テキスト ファイルをコングロマリット ファイルに結合するオプションをユーザーに提供したいと考えていますが、問題は、特定のタイプを結合する意味がないことです (理由を説明する価値がないため)。

互換性のマトリックスを作成し、例を示しました

        A   B   C   D   E
   A    1   1   1   1   0
   B    1   1   1   0   0
   C    1   1   1   1   0
   D    1   0   1   1   1
   E    0   0   0   1   1

つまり、これは、A を B、C、D と組み合わせることはできますが、E (など) を組み合わせることはできないということです。

ここで、ユーザーがファイルのリストから「A、B、および C」タイプのファイル (明らかにタイプされていないファイル) を選択した場合、選択内容を確認し、「はい、ABC は合法的なマージです」と言って、マージ。

ユーザーが A、B、C、D を選択した場合、いいえ、D は B と互換性がないため、それを行うことはできません - ただし、A、B、C または A、C、D を行うことはできます。 (D は B の場所であってはなりません)。

まだ私と一緒に?

私は上記のマトリックスをコードで作成しましたが、ループ構造になってしまい、少し混乱し始め、家や家族を失う前に助けを求めるかもしれないと考えました. どのように選択しようとしているかについて、かなり大きなコメント セクションがあります。「A」は「犬」、「B」は「猫」などになる可能性があることに注意してください。

internal class CompatibilityCheck
{
    private List<string> FileTypes;

    public CompatibilityCheck()
    {
        //Strings are unique types for text files
        FileTypes = new List<string> {"A", "B", "C", "D", "E"};
        int[,] CompatibilityMatrix =
            {
                {1, 1, 1, 1, 0},
                {1, 1, 1, 0, 0},
                {1, 1, 1, 1, 0},
                {1, 0, 1, 1, 1},
                {0, 0, 0, 1, 1}
            };

        /* Scenario 1 */
        //List of file names from user = ALL LEGAL
        var userSelection = new List<string> {"A", "B", "C"};
        /* Go through each item in userSelection and make arrays of "legal" file combinations?
         * start with A and find the compatible matches, B and C.  Check that B and C are okay. 
        * Answer should look like this as A, B and C can be combined */

        /* Scenario 2 */
        // List of file names from user = NOT ALL LEGAL => D and B are incompatible
        var userSelection2 = new List<string> {"A", "B", "C", "D"};
        /* In my head, I go through each item in userSelction2
         * Take A and build "A,B,C,D" as it is compatible
         *  check B with C(yes) and D(no) - remove D.
         *      end [ A,B,C ]
         *          
         * Start with B and build B,A,C
         *  check A with C(yes) 
         *      end [ B,A,C ]
         *          
         * Start with C and build C,A,B
         *  check A with B(yes)
         *      end [C,A,B]
         *      
         * Start with D and build D,A,C
         *  check A with C(yes)
         *      end [D,A,C]
         *      
         * take the nth string and compare to n+1, n+2 ... n+(length-n)
         *  
         * the unique string sets woudld be  A , B , C and A , C , D  
         */
    }
}

これが明確であることを願っています。では、そのようなタスクを達成するための最良の方法は何ですか? 再帰、LINQ「魔法」、行列演算?

[編集:] 実装が簡単なアイデアは、ファイルのリストを表示し、ユーザーがそれらを選択すると、互換性のない他の選択肢を「非アクティブ化」することです。「A」タイプを選択するlistBoxなどを想像してください。上記のマトリックスが有効な場合、タイプ「E」ファイルはグレー表示されます。これでストレスが減るかな…?

4

2 に答える 2

2

これを確認したり、コードをリファクタリングしたりする時間があまりなかったので、これは頭の痛い問題ですが、開始して少しすっきりしたものにリファクタリングするのに適した場所かもしれません。

public class StrongFileType
{
    private string _friendlyName = string.Empty;

    public StrongFileType(string friendlyName)
    {
        _friendlyName = friendlyName;
    }

    public IEnumerable<StrongFileType> CompatibleTypes { get; set; }

    public override string ToString()
    {
        return _friendlyName;
    }
}

private void SampleTest()
{
    // The possible types
    var typeA = new StrongFileType("A");
    var typeB = new StrongFileType("B");
    var typeC = new StrongFileType("C");
    var typeD = new StrongFileType("D");
    var typeE = new StrongFileType("E");

    // Setup possible compatible types
    typeA.CompatibleTypes = new List<StrongFileType> { typeA, typeB, typeC, typeD };
    typeB.CompatibleTypes = new List<StrongFileType> { typeA, typeB, typeC };
    typeC.CompatibleTypes = new List<StrongFileType> { typeA, typeB, typeC, typeD };
    typeD.CompatibleTypes = new List<StrongFileType> { typeA, typeC, typeD, typeE };
    typeE.CompatibleTypes = new List<StrongFileType> { typeD, typeE };

    // Now do a check...
    var userSubmittedFilesValid = new List<StrongFileType> { typeA, typeB, typeC };
    CheckCompatible(userSubmittedFilesValid);
    var userSubmittedFilesInvalid = new List<StrongFileType> { typeA, typeB, typeC, typeD };
    CheckCompatible(userSubmittedFilesInvalid);
}

private bool CheckCompatible(IEnumerable<StrongFileType> requestedFiles)
{
    // Useful for debugging
    var validList = new List<string>();
    var invalidList = new List<string>();

    foreach (StrongFileType fileType in requestedFiles)
    {
        string invalid = string.Empty;
        string validCombination = string.Empty;

        foreach (StrongFileType fileTypeToCheck in requestedFiles)
        {
            if (!fileType.CompatibleTypes.Contains(fileTypeToCheck))
            {
                // Show as not compatible and remove any previously valid combinations that match
                invalid += string.Format("{0} not compatible with {1}", fileType, fileTypeToCheck);
                validList.RemoveAll(x => x.Contains(fileType.ToString()) && x.Contains(fileTypeToCheck.ToString()));
            }
            else
            {
                validCombination += string.Format("{0}", fileTypeToCheck);
            }
        }

        // Add to respective lists
        if (!string.IsNullOrEmpty(validCombination) && !validList.Contains(validCombination))
        {
            validList.Add(validCombination);
        }
        if (!string.IsNullOrEmpty(invalid))
        {
            invalidList.Add(invalid);
        }
    }

    // Was valid?
    return invalidList.Count == 0;
}

これにより、最初のABCの有効なリストが表示され、無効なリストは空になります。2つ目は、ABCとACDをVALIDとして、BDとDBをINVALIDとして表示する必要があります。

申し訳ありませんが、片付ける時間がありませんでした。

于 2012-10-31T11:56:14.110 に答える
2

クリークの問題、特に最大クリークの問題を見ています。

これを解決するために使用できるアルゴリズムはありますが、指数時間よりも優れたアルゴリズムはまだありません。

あなたの編集ははるかに良いアイデアのように思えます - 進むにつれて選択肢を制限するのがより簡単になるはずです。

于 2012-10-31T11:46:44.760 に答える