Jasmeet
Jasmeet

Reputation: 1460

swap 2 characters in the string based on their indices

Given a string I want to swap 2 characters in the string based on their indices.

Input : str = "Hello" index1 = 1 index2 = 4

Output : str = "Holle"

but when I directly try updating the string character :

str[1] = //Assign something 

it gives the error ->

Property or indexer 'string.this[int]' cannot be assigned to -- it is read only

So I wrote a function that converts the string to character array before performing the swap operation.

static string SwapChars(String str, int index1, int index2)
{
    char[] strChar = str.ToCharArray();
    char temp = strChar[index1];
    strChar[index1] = strChar[index2];
    strChar[index2] = temp;
    
    return new String(strChar);
}

It is working fine, but I want to know what is the time complexity for the function. I think it is O(n) as char array and string are getting constructed as new, where n is length of string passed. Also is there some other way I can perform this operation with better performance.

Upvotes: 1

Views: 2413

Answers (4)

TheGeneral
TheGeneral

Reputation: 81493

You could use pointers, with minimal allocations

public unsafe void SwapChars(ref string str, int index1, int index2)
{
   fixed (char* p = str)
   {
      var temp = p[index1];
      p[index1] = p[index2];
      p[index2] = temp;
   }
}

Note the above is fairly dangerous, as it will mess-up unturned strings

This would be safer

public static unsafe string SwapChars(string str, int index1, int index2)
{
   if (str == null) throw new ArgumentNullException(nameof(str));
   if (index1 < 0 || index1 >= str.Length) throw new ArgumentOutOfRangeException(nameof(index1));
   if (index2 < 0 || index2 >= str.Length) throw new ArgumentOutOfRangeException(nameof(index1));

   var result = new string(str);

   fixed (char* p = result)
   {
      var temp = p[index1];
      p[index1] = p[index2];
      p[index2] = temp;
   }
   return result;
}

Upvotes: 1

Ali Bigdeli
Ali Bigdeli

Reputation: 1375

according to this link, one way to replace chars in string is using StringBuilder class in c#,

var str = "Hello";
var strBuilder = new StringBuilder(str);
strBuilder[4] = 'e';

str = strBuilder.ToString();
// the result will be same 

in this link compare c# String function and StringBuilder, if you will you can compare this two function.

EDIT NOTE:

I tested both StringBuilder and ToCharArray methods, the results shows that using ToCharArray and replace the char is really better than using StringBuilder function, here is my tested code(at least in my machine ) :

var str = new String('a' , 100000000);

var stopwatch = new Stopwatch();

stopwatch.Start();
var strBuilder = new StringBuilder(str);
strBuilder[4] = 'e';

str = strBuilder.ToString();
stopwatch.Stop();
Console.WriteLine("Elapsed time using StringBuilder: {0} ms", stopwatch.Elapsed.Milliseconds);

stopwatch.Reset();
stopwatch.Start();
char[] strChar = str.ToCharArray();
char temp = strChar[1];
strChar[1] = strChar[4];
strChar[4] = temp;

stopwatch.Stop();
Console.WriteLine("Elapsed time using ToCharArray: {0} ms", stopwatch.Elapsed.Milliseconds);


/*
  results: 
    Elapsed time using StringBuilder: 179 ms
    Elapsed time using ToCharArray: 94 ms
*/

Upvotes: 1

Caius Jard
Caius Jard

Reputation: 74605

I want to know what is the time complexity for the function

If n is "copying a char from one memory location to another" then it's O(2n+3)

Your string chars are copied to a char array, you swap them, the chars are copied to another string

Upvotes: 1

Alfred Luu
Alfred Luu

Reputation: 1983

The string cannot assign value through indexer because it's not allowed to do that. When you look up at the definition of string, find for this[int index] you will know it only allowed get

enter image description here

The best way to swap them is base on your method, but have no temp value.

static string SwapChars(String str, int index1, int index2)
{
    char[] strChar = str.ToCharArray();
    strChar[index1] = str[index2];
    strChar[index2] = str[index1];
    
    return new String(strChar);
}

Another option is using Insert and Remove

static string SwapChars(String str, int index1, int index2)
{
    return str.Remove(index1, 1).Insert(index1, str[index2].ToString())
            .Remove(index2, 1).Insert(index2, str[index1].ToString());
}

Honestly, I prefer the first one because it's clear.

Upvotes: 5

Related Questions