DEV Community

Cover image for C# - String reversal
FakeStandard
FakeStandard

Posted on • Edited on

3 2 1

C# - String reversal

字串反轉算是基礎的考題,不論在學校或是工作,拿來作為考題或面試題都會是必經的一道題。

首先,你會拿到一個題目,題目內容是將看到的字串反轉,通常會拿到一個固定的字串去反轉,但在這裡,我建立一個方法亂數產生字串,並且有一個必須傳入的參數——length,每次 Random 時都可以自由配置字串的長度。

/// <summary>
/// 取得亂數產生的字串
/// </summary>
/// <param name="length"></param>
/// <returns></returns>
public static string RandomString(int length)
{
    string str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    Random random = new Random(Guid.NewGuid().GetHashCode());
    StringBuilder sb = new StringBuilder();

    for (int i = 0; i < length; i++)
        sb.Append(str[random.Next(0, str.Length)]);

    return sb.ToString();
}
Enter fullscreen mode Exit fullscreen mode

題目準備好後,下一步就來解題,目前我只有想到四種反轉方法,如果你有其他的方法,不論好與壞,請不要吝嗇留言告訴我~

暴力破解法
比較直覺的做法,從尾到頭遍歷所有字符,並將每次遍歷的字符加到新的變數裡

/// <summary>
/// 暴力破解 O(n)
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static string ReverseCase1(string s)
{
    string res = string.Empty;

    for (int i = s.Length - 1; i >= 0; i--)
        res += s[i];

    return res;
}
Enter fullscreen mode Exit fullscreen mode

LINQ
直接使用 LINQ 的 Reverse 方法,寫起來簡易明瞭又快速

/// <summary>
/// LINQ Reverse method
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static string ReverseCase2(string s)
{
    return string.Join("", s.Reverse());
}
Enter fullscreen mode Exit fullscreen mode

頭尾位置對調
運用厲害一點的演算法來解——頭尾文字的位置對調,暴力破解迭代了所有字符,而這個方法只需要迭代一半的字符,等於時間複雜度減少了一半,整體效能優於暴力破解。

/// <summary>
/// 頭尾對調位置 O(n/2)
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static string ReverseCase3(string s)
{
    char[] c = s.ToCharArray();

    int i = 0;
    int j = s.Length - 1;

    // you can also use a for loop to iterate
    while (i < j)
    {
        // swap
        char temp = c[i];
        c[i] = c[j];
        c[j] = temp;

        i++;
        j--;
    }

    return new string(c);
}
Enter fullscreen mode Exit fullscreen mode

C# Array 原生反轉方法
最後,一定要知道的 Array.Reverse() C# 原生方法,反轉前先將字串轉換成 Array,反轉完後再 new 成一個新的字串

/// <summary>
/// C# Array 原生反轉方法
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static string ReverseCase4(string s)
{
    char[] c = s.ToCharArray();

    Array.Reverse(c);

    return new string(c);
}
Enter fullscreen mode Exit fullscreen mode

寫一個測試 Action 執行時間的方法

/// <summary>
/// 測試 Action 執行時間
/// </summary>
/// <param name="action"></param>
/// <param name="methodName"></param>
static void TestTime(Action action, string methodName)
{
    Stopwatch sw = new Stopwatch();

    sw.Start();
    action();
    sw.Stop();

    Console.WriteLine($"Duration: {sw.ElapsedMilliseconds:N0}ms, TestName:{methodName}");
}
Enter fullscreen mode Exit fullscreen mode

Main 方法

static void Main(string[] args)
{
    // six nines
    var str = GetRandomString(100000);

    TestTime(() => ReverseCase1(str), "暴力破解");
    TestTime(() => ReverseCase2(str), "LINQ 反轉方法");
    TestTime(() => ReverseCase3(str), "頭尾對調位置");
    TestTime(() => ReverseCase4(str), "C# Array 原生反轉方法");
}
Enter fullscreen mode Exit fullscreen mode

執行結果
因為暴力破解遍歷的所有字符,沒有意外的話它會是執行時間最久的方法

pic-004

第一次執行結果,可以看到暴力破解法的時間複雜度相對高,僅次於後的是 LINQ 方法,而後兩種方法無法比較。

如果加大長度同時去跑這四種方法,會因為暴力破解法的執行時間過長而等待,為了再更清楚的看到後兩種方法執行狀況,將前兩種方法註解,只運行後兩種方法,並且加大參數長度為 9999999

pic-005

比較就明顯出來了,雖然頭尾對調是優化過的演算法,甚至比 LINQ 的執行效率更高,但還是輸給 C# Array 的原生方法。

或許 Array 底層的最佳化是基於頭尾對調的邏輯去執行的…?


Thanks for reading the article 🌷 🌻 🌼

If you like it, please don't hesitate to click heart button ❤️
or follow my GitHub ⭐ I'd appreciate it.


AWS Security LIVE!

Join us for AWS Security LIVE!

Discover the future of cloud security. Tune in live for trends, tips, and solutions from AWS and AWS Partners.

Learn More

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay