একটি স্ট্রিং বিপরীত সেরা উপায়


440

আমাকে কেবল # # 2.0 তে একটি স্ট্রিং রিভার্স ফাংশন লিখতে হয়েছিল (যেমন লিনকিউ উপলব্ধ নেই) এবং এটি নিয়ে এসেছি:

public string Reverse(string text)
{
    char[] cArray = text.ToCharArray();
    string reverse = String.Empty;
    for (int i = cArray.Length - 1; i > -1; i--)
    {
        reverse += cArray[i];
    }
    return reverse;
}

ব্যক্তিগতভাবে আমি ফাংশনটির জন্য পাগল নই এবং আমি নিশ্চিত যে এটি করার আরও ভাল উপায় আছে। আছে?


51
আপনি যথাযথ আন্তর্জাতিক সমর্থন চাইলে আশ্চর্যজনকভাবে জটিল। উদাহরণ: ক্রোয়েশিয়ান / সার্বিয়ান দুটি বর্ণের অক্ষর রয়েছে lj, nj ইত্যাদি "ljudi" এর যথাযথ বিপরীত হয় "idulj", "idujl" নয়। আমি নিশ্চিত আপনি আরবী, থাই ইত্যাদির চেয়ে আরও খারাপ কিছু চাইবেন
dbkk

আমি অবাক হয়েছি যদি কোনও টেম্প অ্যারে শুরু করার পরিবর্তে কোনও স্ট্রিং সংকোচনের জন্য ধীর হয় এবং ফলাফলটি সংরক্ষণ করে, এবং শেষ পর্যন্ত এটিকে একটি স্ট্রিতে রূপান্তরিত করে?
মাফিন ম্যান


5
"সেরা" বলতে আপনার অর্থ কী তা বোঝায় এই প্রশ্নটি উন্নত হতে পারে। দ্রুততম? সর্বাধিক পাঠযোগ্য? বিভিন্ন প্রান্তের ক্ষেত্রে সবচেয়ে নির্ভরযোগ্য (নাল চেক, একাধিক ভাষা ইত্যাদি)? সি # এবং .NET এর সংস্করণগুলিতে সর্বাধিক রক্ষণাবেক্ষণযোগ্য?
হাইফিউম্যান

উত্তর:


608
public static string Reverse( string s )
{
    char[] charArray = s.ToCharArray();
    Array.Reverse( charArray );
    return new string( charArray );
}

16
সাম্বো৯৯৯: এটি ইউনিকোড উল্লেখ করার দরকার নেই: সি # তে বর্ণগুলি ইউনিকোড অক্ষর, বাইট নয়। জোওর দ্রুততর হতে পারে তবে স্বল্প পাঠযোগ্য হওয়া ছাড়া এটি অ্যারেও হতে পারে e রিভার্স () অভ্যন্তরীণভাবে ব্যবহার করে।
নিক জনসন

27
@ আরচনিড: আসলে, সি # তে বর্ণগুলি ইউটিএফ -16 কোড ইউনিট; পরিপূরক চরিত্রটি উপস্থাপন করতে তাদের মধ্যে দুটি লাগে। Jaggersoft.com/csharp_standard/9.4.1.htm দেখুন ।
ব্র্যাডলি গ্রেঞ্জার

4
হ্যাঁ সাম্বো৯৯ আমি মনে করি আপনি সঠিক আছেন তবে ইউটিএফ -32 ব্যবহার করা এটি বেশ বিরল ঘটনা। এবং এক্সওআর খুব কম মানের মানগুলির জন্য কেবলমাত্র দ্রুত, সঠিক উত্তরটি আমি মনে করি বিভিন্ন দৈর্ঘ্যের জন্য বিভিন্ন পদ্ধতি প্রয়োগ করা হবে। তবে এটি স্পষ্ট এবং সংক্ষিপ্ত যা আমার মতে একটি উপকার।
পিটটি

21
ইউনিকোড নিয়ন্ত্রণের অক্ষরগুলি ল্যাটিন-অক্ষর অক্ষর সেটগুলির জন্য এই পদ্ধতিটিকে অকেজো করে তোলে। একটি সক পুতুল ব্যবহার করে জোন স্কিটের ব্যাখ্যা দেখুন: কোডব্লগ.জোনস্কিট.উক / ২০০৯ / ১১ / ২ / (নিচে নামার পথে), বা ভিডিও: vimeo.com/7516539
কলম রজার্স

20
আশা করি আপনি কোনও সরোগেট বা মিলিত অক্ষরগুলির মুখোমুখি হন নি।
ডাল

183

