C # - Dealing with inconsistencies in string.replace

I am a beginner with C # and programming in general, and I play with if statements, arrays and generally get my head around things. However, one thing that has surpassed me is how you are going to perform the replace operation, which is inherently inconsistent.

IE: I have the string "AAABBB" but I want to search my text and replace all "A" s with "B" s and vice versa. Therefore my intended exit will be "BBBAAA".

I'm currently trying to use the string.replace and if statements, but it doesn't work (it follows the order of the instructions, so in the examples above I would get all "A" or all "B".

Code examples:

if (string.Contains("a"));
{
    string = string.Replace("a", "b");
}

if (string.Contains("b"));
{
    string = string.Replace("b", "a");
}

      

Any help would be greatly appreciated!

+3


source to share


3 answers


Consider using Linq:



s = new string(s.Select(x => x == 'A' ? 'B' : x == 'B' ? 'A' : x).ToArray());

      

+4


source


If you are always replacing one character with another, it might be easiest to convert it to char[]

and step through it one character at a time, fixing each one appropriately - rather than doing everything "like" and then "all Bs".



public static string PerformReplacements(string text)
{
    char[] chars = text.ToCharArray();
    for (int i = 0; i < chars.Length; i++)
    {
        switch (chars[i])
        {
            case 'A':
                chars[i] = 'B';
                break;
            case 'B':
                chars[i] = 'A';
                break;
        }
    }
    return new string(chars);
}

      

+10


source


The reason this happens is because everything is A

first replaced with B

and then back with A

.

The general way to solve this problem is as follows:

using System.Linq;
using System.Text;
using System.Diagnostics.Contracts;

public class Foo {

    public static string ParallelReplace (string text, char[] fromc, char[] toc) {
        Contract.Requires(text != null);
        Contract.Requires(fromc != null);
        Contract.Requires(toc != null)
        Contract.Requires(fromc.Length == toc.Length);
        Contract.Ensures(Contract.Result<string>().Length == text.Length);
        Array.Sort(fromc,toc);
        StringBuilder sb = new StringBuilder();
        foreach(char c in text) {
            int i = Array.BinarySearch(fromc,c);
            if(i >= 0) {
                sb.Append(toc[i]);
            } else {
                sb.Append(c);
            }
        }
        return sb.ToString();
    }

}

      

Demo with interactive shell csharp

:

csharp> Foo.ParallelReplace("ABasdsadsadaABABB",new char[] {'b','a','s'},new char[] {'f','s','a'});
"ABsadasdasdsABABB"

      

This is a mapping {b->f,a->s,s->a}

. The method works in O(s*log(n)+n*log(n))

, with s

line length and n

number of rules.

Contract

not needed, but can help if you use a static code analysis tool to prevent errors.

+2


source







All Articles