Home > Software design >  Replacing char occurrences in a string with x or y
Replacing char occurrences in a string with x or y

Time:04-25

I'm a bit out of practice and currently having a hard time with this one question.

If a character appears only once in the given string, I need to replace it with 'x' If a character appears several times in the string I need to replace it with 'y' (Case sensitive) e.g. "Passable" would return as "xyyyyxxx".

So far I've tried converting the string to a char array and comparing it to a copy of itself using nested loops, but I cant figure out a way to save the index of all occurrences to change them into x or y.

Unfortunately it didn't work out too great, and I'm sure there is a much simpler way of doing this that I'm missing, any ideas?

This is what I have so far:

for (int i = 0; i < OccuredArray.Length; i  )
        {
            for (int x = 0; x < CharArray.Length; x  )
            {
                if (CharArray[x] == OccuredArray[i])
                { 
                    TimesOccured  ;
                }

              
            }
            if (TimesOccured > 1)
            {
                for (int y = 0; y < OccuredArray.Length; y  )
                {
                    if (OccuredArray[i] == OccuredArray[y])
                    {
                        OccuredArray[i] = 'y';
                    }
                    
                }
            }

            if (TimesOccured == 1)
            {
                for (int y = 0; y < OccuredArray.Length; y  )
                {
                    if (OccuredArray[i] == OccuredArray[y])
                    {
                        OccuredArray[i] = 'x';
                    }

                }
            }

            TimesOccured = 0;
        }
   

CodePudding user response:

What about simplifying it a bit? Use a Dictionary<char, int> to count the occurences:

string input = "Passable";
var charCounter = new Dictionary<char, int>();
foreach (char c in input)
{
    charCounter.TryGetValue(c, out int count);
    charCounter[c] =   count;
}

string output = string.Concat(input.Select(c => charCounter[c] == 1 ? "x" : "y"));

CodePudding user response:

If you wanted to use a loop then you could do it like this:

var text = "Passable";
var countsByChar = new Dictionary<char, int>();

foreach (var c in text)
{
    if (!countsByChar.TryAdd(c,1))
    {
        countsByChar[c]  ;
    }
}

foreach (var c in countsByChar.Keys)
{
    text = text.Replace(c,
                        countsByChar[c] == 1
                            ? 'x'
                            : 'y');
}

Console.WriteLine(text);

You could use a LINQ query instead though:

var text = "Passable";
var countsByChar = text.GroupBy(c => c)
                       .ToDictionary(g => g.Key,
                                     g => g.Count());

foreach (var c in countsByChar.Keys)
{
    text = text.Replace(c,
        countsByChar[c] == 1
            ? 'x'
            : 'y');
}

Console.WriteLine(text);

CodePudding user response:

Based on your code I modified and commented on some cases which you should check out:

// So, I suggest this is the input string.
var OccuredArray = "abbcdd";
// It is always better for the length to be in a variable and to be used in for loops.
var OccuredArrayLenght = OccuredArray.Length;
// Here we will fill the placeholders depending on their appearance.
var OccuredArrayResult = new char[OccuredArrayLenght];
// Here we will trace the occurrences in which each index corresponds to a char from the ASCII table.
var OccuredArrayCharMap = new bool[byte.MaxValue];

for (int CurrentCharIndex = 0; CurrentCharIndex < OccuredArrayLenght; CurrentCharIndex  )
{
    var CurrentChar = OccuredArray[CurrentCharIndex];

    // If we have processed this char, we continue with the next one
    if (OccuredArrayCharMap[CurrentChar] == true)
    {
        continue;
    }

    var Placeholder = 'x';

    // Then we will check all the characters, starting from the next index
    for (int NextCharIndex = CurrentCharIndex   1; NextCharIndex < OccuredArrayLenght; NextCharIndex  )
    {
        //if (CharArray[FollowingCharIndex] == OccuredArray[OccuredArrayCharIndex])
        //{
        //    TimesOccured  ;
        //}

        // If char occured twice then the placeholder is y and we can break here
        if (OccuredArray[NextCharIndex] == CurrentChar)
        {
            Placeholder = 'y';

            break;
        }
    }

    //if (TimesOccured > 1)
    //{
    //    for (int y = 0; y < OccuredArray.Length; y  )
    //    {
    //        if (OccuredArray[OccuredArrayCharIndex] == OccuredArray[y])
    //        {
    //            OccuredArray[OccuredArrayCharIndex] = 'y';
    //        }

    //    }
    //}

    //if (TimesOccured == 1)
    //{
    //    for (int y = 0; y < OccuredArray.Length; y  )
    //    {
    //        if (OccuredArray[OccuredArrayCharIndex] == OccuredArray[y])
    //        {
    //            OccuredArray[OccuredArrayCharIndex] = 'x';
    //        }

    //    }
    //}

    //TimesOccured = 0;


    // Here we fill ouer result array with coresponding placeholder at matched index.
    for (int CharIndex = CurrentCharIndex; CharIndex < OccuredArrayLenght; CharIndex  )
    {
        if (OccuredArray[CharIndex] == CurrentChar)
        {
            OccuredArrayResult[CharIndex] = Placeholder;
        }
    }

    // And at the end we say that this char was already replaced.
    OccuredArrayCharMap[CurrentChar] = true;
}

var ResultString = new string(OccuredArrayResult);

Console.WriteLine(OccuredArray);
Console.WriteLine(ResultString);
  •  Tags:  
  • c#
  • Related