এখানে একটি সমাধান সঠিকভাবে স্ট্রিং reverses "Les Mise\u0301rables"যেমন "selbare\u0301siM seL"। এটি কোডের (( ইত্যাদি) বা এমনকি কোড পয়েন্ট (সারোগেট জোড়গুলির জন্য বিশেষ যত্নের সাথে বিপরীত) এর উপর ভিত্তি করে বেশিরভাগ বাস্তবায়নের ফলাফল হিসাবে, (অ্যাকসেন্টের অবস্থানটি দ্রষ্টব্য) selbarésiM seLনয়, ঠিক যেমন রেন্ডার করা উচিত ।selbaŕesiM seLArray.Reverse

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;

public static class Test
{
    private static IEnumerable<string> GraphemeClusters(this string s) {
        var enumerator = StringInfo.GetTextElementEnumerator(s);
        while(enumerator.MoveNext()) {
            yield return (string)enumerator.Current;
        }
    }
    private static string ReverseGraphemeClusters(this string s) {
        return string.Join("", s.GraphemeClusters().Reverse().ToArray());
    }

    public static void Main()
    {
        var s = "Les Mise\u0301rables";
        var r = s.ReverseGraphemeClusters();
        Console.WriteLine(r);
    }
}

(এবং সরাসরি চলমান উদাহরণ এখানে: https://ideone.com/DqAeMJ )

এটি কেবল গ্রাফিম ক্লাস্টার পুনরাবৃত্তির জন্য .NET এপিআই ব্যবহার করে , যা তখন থেকেই রয়েছে, তবে কিছুটা দৃষ্টিকোণ থেকে "লুকানো" আছে বলে মনে হয়।


10
+1 টি খুব কম সঠিক উত্তরের এক, এবং অনেক অন্যদের কোনো তুলনায় আরো মার্জিত এবং ভবিষ্যতে প্রমাণ, আইএমও
sehe

যদিও কিছু স্থানীয় নির্ভরশীল স্টাফের জন্য এটি ব্যর্থ।
আর মার্টিনহো ফার্নান্দেস

7
এটি মজার বিষয় যে অন্য বেশিরভাগ উত্তরদাতারা কীভাবে অন্যথায় ভুল পন্থাগুলি বন্ধ করে দেওয়ার জন্য এমএস চালিয়ে দেওয়ার চেষ্টা করছেন। কেমন প্রতিনিধি।
জি স্টোনেভ

2
স্ট্রিংইনফো (গুলি) ইনস্ট্যান্ট করার পক্ষে এটি আসলে উল্লেখযোগ্যভাবে দ্রুত, তারপরে সাবস্ট্রিংবিটেক্সটমেন্টস (এক্স, 1) এর মাধ্যমে পুনরাবৃত্তি করুন এবং স্ট্রিংবিল্ডার দিয়ে একটি নতুন স্ট্রিং তৈরি করুন।

2
এটি কিছুটা আশ্চর্যের বিষয় যে আপনি জোন স্কিটের উদাহরণটি ব্যবহার করেছেন যা তিনি কয়েক বছর আগের কোডব্লগ.জোঁসকেট.ইক / ২০০৯ / ১১/০২/২০১é লেস মিসেরেবলস (যদিও জনের কোনও সমাধানের কথা উল্লেখ করেননি, তিনি কেবল সমস্যাগুলি তালিকাভুক্ত করেছেন)। ভালো যে আপনি একটি সমাধান নিয়ে এসেছেন। হয়তো জোন স্কিট একটি টাইম মেশিন আবিষ্কার করেছে, ২০০৯ এ ফিরে গিয়ে সমস্যার সমাধান করেছে যা আপনি আপনার সমাধানটিতে ব্যবহার করেছেন।
বার্লোপ

126

এটি একটি আশ্চর্যজনকভাবে জটিল প্রশ্নে পরিণত হচ্ছে।

আমি অ্যারে ব্যবহার করার পরামর্শ দেব most বেশিরভাগ ক্ষেত্রেই এটি স্থানীয়ভাবে কোডড হওয়ায় এটি বিপরীত হয় এবং এটি বজায় রাখা এবং বুঝতে খুব সহজ।

আমি পরীক্ষিত সমস্ত ক্ষেত্রে স্ট্রিংবিল্ডারকে ছাড়িয়ে গেছে বলে মনে হচ্ছে।

public string Reverse(string text)
{
   if (text == null) return null;

   // this was posted by petebob as well 
   char[] array = text.ToCharArray();
   Array.Reverse(array);
   return new String(array);
}

একটি দ্বিতীয় পদ্ধতি রয়েছে যা নির্দিষ্ট স্ট্রিং দৈর্ঘ্যের জন্য দ্রুত হতে পারে যা জোওর ব্যবহার করে

    public static string ReverseXor(string s)
    {
        if (s == null) return null;
        char[] charArray = s.ToCharArray();
        int len = s.Length - 1;

        for (int i = 0; i < len; i++, len--)
        {
            charArray[i] ^= charArray[len];
            charArray[len] ^= charArray[i];
            charArray[i] ^= charArray[len];
        }

        return new string(charArray);
    }

দ্রষ্টব্য আপনি যদি পুরো ইউনিকোড UTF16 চারসেটটি সমর্থন করতে চান তবে এটি পড়ুন । এবং পরিবর্তে সেখানে প্রয়োগটি ব্যবহার করুন। উপরের একটি অ্যালগরিদম ব্যবহার করে এবং চরগুলি বিপরীত হওয়ার পরে এটি পরিষ্কার করার জন্য স্ট্রিংয়ের মাধ্যমে চালিয়ে এটি আরও অনুকূলিত করা যেতে পারে।

এখানে স্ট্রিংবিল্ডার, অ্যারে। রিভার্স এবং জোর পদ্ধতির মধ্যে পারফরম্যান্স তুলনা করা হচ্ছে।

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace ConsoleApplication4
{
    class Program
    {
        delegate string StringDelegate(string s);

        static void Benchmark(string description, StringDelegate d, int times, string text)
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();
            for (int j = 0; j < times; j++)
            {
                d(text);
            }
            sw.Stop();
            Console.WriteLine("{0} Ticks {1} : called {2} times.", sw.ElapsedTicks, description, times);
        }

        public static string ReverseXor(string s)
        {
            char[] charArray = s.ToCharArray();
            int len = s.Length - 1;

            for (int i = 0; i < len; i++, len--)
            {
                charArray[i] ^= charArray[len];
                charArray[len] ^= charArray[i];
                charArray[i] ^= charArray[len];
            }

            return new string(charArray);
        }

        public static string ReverseSB(string text)
        {
            StringBuilder builder = new StringBuilder(text.Length);
            for (int i = text.Length - 1; i >= 0; i--)
            {
                builder.Append(text[i]);
            }
            return builder.ToString();
        }

        public static string ReverseArray(string text)
        {
            char[] array = text.ToCharArray();
            Array.Reverse(array);
            return (new string(array));
        }

        public static string StringOfLength(int length)
        {
            Random random = new Random();
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < length; i++)
            {
                sb.Append(Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65))));
            }
            return sb.ToString();
        }

        static void Main(string[] args)
        {

            int[] lengths = new int[] {1,10,15,25,50,75,100,1000,100000};

            foreach (int l in lengths)
            {
                int iterations = 10000;
                string text = StringOfLength(l);
                Benchmark(String.Format("String Builder (Length: {0})", l), ReverseSB, iterations, text);
                Benchmark(String.Format("Array.Reverse (Length: {0})", l), ReverseArray, iterations, text);
                Benchmark(String.Format("Xor (Length: {0})", l), ReverseXor, iterations, text);

                Console.WriteLine();    
            }

            Console.Read();
        }
    }
}

ফলাফল এখানে:

26251 Ticks String Builder (Length: 1) : called 10000 times.
33373 Ticks Array.Reverse (Length: 1) : called 10000 times.
20162 Ticks Xor (Length: 1) : called 10000 times.

51321 Ticks String Builder (Length: 10) : called 10000 times.
37105 Ticks Array.Reverse (Length: 10) : called 10000 times.
23974 Ticks Xor (Length: 10) : called 10000 times.

66570 Ticks String Builder (Length: 15) : called 10000 times.
26027 Ticks Array.Reverse (Length: 15) : called 10000 times.
24017 Ticks Xor (Length: 15) : called 10000 times.

101609 Ticks String Builder (Length: 25) : called 10000 times.
28472 Ticks Array.Reverse (Length: 25) : called 10000 times.
35355 Ticks Xor (Length: 25) : called 10000 times.

161601 Ticks String Builder (Length: 50) : called 10000 times.
35839 Ticks Array.Reverse (Length: 50) : called 10000 times.
51185 Ticks Xor (Length: 50) : called 10000 times.

230898 Ticks String Builder (Length: 75) : called 10000 times.
40628 Ticks Array.Reverse (Length: 75) : called 10000 times.
78906 Ticks Xor (Length: 75) : called 10000 times.

312017 Ticks String Builder (Length: 100) : called 10000 times.
52225 Ticks Array.Reverse (Length: 100) : called 10000 times.
110195 Ticks Xor (Length: 100) : called 10000 times.

2970691 Ticks String Builder (Length: 1000) : called 10000 times.
292094 Ticks Array.Reverse (Length: 1000) : called 10000 times.
846585 Ticks Xor (Length: 1000) : called 10000 times.

305564115 Ticks String Builder (Length: 100000) : called 10000 times.
74884495 Ticks Array.Reverse (Length: 100000) : called 10000 times.
125409674 Ticks Xor (Length: 100000) : called 10000 times.

দেখে মনে হচ্ছে সংক্ষিপ্ত স্ট্রিংয়ের জন্য Xor দ্রুততর হতে পারে।


2
এটি কোনও স্ট্রিং ফিরিয়ে দেয় না - আপনার "নতুন স্ট্রিং (...)" এর কলটিতে এটি মোড়ানো দরকার
গ্রেগ বিচ

বিটিডাব্লু .. আমি কেবল অ্যারে বাস্তবায়নের দিকে নজর রেখেছি। বিপরীত, এবং এটি অক্ষরের জন্য উপযুক্তভাবে সম্পন্ন হয়েছে ... এটি স্ট্রিংবিল্ডার বিকল্পের চেয়ে অনেক দ্রুত হওয়া উচিত।
স্যাম জাফরান

আপনি কতটা দুর্দান্ত, গ্রেগ, সাম্বোকে থামিয়ে দিতে তাকে নীচে ভোট দেওয়ার পরিবর্তে আরও ভাল সমাধানে পৌঁছেছেন।
ডক করুন

@ ডক 1 - এটি উল্লেখ করবেন না :) @ সাম্বো৯৯ - এখন আমি কৌতূহল বোধ করছি, আগামীকাল একটি কোড প্রোফাইলারকে হুইপ করতে হবে এবং এক নজর দেখতে হবে!
গ্রেগ বিচ 0

9
এই পদ্ধতিগুলি বেস বহুভাষিক প্লেনের বাইরে অক্ষরগুলি সহ স্ট্রিংগুলি পরিচালনা করে না, যেমন, ইউনিকোড অক্ষর> = ইউ + 10000 যা দুটি সি # অক্ষর দ্বারা প্রতিনিধিত্ব করা হয়। আমি একটি উত্তর পোস্ট করেছি যা এই জাতীয় স্ট্রিং সঠিকভাবে পরিচালনা করে।
ব্র্যাডলি গ্রেনার

52

আপনি যদি লাইনক (। নেট ফ্রেমওয়ার্ক 3.5+) ব্যবহার করতে পারেন তবে নীচের একটি লাইনার আপনাকে শর্ট কোড দেবে। এতে using System.Linq;অ্যাক্সেস রাখতে যুক্ত করতে ভুলবেন না Enumerable.Reverse:

