0

入力として 2 つの文字列を受け取り、可能なすべての文字列の組み合わせの配列を返す C# 関数が必要です。

private string[] FunctionName(string string1, string string2) 
{
    //code
}

文字列の入力は次の形式になります。

string1:地下室

string2: a*f a

ここで必要なのは、String2 の文字を使用して (* 記号を無視して) 可能な文字列のすべての組み合わせを、次のように同じ文字位置に保持することです。

baaement, baaefent, baaefena, basefent, basemena, etc.

編集: これは宿題ではありません。私がやっているプログラムの一部にこの関数が必要です。以下は私がこれまでに持っているコードですが、いくつかのバグがあります。

static List<string> combinations = new List<string>();

static void Main(string[] args)
{
    //include trimming of input string
    string FoundRes = "incoming";
    string AltRes = "*2*45*78";
    List<int> loc = new List<int>();
    string word = "";


    for (int i = 0; i < AltRes.Length; i++)
    {
        if (AltRes[i] != '*')
        {
            loc.Add(i);
            word += AltRes[i];
        }
    }

    generate(word);
    string[] aaa = InsertSymbol(FoundRes, loc.ToArray(), AltRes, combinations);

    Console.WriteLine("input string: " + FoundRes);
    Console.WriteLine("Substitute string: " + AltRes);

    Console.WriteLine("============Output============");


    for (int j = 0; j < aaa.Length; j++)
    {

        Console.WriteLine(aaa[j]);
    }
    Console.ReadKey();
}//

private static void generate(string word)
{
    // Add this word to combination results set
    if (!combinations.Contains(word))
        combinations.Add(word);

    // If the word has only one character, break the recursion
    if (word.Length == 1)
    {
        if (!combinations.Contains(word))
            combinations.Add(word);
        return;
    }

    // Go through every position of the word
    for (int i = 0; i < word.Length; i++)
    {
        // Remove the character at the current position
        // call this method with the String
        generate(word.Substring(0, i) + word.Substring(i + 1));
    }
}//

private static string[] InsertSymbol(string orig, int[] loc, string alternative, List<string> Chars)
{
    List<string> CombinationsList = new List<string>();
    string temp = "";
    for (int i = 0; i < Chars.Count; i++)
    {
        temp = orig;
        for (int j = 0; j < Chars[i].Length; j++)
        {
            string token = Chars[i];

            if (alternative.IndexOf(token[j]) == loc[j])
            {
                temp = temp.Remove(loc[j], 1);
                temp = temp.Insert(loc[j], token[j].ToString());

                //     int pos = sourceSubst.IndexOf(token[j]);
                //     sourceSubst = sourceSubst.Remove(pos, 1);
                //     sourceSubst = sourceSubst.Insert(pos, ".");
            }
            else
            {
                temp = temp.Remove(alternative.IndexOf(token[j]), 1);
                temp = temp.Insert(alternative.IndexOf(token[j]), token[j].ToString());
            }
        }
        CombinationsList.Add(temp);
    }
    return CombinationsList.ToArray();
}//
4

4 に答える 4

2

それは宿題のように聞こえます。提案として、最初のパラメーターを無視し、2 番目の文字列のすべての可能な順列を取得することに集中します。オフになっているもの、オンになっているものなど。そのリストから、最初の文字列の文字を入れ替える方法を簡単に思いつくことができます。

その点で、私は機能の準備ができているのに、宿題の意味合いのために投稿したくないという不快な立場にあります。どなたかレビューしていただけると嬉しいです!技術的には、サブセットを生成するための汎用関数がたまたま既に存在していたため、2 つの関数が関係しています。

編集:OPは宿題ではないと言っているので、ここに私が思いついたものがあります. 2 つの関数の主張以来、少しリファクタリングされており、私は批判を受け入れる以上のものです。

using System;
using System.Collections.Generic;
using System.Text;

class Program
{
    static void Main()
    {
        string original = "phenomenal";
        string pattern = "*xo**q*t**";

        string[] replacements = StringUtility.GetReplacementStrings(original, pattern, true);

        foreach (string replacement in replacements)
            Console.WriteLine(replacement);

        Console.Read();
    }

    public static class StringUtility
    {
        public static string[] GetReplacementStrings(string original, string pattern, bool includeOriginal)
        {
            // pattern and original might not be same length
            int maxIndex = Math.Max(original.Length, pattern.Length);

            List<int> positions = GetPatternPositions(pattern, maxIndex, '*');
            List<int[]> subsets = ArrayUtility.CreateSubsets(positions.ToArray());
            List<string> replacements = GenerateReplacements(original, pattern, subsets);

            if (includeOriginal)
                replacements.Insert(0, original);

            return replacements.ToArray();
        }

