-2

次のコードがあります。長さがmの文字列を指定し、可能な任意の位置(元の文字列の異なる文字間を含む)に「-」を追加して、長さnに拡張します。たとえば、「ABC」を指定して、6に拡張します。「--- ABC」、「-A-BC」、「-AB-C」、「-ABC-」、...になります。 ..、「AB --- C」、「ABC---」。

class Program
{
    // <summary>
    /// Grow a string to desired length with time limitation
    /// </summary>
    /// <param name="s"></param>
    /// <param name="length"></param>
    /// <param name="pad"></param>
    /// <param name="Padded"></param>
    public static bool ExtendToLen(string s, int length, char pad, ref List<string> Padded, ref Stopwatch timer, int timeOut)
    {
        if (s.Length == length)
        {
            Padded.Add(s);
            return true;
        }
        else if (s.Length > length)
        {
            return true;
        }
        else
        {
            List<int> pos = GetExceptPos(s, pad.ToString());
            pos.Sort();

            int count = -1;
            foreach (int p in pos)
            {
                if (timer.Elapsed.TotalSeconds > timeOut)
                {
                    return false;
                }

                //Debug.WriteLine(string.Format("pos:{0}", p), "PadToLength");
                count++;

                // Pad left 
                string leftPadStr = s.Substring(0, p) + pad + s.Substring(p);
                //Debug.WriteLine(string.Format("\tLeftPadStr:{0}", leftPadStr));
                bool go = ExtendToLen(leftPadStr, length, pad, ref Padded, ref timer, timeOut);
                if (go == false) { return false; }

                // Pad right at the last pos
                if (count == pos.Count - 1)
                {
                    string rightPadStr = s + pad;
                    go = ExtendToLen(rightPadStr, length, pad, ref Padded, ref timer, timeOut);
                    if (go == false) { return false; }
                }
            }
            return true;
        }
    }

    /// <summary>
    /// Find indexes of elements different from target str
    /// </summary>
    /// <param name="str"></param>
    /// <param name="excludeStr"></param>
    /// <returns></returns>
    private static List<int> GetExceptPos(string str, string excludeStr)
    {
        List<int> allIndexes = new List<int>();
        for (int i = 0; i < str.Length; i++)
        {
            allIndexes.Add(i);
        }

        return allIndexes.Except(str.IndexesOf(excludeStr)).ToList();
    }

    static void Main(string[] args)
    {
        string old = "ACGUA";
        List<string> newList = new List<string>();
        Stopwatch timer = new Stopwatch();
        timer.Start();
        bool isGood = ExtendToLen(old, 12, '-', ref newList, ref timer, 100);
        timer.Stop();

        foreach (string s in newList)
        {
            Console.WriteLine(s);
        }

        Console.WriteLine("Elapsed time: {0}", timer.Elapsed);
        Console.ReadLine();
    }
}

public static class ExtensionMethods
{
    /// <summary>
    /// Return all indeces
    /// </summary>
    /// <param name="haystack"></param>
    /// <param name="needle"></param>
    /// <returns></returns>
    public static IEnumerable<int> IndexesOf(this string haystack, string needle)
    {
        int lastIndex = 0;
        while (true)
        {
            int index = haystack.IndexOf(needle, lastIndex);
            if (index == -1)
            {
                yield break;
            }
            yield return index;
            lastIndex = index + needle.Length;
        }
    }
}

実行速度が遅くなります。たとえば、文字列(len = 5)を20に拡張したい場合は、長時間実行されます。そして、結果は冗長なようです。

したがって、問題は、それをどのように高速化し、それらの冗長性を取り除くかです。

任意の提案をいただければ幸いです。

4

1 に答える 1

0

これは非常に大まかなハックであり、開始する必要があります。

基本的に、一度に1文字ずつパディングを介して文字列を後方に移動します。

static unsafe void performPaddedBubbleSort(string s, char c, int padCount, IList<string> list) {
        s = new string(c, padCount) + s;
        bool complete = false;
        int index = 0;
        int count = 0;
        fixed (char* p = s) {
            while (count < s.Length && *p == c) {
                while (index < s.Length) {
                    if (*(p + index) != c) {
                        // flip them
                        char tempChar = *(p + index);
                        if (index != 0)
                            *((p + index) - 1) = tempChar;
                        *(p + index) = c;

                        list.Add(new string(p));
                    }

                    index++;
                }
                index = 0;
                count++;
            }
        }
    }

パディング 3 (6 文字幅にするため) を使用した "ABC" の入力は次のとおりです。

--A-BC
--AB-C
--ABC-
-A-BC-
-AB-C-
-ABC--
A-BC--
AB-C--
ABC---
Elapsed time: 00:00:00.0008663

それがまさにあなたが求めていたものかどうかはわかりません..しかし、それは始まりだと思います。ご覧のとおり、ほんの一瞬で実行されます。

于 2013-02-19T00:37:30.357 に答える