public string ReverseString(string srtVarable)
{
    return new string(srtVarable.Reverse().ToArray());
}

মন্তব্য:

  • দ্রুততম সংস্করণ নয় - মার্টিন নিডারল অনুসারে এখানে দ্রুততম পছন্দের চেয়ে times গুণ ধীর গতিতে।
  • অনেক অন্যান্য অপশন যেমন এই কোড সম্পূর্ণরূপে, মাল্টি-অক্ষর সমন্বয় সমস্ত প্রকারের উপেক্ষা করে তাই হোমওয়ার্ক বরাদ্দকরণ এবং স্ট্রিং যা সীমা ব্যবহার না এমন অক্ষর থাকে। বাস্তবায়নের জন্য এই প্রশ্নের আরও একটি উত্তর দেখুন যা সঠিকভাবে এই জাতীয় সংমিশ্রণগুলি পরিচালনা করে।

এটি সর্বাধিক উত্সাহিত সংস্করণ থেকে প্রায় 5.7 গুণ ধীর তাই আমি এটি ব্যবহার করার পরামর্শ দিই না!
মার্টিন নিডারল

2
দ্রুততম সমাধান নয়, তবে ওয়ান-লাইনার হিসাবে কার্যকর।
এড্রিয়ান্প

49

যদি স্ট্রিংটিতে ইউনিকোড ডেটা থাকে (কঠোরভাবে বলা যায়, নন-বিএমপি অক্ষর রয়েছে) তবে পোস্ট করা অন্যান্য পদ্ধতিগুলি এটি দুর্নীতিগ্রস্থ করবে, কারণ স্ট্রিংটি উল্টানোর সময় আপনি উচ্চ এবং নিম্ন সারোগেট কোড ইউনিটের ক্রম পরিবর্তন করতে পারবেন না। (এটি সম্পর্কে আরও তথ্য আমার ব্লগে পাওয়া যাবে ))

নিম্নলিখিত কোডের নমুনাটি সঠিকভাবে একটি স্ট্রিংকে বিপরীত করবে যাতে বিএমপিবিহীন অক্ষর রয়েছে, যেমন, "\ U00010380 \ U00010381" (উগারিটিক লেটার আলপা, উগারিটিক লেটার বিটা)।

public static string Reverse(this string input)
{
    if (input == null)
        throw new ArgumentNullException("input");

    // allocate a buffer to hold the output
    char[] output = new char[input.Length];
    for (int outputIndex = 0, inputIndex = input.Length - 1; outputIndex < input.Length; outputIndex++, inputIndex--)
    {
        // check for surrogate pair
        if (input[inputIndex] >= 0xDC00 && input[inputIndex] <= 0xDFFF &&
            inputIndex > 0 && input[inputIndex - 1] >= 0xD800 && input[inputIndex - 1] <= 0xDBFF)
        {
            // preserve the order of the surrogate pair code units
            output[outputIndex + 1] = input[inputIndex];
            output[outputIndex] = input[inputIndex - 1];
            outputIndex++;
            inputIndex--;
        }
        else
        {
            output[outputIndex] = input[inputIndex];
        }
    }

    return new string(output);
}

29
আসলে, সি # তে বর্ণগুলি 16-বিট ইউটিএফ -16 কোড ইউনিট; তাদের দুটি ব্যবহার করে পরিপূরক চরিত্রটি এনকোড করা হয়েছে, সুতরাং এটি প্রয়োজনীয়,
ব্র্যাডলি গ্রেনার

14
দেখে মনে হচ্ছে সিস্টেম.স্ট্রিংয়ের ইউনিকোড পরিপূরক অক্ষরযুক্ত স্ট্রিংগুলির জন্য হিয়ারবিড্রাগন সম্পত্তি প্রকাশ করা উচিত।
রবার্ট রসনি

4
@ সেবাস্তিয়ান নেগ্রাসজাস: এটি সঠিক: এই পদ্ধতিটি কেবল স্ট্রিংয়ের কোডপয়েন্টগুলিকে বিপরীত করে। গ্রাফি ক্লাস্টারগুলিকে বিপরীত করা সম্ভবত সামগ্রিকভাবে আরও "দরকারী" হতে পারে (তবে প্রথমে একটি স্বেচ্ছাচারী স্ট্রিংকে উল্টানোর "ব্যবহার" কী?), কিন্তু নেট ফ্রেমওয়ার্কে কেবল অন্তর্নির্মিত পদ্ধতিগুলি প্রয়োগ করা সহজ নয়।
ব্র্যাডলি গ্রেনার

2
@ রিচার্ড: গ্রাফিম ক্লাস্টারগুলি ভেঙে দেওয়ার নিয়মগুলি কেবল কোড পয়েন্টগুলির সংমিশ্রণের চেয়ে কিছুটা জটিল; আরও তথ্যের জন্য ইউএএক্স # 29 এর গ্রাফিম ক্লাস্টার সীমানায় ডকুমেন্টেশন দেখুন।
ব্র্যাডলি গ্রেনার

1
খুব ভাল তথ্য! না যে কেউ Array.Reverse পরীক্ষার জন্য একটি ব্যর্থ পরীক্ষা আছে? এবং পরীক্ষার দ্বারা আমার অর্থ একটি নমুনা স্ট্রিং পুরো ইউনিট পরীক্ষা নয় ... এটি আমাকে সত্যই সহায়তা করবে (এবং অন্যরা) এই সমস্যা সম্পর্কে বিভিন্ন ব্যক্তিকে বোঝাতে ..
আন্দ্রে রেনিয়া

25

ঠিক আছে, "নিজেকে পুনরাবৃত্তি করবেন না" স্বার্থে আমি নিম্নলিখিত সমাধানটি সরবরাহ করি:

public string Reverse(string text)
{
   return Microsoft.VisualBasic.Strings.StrReverse(text);
}

আমার উপলব্ধি হ'ল ভিবি.এনইটি-তে ডিফল্টরূপে উপলব্ধ এই বাস্তবায়নটি ইউনিকোড অক্ষরকে সঠিকভাবে পরিচালনা করে।


11
এটি কেবল সরোগেটসকে সঠিকভাবে পরিচালনা করে। এটি মিশ্রিত চিহ্নগুলিতে গণ্ডগোল করে: ideone.com/yikdqX
আর মার্টিনহো ফার্নান্দেস

17

গ্রেগ বিচ unsafeএমন একটি বিকল্প পোস্ট করেছে যা প্রকৃতপক্ষে এটি দ্রুত গতিতে আসে (এটি একটি স্থানের অভ্যন্তরে বিপরীত); কিন্তু, তিনি তার উত্তর নির্দেশিত, এটা একটি সম্পূর্ণ বিপর্যয়মূলক ধারণা

এটি বলেছিল, আমি এতই conকমত্যের পক্ষে অবাক যে Array.Reverseদ্রুততম পদ্ধতি। ছোট একটি স্ট্রিংয়ের পদ্ধতির চেয়ে উল্লেখযোগ্যভাবে দ্রুতগতিতেunsafe স্ট্রিংয়ের বিপরীত অনুলিপি (কোনও স্থানের বিপরীতে শেননিগান নেই) এখনও রয়েছে approachArray.Reverse

public static unsafe string Reverse(string text)
{
    int len = text.Length;

    // Why allocate a char[] array on the heap when you won't use it
    // outside of this method? Use the stack.
    char* reversed = stackalloc char[len];

    // Avoid bounds-checking performance penalties.
    fixed (char* str = text)
    {
        int i = 0;
        int j = i + len - 1;
        while (i < len)
        {
            reversed[i++] = str[j--];
        }
    }

    // Need to use this overload for the System.String constructor
    // as providing just the char* pointer could result in garbage
    // at the end of the string (no guarantee of null terminator).
    return new string(reversed, 0, len);
}

এখানে কিছু মানদণ্ডের ফলাফল রয়েছে

আপনি দেখতে পাচ্ছেন যে কর্মক্ষমতা অর্জন সঙ্কুচিত হয় এবং তারপরে Array.Reverseবড় হওয়ার সাথে সাথে পদ্ধতির বিরুদ্ধে অদৃশ্য হয়ে যায় । ছোট থেকে মাঝারি আকারের স্ট্রিংগুলির জন্য, যদিও এই পদ্ধতিটি পরাস্ত করা শক্ত।


