Reputation: 1460
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
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
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
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
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
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