Функция, которая генерирует строки в соответствии с входными данными

StackOverflow https://stackoverflow.com/questions/2484345

  •  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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top