2
বড় স্ট্রিংগুলিতে স্ট্যাক ওভারফ্লো।
রাজ্জ মেগ্রেলিজে

@ রেজোমেগ্রেল্ডাইজ: হ্যাঁ, তা ঘটবে;)
ড্যান টাও

15

সহজ এবং সুন্দর উত্তরটি এক্সটেনশন পদ্ধতিটি ব্যবহার করছে:

static class ExtentionMethodCollection
{
    public static string Inverse(this string @base)
    {
        return new string(@base.Reverse().ToArray());
    }
}

এবং এখানে ফলাফল:

string Answer = "12345".Inverse(); // = "54321"

Reverse()এবং ToArray()আপনার কোড নমুনা ভুল ক্রমে হয়।
ক্রিস ওয়ালশ

@ কী উদ্দেশ্যে কাজ করে?
ব্যবহারকারী5389726598465

2
@ user5389726598465 এই লিঙ্কটি দেখুন: ডকস.মাইক্রোসফটি.এইন / ডটনেট / সিএসআরপি / ভাষাগুলি-রেফারেন্স/… যেহেতু 'বেস' সি # তে একটি কীওয়ার্ড, এটি সি # সংকলককে এটি হিসাবে ব্যাখ্যা করার জন্য @ এর সাথে উপসর্গ করা আবশ্যক শনাক্তকারী।
ডায়ান্ড্রিলিয়াক

14

আপনি যদি সত্যিই একটি বিপজ্জনক খেলা খেলতে চান তবে এটি এখন পর্যন্ত সবচেয়ে দ্রুততম উপায় (এর চেয়ে প্রায় চারগুণ বেশি দ্রুত) Array.Reverse পদ্ধতির )। এটি পয়েন্টার ব্যবহার করে একটি স্থানের বিপরীত।

মনে রাখবেন যে আমি সত্যিই এটি কোনও ব্যবহারের জন্য সুপারিশ করি না, ( এই পদ্ধতিটি কেন ব্যবহার না করা উচিত তা কিছু কারণের জন্য এখানে দেখুন ) তবে এটি করা যেতে পারে তা দেখার জন্য এটি আকর্ষণীয় এবং এটির স্ট্রিংগুলি সত্যই অপরিবর্তনীয় নয় একবার আপনি অনিরাপদ কোডটি চালু করুন।

public static unsafe string Reverse(string text)
{
    if (string.IsNullOrEmpty(text))
    {
        return text;
    }

    fixed (char* pText = text)
    {
        char* pStart = pText;
        char* pEnd = pText + text.Length - 1;
        for (int i = text.Length / 2; i >= 0; i--)
        {
            char temp = *pStart;
            *pStart++ = *pEnd;
            *pEnd-- = temp;
        }

        return text;
    }
}

আমি নিশ্চিত যে এটি ইউটিএফ 16 স্ট্রিংয়ের জন্য ভুল ফলাফল ফিরিয়ে দেবে, এটি সত্যিই সমস্যা জিজ্ঞাসা করছে :)
স্যাম

হাই আপনার এই পোস্টটি লিঙ্ক করা উচিত এই স্ট্যাকওভারফ্লো.com / প্রশ্নগুলি / 229346/… তে , যেমন আমি আগে বলেছিলাম যে এটি সত্যই সমস্যার জন্য জিজ্ঞাসা করছে ...
স্যাম সাফ্রন

এটি সম্পূর্ণ অশুভ এবং অসুস্থ পরামর্শদাতা হতে পারে (যেমন আপনি নিজেরাই স্বীকার করেছেন), তবে unsafeকোডটি ব্যবহার করে স্ট্রিংটি বিপরীত করার জন্য এখনও একটি উচ্চ-কার্য সম্পাদনের উপায় রয়েছে যা অশুভ নয় এবং এখনওArray.Reverse অনেক ক্ষেত্রে মারধর করে। আমার উত্তর একবার দেখুন।
ড্যান তাও

13

এখানে উইকিপিডিয়া এন্ট্রি একবার দেখুন । তারা স্ট্রিং বাস্তবায়ন করে R বিপরীত এক্সটেনশন পদ্ধতি। এটি আপনাকে এই জাতীয় কোড লিখতে দেয়:

string s = "olleh";
s.Reverse();

তারা ToCharArray / বিপরীত সংমিশ্রণটিও ব্যবহার করে যা এই প্রশ্নের অন্যান্য উত্তরগুলির পরামর্শ দেয়। উত্স কোডটি এর মতো দেখাচ্ছে:

public static string Reverse(this string input)
{
    char[] chars = input.ToCharArray();
    Array.Reverse(chars);
    return new String(chars);
}

এটি দুর্দান্ত, এক্সটেনশন পদ্ধতি বাদে সি # 2.0 তে প্রবর্তিত হয়নি।
কোবি

11

প্রথমে আপনাকে কল করার দরকার নেই ToCharArrayকারণ একটি স্ট্রিং ইতিমধ্যে একটি চর অ্যারে হিসাবে সূচকযুক্ত করা যেতে পারে, সুতরাং এটি আপনাকে বরাদ্দ সংরক্ষণ করবে।

পরবর্তী অপ্টিমাইজেশন হ'ল StringBuilderঅপ্রয়োজনীয় বরাদ্দ প্রতিরোধের জন্য একটি ব্যবহার করা (যেমন স্ট্রিংগুলি পরিবর্তনযোগ্য, সংক্ষেপে প্রতিটি সময় স্ট্রিংয়ের একটি অনুলিপি তৈরি করে)। এটি আরও অনুকূলিত করতে আমরা এর দৈর্ঘ্য পূর্ব-সেট করে রেখেছি StringBuilderযাতে এর বাফারটি প্রসারিত করার দরকার পড়বে না।

public string Reverse(string text)
{
    if (string.IsNullOrEmpty(text))
    {
        return text;
    }

    StringBuilder builder = new StringBuilder(text.Length);
    for (int i = text.Length - 1; i >= 0; i--)
    {
        builder.Append(text[i]);
    }

    return builder.ToString();
}

সম্পাদনা: পারফরম্যান্স ডেটা

আমি Array.Reverseনিম্নলিখিত Reverse1ফাংশনটি এবং অন্যটি হ'ল নিম্নলিখিত সাধারণ প্রোগ্রামটি ব্যবহার করে এই ফাংশনটি এবং ফাংশনটি পরীক্ষা করেছি Reverse2:

static void Main(string[] args)
{
    var text = "abcdefghijklmnopqrstuvwxyz";

    // pre-jit
    text = Reverse1(text); 
    text = Reverse2(text);

    // test
    var timer1 = Stopwatch.StartNew();
    for (var i = 0; i < 10000000; i++)
    {
        text = Reverse1(text);
    }

    timer1.Stop();
    Console.WriteLine("First: {0}", timer1.ElapsedMilliseconds);

    var timer2 = Stopwatch.StartNew();
    for (var i = 0; i < 10000000; i++)
    {
        text = Reverse2(text);
    }

    timer2.Stop();
    Console.WriteLine("Second: {0}", timer2.ElapsedMilliseconds);

    Console.ReadLine();
}

দেখা যাচ্ছে যে সংক্ষিপ্ত স্ট্রিংগুলির জন্য Array.Reverseপদ্ধতিটি উপরেরটির চেয়ে দ্বিগুণ দ্রুত এবং দীর্ঘতর স্ট্রিংগুলির জন্য পার্থক্যটি আরও প্রকট। তাই দেওয়া যে Array.Reverseপদ্ধতি উভয় সহজ এবং দ্রুত আমি আপনি যে ব্যবহার বরং এই এক তুলনায় বলতে চাই। আমি এটি এখানে রেখেছি কেবল এটি দেখানোর জন্য যে এটি করা উচিত নয় তা নয় (আমার অবাক করার মতো বিষয়!)


পাঠ্যটি সংরক্ষণ করবে না are ভেরিয়েবলের দৈর্ঘ্য কিছুটা গতি দেয় যখন আপনি এটি কোনও অবজেক্টের মাধ্যমে উল্লেখ করছেন?
ডেভিড রবিনস

10

অ্যারে ব্যবহার করার চেষ্টা করুন। বিপরীত


public string Reverse(string str)
{
    char[] array = str.ToCharArray();
    Array.Reverse(array);
    return new string(array);
}

এটি অবিশ্বাস্যভাবে দ্রুত।
মাইকেল স্টাম

কেন ডাউন ভোট? এটি বিতর্ক না, বরং আমি আমার ভুল থেকে শিখতে হবে।
মাইক টু

অন্যান্য অনেক কিছুর মধ্যে কোড পয়েন্ট সমন্বয় করতে ব্যর্থ।
মাকিং হাঁস

@ মুভিংডাক - ব্যাখ্যা করার জন্য ধন্যবাদ, তবে কোড পয়েন্ট বলতে কী বোঝাতে চাইছি তা আমি জানি না এছাড়াও আপনি "অন্যান্য অনেক বিষয়" সম্পর্কে বিস্তারিত ব্যাখ্যা করতে পারেন।
মাইক টু

@ মুভিংডাক আমি কোড পয়েন্ট সন্ধান করেছি। হ্যাঁ. আপনি সঠিক. এটি কোড পয়েন্টগুলি পরিচালনা করে না। এই জাতীয় সরল প্রশ্নের জন্য সমস্ত প্রয়োজনীয়তা নির্ধারণ করা শক্ত। মতামতের জন্য ধন্যবাদ
মাইক টু

10
public static string Reverse(string input)
{
    return string.Concat(Enumerable.Reverse(input));
}

অবশ্যই আপনি বিপরীত পদ্ধতিতে স্ট্রিং ক্লাস প্রসারিত করতে পারেন

public static class StringExtensions
{
    public static string Reverse(this string input)
    {
        return string.Concat(Enumerable.Reverse(input));
    }
}

Enumerable.Reverse(input)সমানinput.Reverse()
fubo

8

"সেরা" অনেক কিছুর উপর নির্ভর করতে পারে তবে দ্রুত থেকে ধীর গতির জন্য আরও কয়েকটি সংক্ষিপ্ত বিকল্প এখানে দেওয়া হয়েছে:

string s = "z̽a̎l͘g̈o̓😀😆", pattern = @"(?s).(?<=(?:.(?=.*$(?<=((\P{M}\p{C}?\p{M}*)\1?))))*)";

string s1 = string.Concat(s.Reverse());                          // "☐😀☐̓ög͘l̎a̽z"  👎

string s2 = Microsoft.VisualBasic.Strings.StrReverse(s);         // "😆😀o̓g̈l͘a̎̽z"  👌

string s3 = string.Concat(StringInfo.ParseCombiningCharacters(s).Reverse()
    .Select(i => StringInfo.GetNextTextElement(s, i)));          // "😆😀o̓g̈l͘a̎z̽"  👍

string s4 = Regex.Replace(s, pattern, "$2").Remove(s.Length);    // "😆😀o̓g̈l͘a̎z̽"  👍

8

.NET কোর 2.1 দিয়ে শুরু করে একটি ব্যবহার করে স্ট্রিংটি বিপরীত করার একটি নতুন উপায় রয়েছে string.Create পদ্ধতিটি ।

নোট করুন যে এই সমাধানটি ইউনিকোডের সাথে সংযুক্ত অক্ষরগুলি ইত্যাদি সঠিকভাবে পরিচালনা করে না, কারণ "লেস মাইস \ u0301rables" "সেলবার selসিম সেল" তে রূপান্তরিত হবে। আরও ভাল সমাধানের জন্য অন্যান্য উত্তর

public static string Reverse(string input)
{
    return string.Create<string>(input.Length, input, (chars, state) =>
    {
        state.AsSpan().CopyTo(chars);
        chars.Reverse();
    });
}

এটি মূলত inputএকটি নতুন স্ট্রিং- এর অক্ষরগুলি অনুলিপি করে এবং নতুন স্ট্রিংটিকে জায়গায় রেখে দেয়।

কেন string.Createদরকারী?

আমরা যখন বিদ্যমান অ্যারে থেকে স্ট্রিং তৈরি করি তখন একটি নতুন অভ্যন্তরীণ অ্যারে বরাদ্দ করা হয় এবং মানগুলি অনুলিপি করা হয়। অন্যথায়, কোনও স্ট্রিং তৈরির পরে (নিরাপদ পরিবেশে) পরিবর্তন করা সম্ভব হবে। এটি হ'ল, নিম্নলিখিত স্নিপেটে আমাদের দু'বার দৈর্ঘ্যের অ্যারে দুবার বরাদ্দ করতে হবে, একটি বাফার হিসাবে এবং একটি স্ট্রিংয়ের অভ্যন্তরীণ অ্যারে হিসাবে।

var chars = new char[10];
// set array values
var str = new string(chars);

string.Createমূলত স্ট্রিং তৈরির সময় আমাদের অভ্যন্তরীণ অ্যারে হেরফের করতে দেয়। এটি হ'ল, আমাদের আর বাফার দরকার নেই এবং তাই সেই চারটি অ্যারের বরাদ্দ এড়াতে পারি।

স্টিভ গর্ডন এখানে আরও বিস্তারিতভাবে এটি লিখেছেন । এমএসডিএন নিয়ে একটি নিবন্ধও রয়েছে

কিভাবে ব্যবহার করবেন string.Create?

public static string Create<TState>(int length, TState state, SpanAction<char, TState> action);

পদ্ধতিটি তিনটি পরামিতি নেয়:

  1. স্ট্রিংটির দৈর্ঘ্য তৈরি করতে,
  2. আপনি নতুন তথ্যটি নতুনভাবে তৈরি করতে ডেটা ব্যবহার করতে চান,
  3. এবং একটি প্রতিনিধি যা ডেটা থেকে চূড়ান্ত স্ট্রিং তৈরি করে, যেখানে প্রথম প্যারামিটারটি charনতুন স্ট্রিংয়ের অভ্যন্তরীণ অ্যারেতে নির্দেশ করে এবং দ্বিতীয়টি হ'ল আপনি যে ডেটা (রাষ্ট্র) পাস করেছেন string.Create

প্রতিনিধিটির ভিতরে আমরা উল্লেখ করতে পারি যে কীভাবে ডেটা থেকে নতুন স্ট্রিং তৈরি হয়। আমাদের ক্ষেত্রে, আমরা কেবলমাত্র Spanনতুন স্ট্রিং দ্বারা ব্যবহৃত ইনপুট স্ট্রিংয়ের অক্ষরগুলি অনুলিপি করি । তারপরে আমরা বিপরীত করি Spanএবং তাই পুরো স্ট্রিংটি বিপরীত হয়।

benchmarks

স্বীকৃত উত্তরের সাথে আমার স্ট্রিংটিকে বিপরীত করার প্রস্তাবিত পদ্ধতির তুলনা করতে, আমি বেঞ্চমার্কডটনেট ব্যবহার করে দুটি মানদণ্ড লিখেছি।

public class StringExtensions
{
    public static string ReverseWithArray(string input)
    {
        var charArray = input.ToCharArray();
        Array.Reverse(charArray);
        return new string(charArray);
    }

    public static string ReverseWithStringCreate(string input)
    {
        return string.Create(input.Length, input, (chars, state) =>
        {
            state.AsSpan().CopyTo(chars);
            chars.Reverse();
        });
    }
}

[MemoryDiagnoser]
public class StringReverseBenchmarks
{
    private string input;

    [Params(10, 100, 1000)]
    public int InputLength { get; set; }


    [GlobalSetup]
    public void SetInput()
    {
        // Creates a random string of the given length
        this.input = RandomStringGenerator.GetString(InputLength);
    }

    [Benchmark(Baseline = true)]
    public string WithReverseArray() => StringExtensions.ReverseWithArray(input);

    [Benchmark]
    public string WithStringCreate() => StringExtensions.ReverseWithStringCreate(input);
}

আমার মেশিনে ফলাফল এখানে:

| Method           | InputLength |         Mean |      Error |    StdDev |  Gen 0 | Allocated |
| ---------------- | ----------- | -----------: | ---------: | --------: | -----: | --------: |
| WithReverseArray | 10          |    45.464 ns |  0.4836 ns | 0.4524 ns | 0.0610 |      96 B |
| WithStringCreate | 10          |    39.749 ns |  0.3206 ns | 0.2842 ns | 0.0305 |      48 B |
|                  |             |              |            |           |        |           |
| WithReverseArray | 100         |   175.162 ns |  2.8766 ns | 2.2458 ns | 0.2897 |     456 B |
| WithStringCreate | 100         |   125.284 ns |  2.4657 ns | 2.0590 ns | 0.1473 |     232 B |
|                  |             |              |            |           |        |           |
| WithReverseArray | 1000        | 1,523.544 ns |  9.8808 ns | 8.7591 ns | 2.5768 |    4056 B |
| WithStringCreate | 1000        | 1,078.957 ns | 10.2948 ns | 9.6298 ns | 1.2894 |    2032 B |

আপনি দেখতে পাচ্ছেন যে, ReverseWithStringCreateআমরা ReverseWithArrayপদ্ধতি দ্বারা ব্যবহৃত মেমরির অর্ধেক বরাদ্দ করি ।


এটি লিনক বিপরীতে
কোড

7

কোনও ফাংশন নিয়ে বিরক্ত করবেন না, কেবল এটি জায়গায় করুন। দ্রষ্টব্য: দ্বিতীয় লাইনটি কিছু ভিএস সংস্করণের তাত্ক্ষণিক উইন্ডোতে একটি আর্গুমেন্ট ব্যতিক্রম নিক্ষেপ করবে।

string s = "Blah";
s = new string(s.ToCharArray().Reverse().ToArray()); 

1
কিছু লোক কেন তা ব্যাখ্যা না করে প্রতিটি উত্তর (আমার অন্তর্ভুক্ত) কমিয়ে দেওয়ার জন্য সময় নিয়েছিল।
মার্সেল ভালদেজ ওরোজকো

এই জায়গায় সত্যিই না, যেহেতু আপনি একটি তৈরি করছেনnew string
mbadawi23

5

দীর্ঘ পোস্টের জন্য দুঃখিত, তবে এটি আকর্ষণীয় হতে পারে

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        public static string ReverseUsingArrayClass(string text)
        {
            char[] chars = text.ToCharArray();
            Array.Reverse(chars);
            return new string(chars);
        }

        public static string ReverseUsingCharacterBuffer(string text)
        {
            char[] charArray = new char[text.Length];
            int inputStrLength = text.Length - 1;
            for (int idx = 0; idx <= inputStrLength; idx++) 
            {
                charArray[idx] = text[inputStrLength - idx];                
            }
            return new string(charArray);
        }

        public static string ReverseUsingStringBuilder(string text)
        {
            if (string.IsNullOrEmpty(text))
            {
                return text;
            }

            StringBuilder builder = new StringBuilder(text.Length);
            for (int i = text.Length - 1; i >= 0; i--)
            {
                builder.Append(text[i]);
            }

            return builder.ToString();
        }

        private static string ReverseUsingStack(string input)
        {
            Stack<char> resultStack = new Stack<char>();
            foreach (char c in input)
            {
                resultStack.Push(c);
            }

            StringBuilder sb = new StringBuilder();
            while (resultStack.Count > 0)
            {
                sb.Append(resultStack.Pop());
            }
            return sb.ToString();
        }

        public static string ReverseUsingXOR(string text)
        {
            char[] charArray = text.ToCharArray();
            int length = text.Length - 1;
            for (int i = 0; i < length; i++, length--)
            {
                charArray[i] ^= charArray[length];
                charArray[length] ^= charArray[i];
                charArray[i] ^= charArray[length];
            }

            return new string(charArray);
        }


        static void Main(string[] args)
        {
            string testString = string.Join(";", new string[] {
                new string('a', 100), 
                new string('b', 101), 
                new string('c', 102), 
                new string('d', 103),                                                                   
            });
            int cycleCount = 100000;

            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            for (int i = 0; i < cycleCount; i++) 
            {
                ReverseUsingCharacterBuffer(testString);
            }
            stopwatch.Stop();
            Console.WriteLine("ReverseUsingCharacterBuffer: " + stopwatch.ElapsedMilliseconds + "ms");

            stopwatch.Reset();
            stopwatch.Start();
            for (int i = 0; i < cycleCount; i++) 
            {
                ReverseUsingArrayClass(testString);
            }
            stopwatch.Stop();
            Console.WriteLine("ReverseUsingArrayClass: " + stopwatch.ElapsedMilliseconds + "ms");

            stopwatch.Reset();
            stopwatch.Start();
            for (int i = 0; i < cycleCount; i++) 
            {
                ReverseUsingStringBuilder(testString);
            }
            stopwatch.Stop();
            Console.WriteLine("ReverseUsingStringBuilder: " + stopwatch.ElapsedMilliseconds + "ms");

            stopwatch.Reset();
            stopwatch.Start();
            for (int i = 0; i < cycleCount; i++) 
            {
                ReverseUsingStack(testString);
            }
            stopwatch.Stop();
            Console.WriteLine("ReverseUsingStack: " + stopwatch.ElapsedMilliseconds + "ms");

            stopwatch.Reset();
            stopwatch.Start();
            for (int i = 0; i < cycleCount; i++) 
            {
                ReverseUsingXOR(testString);
            }
            stopwatch.Stop();
            Console.WriteLine("ReverseUsingXOR: " + stopwatch.ElapsedMilliseconds + "ms");            
        }
    }
}

ফলাফল:

  • রিভারস ইউজিংচ্যাকারবাফার: 346 মিমি
  • বিপরীতমুখীআরাইক্লাস: 87 মিমি
  • রিভার্সউসিংস্ট্রিংবিল্ডার: 824 মিমি
  • রিভারসউসিংস্ট্যাক: 2086 মিমি
  • রিভারসউজিংএক্সআর: 319 মি

আমি আমার পোস্টে একটি অনুরূপ তুলনা যুক্ত করেছি, এটি একটি সম্প্রদায় উইকি যাতে আপনার সম্পাদনা করতে সক্ষম হওয়া উচিত। পারফরম্যান্সটি সত্যই স্ট্রিংয়ের দৈর্ঘ্যের পাশাপাশি অ্যালগরিদমের উপর নির্ভর করে, এটি গ্রাফ করা আকর্ষণীয় হবে। আমি এখনও মনে করি অ্যারে। বিপরীত সব ক্ষেত্রে সবচেয়ে দ্রুত হবে ...
স্যাম

"সকল ক্ষেত্রে দ্রুততম হবে" যখন যাদুকরী ট্রাইজেড রিভার্স ফাংশন (এটি বিপরীত বাস্তবায়নে ব্যবহৃত হয়) ব্যর্থ হয়, অ্যারে boxing তবে আমি জানি না ট্রাইজেড রেভার্সকে ব্যর্থ করার শর্ত কী।
আকু

এটি সর্বাধিক ক্ষেত্রে দ্রুততম হয় না :), আমি আমার পোস্ট আপডেট করেছি। এটি এখনও সঠিকতা এবং গতি উভয়ের জন্য ইউনিকোড দিয়ে পরীক্ষা করা দরকার।
স্যাম জাফরান

5
public string Reverse(string input)
{
    char[] output = new char[input.Length];

    int forwards = 0;
    int backwards = input.Length - 1;

    do
    {
        output[forwards] = input[backwards];
        output[backwards] = input[forwards];
    }while(++forwards <= --backwards);

    return new String(output);
}

public string DotNetReverse(string input)
{
    char[] toReverse = input.ToCharArray();
    Array.Reverse(toReverse);
    return new String(toReverse);
}

public string NaiveReverse(string input)
{
    char[] outputArray = new char[input.Length];
    for (int i = 0; i < input.Length; i++)
    {
        outputArray[i] = input[input.Length - 1 - i];
    }

    return new String(outputArray);
}    

public string RecursiveReverse(string input)
{
    return RecursiveReverseHelper(input, 0, input.Length - 1);
}

