質問
2 つの文字列を入力として受け取り、文字列の可能なすべての組み合わせの配列を返す C# 関数が必要です。
private string[] FunctionName(string string1, string string2)
{
//code
}
入力される文字列は次の形式になります。
string1
:地下
string2
: ああ、ふある
ここで必要なのは、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();
}//
解決
これは宿題のような音を行います。提案として、私は、最初のパラメータを無視し第二文字列のすべての可能な順列を得ることに焦点を当てます。そのリストからなど、オン何、オフになって何を、あなたは簡単に最初の文字列の文字をスワップアウトする方法を考え出すことができます。
そのノートで、私は行く準備ができて機能を有するがために宿題含意のそれを投稿したくないの不快な位置にいます。でも、私はそれを確認するために誰かのための確かな愛をたい!そして技術的には、私はちょうどすでに転がっサブセットを生成するための汎用的な機能を持つことが起こったので、関与する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;
}
}
}
他のヒント
それはhopw仕事だから私だけではなく、コードを書くよりも、問題を解決するためにいくつかの方法をお勧めます。
あなたはループ2番目のパラメータ場合は、文字を打つたびに、あなたがいずれかのオプションを持っている最初の引数または第二の手紙からの手紙を使用します。インデックスと一緒にすべてのこれらのoptinを集めます。決して変わらない最初の引数からの部品のリストを保持します。作成されたすべての可能な順列
にこれら二つのリストthorugh反復バイナリの10進コードは変換ここからコピー<ストライキ>ストロンストライキ> A>。
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;
}
これは、パスワードクラッカー、あなたがプログラムにしたいですか? :) 方法については、
if string2 contains '*'
foreach(char ch in string1)
replace first * with ch,
execute FunctionName
else
print string2