locked
How to move chars in char array to the left and to the right RRS feed

  • Question

  • Hello everyone! 

    I have this situation: Given a string and two more characters X and Y. Move all X characters to the beginning of the string and all Y characters to the end of the string. The order of the other characters in the string remains unchanged. I wrote two function MoveCharsLeft and MoveCharsRight to move X to the left and Y to the right, but there is an error System.IndexOutOfRangeException: 'Index was outside the bounds of the array.' on this line of code char toReplace = splitText[charToCheck]; line 41 and I don't know how to handle it, in order to solve the exercise. Can, you guys, help me with that, how should be the functions?

    using System;
    
    namespace StringExercise
    {
        class Program
        {
            static void Main()
            {
                string text = Console.ReadLine();
                char[] splitText = text.ToCharArray();
                string firstLetter = Console.ReadLine();
                char[] firstChar = firstLetter.ToCharArray();
                string secondLetter = Console.ReadLine();
                char[] secondChar = secondLetter.ToCharArray();
                char one = firstChar[0];
                char two = secondChar[0];
                Console.WriteLine(CheckChars(splitText, one, two));
                Console.ReadLine();
            }
    
            static char[] CheckChars(char[] splitText, char one, char two)
            {
                for (char letter = 'a'; letter <= 'z'; letter++)
                {
                    if (Array.IndexOf(splitText, one) > -1)
                    {
                        MoveCharsLeft(splitText, one);
                    }
    
                    if (Array.IndexOf(splitText, two) > -1)
                    {
                        MoveCharsRight(splitText, two);
                    }
                }
    
                return splitText;
            }
    
            static void MoveCharsLeft(char[] splitText, char charToCheck)
            {
                char toReplace = splitText[charToCheck];
                char currentLetter = splitText[0];
                for (int i = 0; i <= charToCheck; i++)
                {
                    char temporary = splitText[i];
                    splitText[i] = currentLetter;
                    currentLetter = temporary;
                }
    
                splitText[0] = toReplace;
            }
    
            static void MoveCharsRight(char[] splitText, char charToCheck)
            {
                char toReplace = splitText[charToCheck];
                char currentLetter = splitText[-1];
                for (int i = 0; i <= charToCheck; i++)
                {
                    char temporary = splitText[i];
                    splitText[i] = currentLetter;
                    currentLetter = temporary;
                }
    
                splitText[-1] = toReplace;
            }
        }
    }
    


    Wednesday, October 14, 2020 1:14 PM

All replies

  • Probably it is not allowed to use LINQ in your work:

    string input = "An example of the given string";
    char X = 'e';
    char Y = 'i';
    string output = string.Concat( input.Where( c => c == X ).Concat( input.Where( c => c != X && c != Y ) ).Concat( input.Where( c => c == Y ) ) );
    Console.WriteLine( input );
    Console.WriteLine( output );
    

    Wednesday, October 14, 2020 2:47 PM
  • Your for loops are wrong. Imagine I give you the string "ABCD" and one is 'B' while two is 'C'. Inside your MoveChars functions you accept the string (as an array) and the character to find. But then you start enumerating the string starting at 0 and going to the char to check. But the loop is treating `i` as an index, not character to find. So in the case of 'C', which is numerically 67, then it'll enumerate from 0 to 67 which is well beyond the length of the string.

    You cannot treat characters as indice into an array. It will never work. The correct approach depends upon how much you have learned in your class at this point. This can be done in a couple lines of code once you know about LINQ and the string functions. It'll take more code if you are still studying arrays and control flow loops. Given that you are limiting yourself to arrays (which is very inefficient) and for loops I assume you haven't learned about string functions yet. So the long way it is. Here's the algorithm you can try. Note there are several ways to solve this problem.

    Enumerate the characters in the array from 0 to the array Length - 1 (C# uses zero-based indexing)
       if the character matches the character you want 
          Shift all characters in the array from 0 to current index - 1 to the right one 
          Insert the character at index 0

    Note that for the "Right" function it is the same algorithm except you shift left and insert at end. You could use the same function and just have a parameter to distinguish.

    An alternative algorithm if you have learned about string functions.

    Get current length of string
    Use Replace function to replace all occurrences of character with empty string
    Get new length of string
    Create new string using constructor that accepts a character and a length to produce a string containing the appropriate character count by subtracting old length from new
    Append or prepend the new string to the modified string


    Michael Taylor http://www.michaeltaylorp3.net

    Wednesday, October 14, 2020 2:51 PM
  • Check this approach too:

       Define prefix, body and suffix as string variables, initially empty (“”).

       For each character in input string:

          If it is X, append to prefix,

          If it is Y, append to suffix,

          Otherwise, append to body

       Build the output string, concatenating prefix, body and suffix.

    Wednesday, October 14, 2020 3:03 PM
  • Thank you very much for this information. Yes, I am a beginner, still learning! I will try your approach. 
    • Edited by Simona.M Thursday, October 15, 2020 7:01 AM grammatical reason
    Thursday, October 15, 2020 7:01 AM
  • Thank you for your solution, I really appreciate! Thanks!
    Thursday, October 15, 2020 7:03 AM
  • Thank you for your idea, I will try it! Thank you!
    Thursday, October 15, 2020 7:03 AM
  • Hi Simona.M,

    Their suggestions can solve this problem well, so after you follow their suggestions to solve the problem, please remember to mark their reply as an answer, so that it will help other members to find the solution quickly if they face a similar issue.

    Best Regards,

    Timon


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, October 15, 2020 8:56 AM
  • I gave them my vote for the answer. Should I do something else? Thank you!
    Thursday, October 15, 2020 11:55 AM
  • Hi Simona.M,

    There should be an option called "Mark as answer" below those replies.

    If an answer solves your problem, you can click this option to express appreciation. You can select multiple replies to mark as answers at the same time.

    Best Regards,

    Timon


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Friday, October 16, 2020 1:23 AM