public string RecursiveReverseHelper(string input, int startIndex , int endIndex)
{
    if (startIndex == endIndex)
    {
        return "" + input[startIndex];
    }

    if (endIndex - startIndex == 1)
    {
        return "" + input[endIndex] + input[startIndex];
    }

    return input[endIndex] + RecursiveReverseHelper(input, startIndex + 1, endIndex - 1) + input[startIndex];
}


void Main()
{
    int[] sizes = new int[] { 10, 100, 1000, 10000 };
    for(int sizeIndex = 0; sizeIndex < sizes.Length; sizeIndex++)
    {
        string holaMundo  = "";
        for(int i = 0; i < sizes[sizeIndex]; i+= 5)
        {   
            holaMundo += "ABCDE";
        }

        string.Format("\n**** For size: {0} ****\n", sizes[sizeIndex]).Dump();

        string odnuMaloh = DotNetReverse(holaMundo);

        var stopWatch = Stopwatch.StartNew();
        string result = NaiveReverse(holaMundo);
        ("Naive Ticks: " + stopWatch.ElapsedTicks).Dump();

        stopWatch.Restart();
        result = Reverse(holaMundo);
        ("Efficient linear Ticks: " + stopWatch.ElapsedTicks).Dump();

        stopWatch.Restart();
        result = RecursiveReverse(holaMundo);
        ("Recursive Ticks: " + stopWatch.ElapsedTicks).Dump();

        stopWatch.Restart();
        result = DotNetReverse(holaMundo);
        ("DotNet Reverse Ticks: " + stopWatch.ElapsedTicks).Dump();
    }
}

আউটপুট

আকারের জন্য: 10

Naive Ticks: 1
Efficient linear Ticks: 0
Recursive Ticks: 2
DotNet Reverse Ticks: 1

আকারের জন্য: 100

Naive Ticks: 2
Efficient linear Ticks: 1
Recursive Ticks: 12
DotNet Reverse Ticks: 1

আকারের জন্য: 1000

Naive Ticks: 5
Efficient linear Ticks: 2
Recursive Ticks: 358
DotNet Reverse Ticks: 9

আকারের জন্য: 10000

Naive Ticks: 32
Efficient linear Ticks: 28
Recursive Ticks: 84808
DotNet Reverse Ticks: 33

1
ইন খালি স্ট্রিং জন্য চেক করা প্রয়োজন Reverse(...)। অন্যথায়, ভাল কাজ।
লারা


4

স্ট্যাক-ভিত্তিক সমাধান।

    public static string Reverse(string text)
    {
        var stack = new Stack<char>(text);
        var array = new char[stack.Count];

        int i = 0;
        while (stack.Count != 0)
        {
            array[i++] = stack.Pop();
        }

        return new string(array);
    }

অথবা

    public static string Reverse(string text)
    {
        var stack = new Stack<char>(text);
        return string.Join("", stack);
    }

4

পুনরাবৃত্তির উদাহরণ জমা দিতে হয়েছিল:

private static string Reverse(string str)
{
    if (str.IsNullOrEmpty(str) || str.Length == 1)
        return str;
    else
        return str[str.Length - 1] + Reverse(str.Substring(0, str.Length - 1));
}

1
দৈর্ঘ্যের 0 টি স্ট্রিং পরিচালনা করা হয় না
বোহদান_ট্রোটসেনকো

এটি দরকারী নয়।
ব্যবহারকারী 3613932

3

কেমন:

    private string Reverse(string stringToReverse)
    {
        char[] rev = stringToReverse.Reverse().ToArray();
        return new string(rev); 
    }

উপরের অন্যান্য পদ্ধতির মতো একই কোডপয়েন্ট বিষয়ক সমস্যা রয়েছে এবং এটি ToCharArrayপ্রথম করার চেয়ে অনেক ধীর গতিবেগ সম্পাদন করবে । লিনকিউ এনুমरेटरটিও তুলনায় বেশ ধীর Array.Reverse()
আবেল

3

আমি মাইক্রোসফ্ট.ভিউজুয়ালবাসিক.সার্টিংস থেকে একটি সি # পোর্ট তৈরি করেছি । আমি নিশ্চিত নই যে তারা কেন এই জাতীয় দরকারী ফাংশন (ভিবি থেকে) ফ্রেমওয়ার্কে স্ট্রিংয়ের বাইরে রেখেছেন, তবে এখনও মাইক্রোসফ্টের মধ্যে রয়েছে V ভিজুয়ালবাসিক। আর্থিক ক্রিয়াকলাপের জন্য একই অবস্থা (যেমন Microsoft.VisualBasic.Financial.Pmt())।

public static string StrReverse(this string expression)
{
    if ((expression == null))
        return "";

    int srcIndex;

    var length = expression.Length;
    if (length == 0)
        return "";

    //CONSIDER: Get System.String to add a surrogate aware Reverse method

    //Detect if there are any graphemes that need special handling
    for (srcIndex = 0; srcIndex <= length - 1; srcIndex++)
    {
        var ch = expression[srcIndex];
        var uc = char.GetUnicodeCategory(ch);
        if (uc == UnicodeCategory.Surrogate || uc == UnicodeCategory.NonSpacingMark || uc == UnicodeCategory.SpacingCombiningMark || uc == UnicodeCategory.EnclosingMark)
        {
            //Need to use special handling
            return InternalStrReverse(expression, srcIndex, length);
        }
    }

    var chars = expression.ToCharArray();
    Array.Reverse(chars);
    return new string(chars);
}

///<remarks>This routine handles reversing Strings containing graphemes
/// GRAPHEME: a text element that is displayed as a single character</remarks>
private static string InternalStrReverse(string expression, int srcIndex, int length)
{
    //This code can only be hit one time
    var sb = new StringBuilder(length) { Length = length };

    var textEnum = StringInfo.GetTextElementEnumerator(expression, srcIndex);

    //Init enumerator position
    if (!textEnum.MoveNext())
    {
        return "";
    }

    var lastSrcIndex = 0;
    var destIndex = length - 1;

    //Copy up the first surrogate found
    while (lastSrcIndex < srcIndex)
    {
        sb[destIndex] = expression[lastSrcIndex];
        destIndex -= 1;
        lastSrcIndex += 1;
    }

    //Now iterate through the text elements and copy them to the reversed string
    var nextSrcIndex = textEnum.ElementIndex;

    while (destIndex >= 0)
    {
        srcIndex = nextSrcIndex;

        //Move to next element
        nextSrcIndex = (textEnum.MoveNext()) ? textEnum.ElementIndex : length;
        lastSrcIndex = nextSrcIndex - 1;

        while (lastSrcIndex >= srcIndex)
        {
            sb[destIndex] = expression[lastSrcIndex];
            destIndex -= 1;
            lastSrcIndex -= 1;
        }
    }

    return sb.ToString();
}

+1, একটি দুর্দান্ত সংযোজন! আমি কেবল এটি দিয়ে চেষ্টা করেছিলাম string s = "abo\u0327\u0307\u035d\U0001d166cd", যার মধ্যে oবিএমপিতে ডায়ারিটিকাল চিহ্নগুলির সাথে মিলিত চিঠিটি রয়েছে এবং এটি অ্যাস্ট্রাল প্লেন (নন-বিএমপি) থেকে একটি সংমিশ্রণ চিহ্ন (মিউজিকাল সিম্বল কম্বিনিং স্টেম) এবং এটি অক্ষত রাখে। তবে পদ্ধতিটি ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে এই ধরনের অক্ষরগুলি একটি দীর্ঘ স্ট্রিংয়ের শেষে উপস্থিত হয়, কারণ এটি পুরো অ্যারের উপরে দুবার যেতে হবে has
আবেল

3

এই পুরানো থ্রেড পোস্ট করার জন্য দুঃখিত। আমি একটি সাক্ষাত্কারের জন্য কিছু কোড অনুশীলন করছি।

এটিই আমি সি # এর জন্য নিয়ে এসেছি। রিফ্যাক্টরিংয়ের আগে আমার প্রথম সংস্করণটি ছিল ভয়ঙ্কর।