        private static List<string> GenerateReplacements(string original, string pattern, List<int[]> subsets)
        {
            List<string> replacements = new List<string>();
            char[] temp = new char[original.Length];

            foreach (int[] subset in subsets)
            {
                original.CopyTo(0, temp, 0, original.Length);
                foreach (int index in subset)
                {
                    temp[index] = pattern[index];
                }

                replacements.Add(new string(temp));
            }

            return replacements;
        }

        private static List<int> GetPatternPositions(string pattern, int maxIndex, char excludeCharacter)
        {
            List<int> positions = new List<int>();

            for (int i = 0; i < maxIndex; i++)
            {
                if (pattern[i] != excludeCharacter)
                    positions.Add(i);
            }

            return positions;
        }
    }

    public static class ArrayUtility
    {
        public static List<T[]> CreateSubsets<T>(T[] originalArray)
        {
            List<T[]> subsets = new List<T[]>();

            for (int i = 0; i < originalArray.Length; i++)
            {
                int subsetCount = subsets.Count;
                subsets.Add(new T[] { originalArray[i] });

                for (int j = 0; j < subsetCount; j++)
                {
                    T[] newSubset = new T[subsets[j].Length + 1];
                    subsets[j].CopyTo(newSubset, 0);
                    newSubset[newSubset.Length - 1] = originalArray[i];
                    subsets.Add(newSubset);
                }
            }

            return subsets;
        }
    }
}
于 2010-03-20T19:15:38.730 に答える
0

それは大変な仕事なので、コードを書くのではなく、問題を解決する方法を提案するだけです。

文字をヒットするたびに 2 番目のパラメーターをループする場合は、最初の引数の文字または 2 番目の引数の文字を使用するオプションを選択する必要があります。これらすべてのオプチンをインデックスと一緒に収集します。変更されない最初の引数からの部分のリストを保持します。これらの 2 つのリストを反復処理して、考えられるすべての順列を作成します

于 2010-03-20T20:06:08.870 に答える
0

10 進数から 2 進数に変換されたコードは、ここからコピーされたストロンです。

static void Main()
{
    string string1 = "basement";
    string string2 = "**a*f**a";

    string[] result = GetCombinations(string1, string2);

    foreach (var item in result)
    {
        Console.WriteLine(item);
    }        

}

private static string[] GetCombinations(string string1, string string2)
{
    var list = new List<List<char>> { new List<char>(), new List<char>() };

    var cl = new List<char>();

    List<string> result = new List<string>();

    for (int i = 0; i < string1.Length; i++)
    {
        if (string2[i] == '*')
        {
            cl.Add(string1[i]);
        }
        else
        {
            list[0].Add(string1[i]);
            list[1].Add(string2[i]);
        }
    }

    int l = list[0].Count;

    for (int i = 0; i < (Int64)Math.Pow(2.0,l); i++)
    {
        string s = ToBinary(i, l);
        string ss = "";

        int x = 0;
        int y = 0;

        for (int I = 0; I < string1.Length; I++)
        {

            if (string2[I] == '*')
            {
                ss += cl[x].ToString();
                x++;
            }
            else
            {
                ss += (list[int.Parse(s[y].ToString())][y]);
                y++;
            }
        }
        result.Add(ss);
    }
    return result.ToArray<string>();
}

public static string ToBinary(Int64 Decimal, int width)
{
    Int64 BinaryHolder;
    char[] BinaryArray;
    string BinaryResult = "";

    while (Decimal > 0)
    {
        BinaryHolder = Decimal % 2;
        BinaryResult += BinaryHolder;
        Decimal = Decimal / 2;
    }

    BinaryArray = BinaryResult.ToCharArray();
    Array.Reverse(BinaryArray);
    BinaryResult = new string(BinaryArray);

    var d = width - BinaryResult.Length;

    if (d != 0) for (int i = 0; i < d; i++) BinaryResult = "0" + BinaryResult;

    return BinaryResult;
}
于 2010-03-20T20:36:23.660 に答える
-1

どのパスワード クラッカーをプログラムしますか? :)どうですか

if string2 contains '*'

    foreach(char ch in string1)
        replace first * with ch, 
        execute FunctionName 
else  
   print string2
于 2010-03-20T19:16:33.783 に答える