Функция, которая генерирует строки в соответствии с входными данными
-
21-09-2019 - |
Вопрос
Мне нужна функция C #, которая принимает 2 строки в качестве входных данных и возвращает массив всех возможных комбинаций строк.
private string[] FunctionName(string string1, string string2)
{
//code
}
Вводимые строки будут иметь следующий формат:
string1
:подвал
string2
: a*fa
Теперь, что мне нужно, это все комбинации возможных строк, использующие символы в 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();
}//
Решение
Это действительно звучит как домашнее задание.В качестве предложения я бы проигнорировал первый параметр и сосредоточился на получении всех возможных перестановок второй строки.Что выключено, что включено и т.д.Из этого списка вы можете легко придумать способ замены символов первой строки.
На этой ноте я нахожусь в неудобном положении, когда функция готова к запуску, но я не хочу публиковать ее из-за необходимости выполнения домашнего задания.Хотя я бы очень хотел, чтобы кто-нибудь это просмотрел!И технически, здесь задействованы две функции, потому что у меня просто так получилось, что у меня уже есть универсальная функция для генерации подмножеств.
Редактировать:ОП говорит, что это не домашнее задание, так что вот что я придумал.Он был немного переработан с момента утверждения двух функций, и я более чем открыт для критики.
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, я бы только предложил какой-то способ решить проблему, а не писать код.
если вы зацикливаете второй параметр каждый раз, когда нажимаете на букву, вам придется выбирать либо букву из первого аргумента, либо букву из второго.соберите все эти оптинцы вместе с указателем.сохраните список частей из первого аргумента, которые никогда не изменятся.выполните итерацию по этим двум спискам, чтобы создать все возможные перестановки
Преобразованный десятичный код в двоичный представляет собой столон скопировано с здесь.
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