static String Reverse2(string str)
{
    int strLen = str.Length, elem = strLen - 1;
    char[] charA = new char[strLen];

    for (int i = 0; i < strLen; i++)
    {
        charA[elem] = str[i];
        elem--;
    }

    return new String(charA);
}

Array.Reverseনীচের পদ্ধতির বিপরীতে , এটি স্ট্রিংটিতে 12 টি বা তারও কম অক্ষরের সাথে দ্রুত প্রদর্শিত হয়। ১৩ টি চরিত্রের পরে, Array.Reverseদ্রুত গতিতে শুরু হয় এবং শেষ পর্যন্ত গতিতে এটি বেশ ভারীভাবে প্রাধান্য পায়। আমি ঠিক যেখানে গতিটি পরিবর্তন শুরু করে তা প্রায় নির্দেশ করতে চেয়েছিলাম।

static String Reverse(string str)
{     
    char[] charA = str.ToCharArray();

    Array.Reverse(charA);

    return new String(charA);
}

স্ট্রিংয়ের 100 টি অক্ষরে এটি আমার সংস্করণ x 4 এর চেয়ে দ্রুত However

পরীক্ষা Stopwatchএবং 5000000 পুনরাবৃত্তি দিয়ে করা হয়েছিল । এছাড়াও, আমি নিশ্চিত নই যে আমার সংস্করণটি সুরোগেটস বা Unicodeএনকোডিংয়ের সাথে সম্মিলিত চরিত্রের পরিস্থিতি পরিচালনা করে কিনা ।


2

"আরও ভাল উপায়" আপনার পরিস্থিতি, পারফরম্যান্স, কমনীয়তা, রক্ষণাবেক্ষণ ইত্যাদি ক্ষেত্রে আপনার কাছে কী বেশি গুরুত্বপূর্ণ তার উপর নির্ভর করে

যাইহোক, অ্যারে ব্যবহার করে এখানে একটি পদ্ধতি রয়েছে। বিপরীত:

string inputString="The quick brown fox jumps over the lazy dog.";
char[] charArray = inputString.ToCharArray(); 
Array.Reverse(charArray); 

string reversed = new string(charArray);

2

যদি এটি কোনও সাক্ষাত্কারে আসে এবং আপনাকে বলা হয়েছিল যে আপনি অ্যারে ব্যবহার করতে পারবেন না e বিপরীত, আমি মনে করি এটি সম্ভবত দ্রুততমগুলির মধ্যে একটি। এটি নতুন স্ট্রিং তৈরি করে না এবং অ্যারের অর্ধেকেরও বেশি (যেমন ও (এন / ২) পুনরাবৃত্তিগুলি) পুনরাবৃত্তি করে

    public static string ReverseString(string stringToReverse)
    {
        char[] charArray = stringToReverse.ToCharArray();
        int len = charArray.Length-1;
        int mid = len / 2;

        for (int i = 0; i < mid; i++)
        {
            char tmp = charArray[i];
            charArray[i] = charArray[len - i];
            charArray[len - i] = tmp;
        }
        return new string(charArray);
    }

2
আমি বেশ কিছু নির্দিষ্ট স্ট্রিংটোরিভার্স.টোকচারআরে () কল একটি ও (এন) এক্সিকিউশন সময় উত্পন্ন করবে।
মার্সেল ভালদেজ ওরোজকো

ইন বিগ-হে স্বরলিপি , ফ্যাক্টর না নির্ভরশীল xআপনার ক্ষেত্রে, বা, nব্যবহার করা হয় না। আপনার অ্যালগরিদমের কর্মক্ষমতা রয়েছে f(x) = x + ½x + C, যেখানে সি কিছু ধ্রুবক। যেহেতু Cএবং ফ্যাক্টর উভয়ই নির্ভর করে না x, তাই আপনার অ্যালগরিদম O(x)। এর অর্থ এই নয় যে এটি দৈর্ঘ্যের কোনও ইনপুট জন্য দ্রুত হবে না x, তবে এর কার্য সম্পাদন ইনপুট দৈর্ঘ্যের উপর নির্ভর করে ar @ মার্সেলওয়াল্ডেজ ওরোজকো উত্তর দেওয়ার জন্য, হ্যাঁ, এটি O(n)গতি বাড়ানোর জন্য প্রতি 16 বাইট খণ্ড অনুলিপি করে (এটি memcpyমোট দৈর্ঘ্যের উপর সরাসরি ব্যবহার করে না )।
হাবিল

2

আপনার যদি স্ট্রিং থাকে যা কেবলমাত্র ASCII অক্ষর রয়েছে, আপনি এই পদ্ধতিটি ব্যবহার করতে পারেন।

    public static string ASCIIReverse(string s)
    {
        byte[] reversed = new byte[s.Length];

        int k = 0;
        for (int i = s.Length - 1; i >= 0; i--)
        {
            reversed[k++] = (byte)s[i];
        }

        return Encoding.ASCII.GetString(reversed);
    }

2

প্রথমে আপনাকে যা বুঝতে হবে তা হল str + = 1 টি অতিরিক্ত চরের জন্য স্থান তৈরি করতে আপনার স্ট্রিং মেমরির আকার পরিবর্তন করবে। এটি ঠিক আছে, তবে আপনার যদি বলুন যে 1000 পৃষ্ঠাগুলি সহ যে বইটি আপনি বিপরীত করতে চান তবে এটি কার্যকর হতে খুব বেশি সময় লাগবে।

কিছু লোক যে সমাধানটির পরামর্শ দিতে পারে তা হ'ল স্ট্রিংবিল্ডার। আপনি যখন স্ট্রিং বিল্ডার একটি + = সম্পাদন করেন তখন তা নতুন চরিত্রটি ধরে রাখতে মেমরির অনেক বড় অংশ বরাদ্দ দেয় যাতে প্রতিবার যখন আপনি চারটি যুক্ত করেন তখন এটি পুনর্নির্মাণের প্রয়োজন হয় না।

আপনি যদি সত্যিই একটি দ্রুত এবং ন্যূনতম সমাধান চান তবে আমি নীচের পরামর্শ দেব:

            char[] chars = new char[str.Length];
            for (int i = str.Length - 1, j = 0; i >= 0; --i, ++j)
            {
                chars[j] = str[i];
            }
            str = new String(chars);

এই সমাধানে যখন চর [] আরম্ভ করা হয় তখন একটি প্রাথমিক মেমরি বরাদ্দ থাকে এবং যখন স্ট্রিং কনস্ট্রাক্টর চর অ্যারে থেকে স্ট্রিং তৈরি করে তখন একটি বরাদ্দ।

আমার সিস্টেমে আমি আপনার জন্য একটি পরীক্ষা চালিয়েছি যা 2 750 000 অক্ষরের স্ট্রিংকে বিপরীত করে। এখানে মৃত্যুদণ্ড কার্যকর করার জন্য ফলাফলগুলি দেওয়া হচ্ছে:

স্ট্রিংবিল্ডার: 190 কে - 200 কে টিক্স

চর অ্যারে: 130 কে - 160 কে টিক্স

আমি সাধারণ স্ট্রিং + = এর জন্যও একটি পরীক্ষা চালিয়েছিলাম তবে আমি 10 মিনিট পরে কোনও আউটপুট ছাড়াই এটি পরিত্যাগ করেছি।

যাইহোক, আমি আরও লক্ষ্য করেছি যে ছোট স্ট্রিংয়ের জন্য স্ট্রিংবিল্ডার দ্রুততর, সুতরাং আপনাকে ইনপুটের উপর ভিত্তি করে বাস্তবায়ন সম্পর্কে সিদ্ধান্ত নিতে হবে।

চিয়ার্স


কাজ স্বল্পতা😀Les Misérables
চার্লস

@ চার্লস আহে হ্যাঁ চার্ট সেট সীমাবদ্ধতা আমি মনে করি।
রিসুরিয়া

2
public static string reverse(string s) 
{
    string r = "";
    for (int i = s.Length; i > 0; i--) r += s[i - 1];
    return r;
}

1
public static string Reverse2(string x)
        {
            char[] charArray = new char[x.Length];
            int len = x.Length - 1;
            for (int i = 0; i <= len; i++)
                charArray[i] = x[len - i];
            return new string(charArray);
        }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.