Chapter 15: Strings

Quiz Solutions

Solution to Question 15-1. string (lowercase) is the C# keyword that maps to the .NET Framework String class. They may be used interchangeably.

Solution to Question 15-2. IComparable guarantees that strings can be sorted. ICloneable guarantees that you can call the Clone method on a string object and get back a new duplicate string. IConvertible allows strings to be converted to other types (such as integers). And IEnumerable guarantees that strings can be iterated over in foreach loops.

Solution to Question 15-3. A string literal is a quoted string, provided by the programmer, such as “Hello”.

Solution to Question 15-4. An escape character embedded in a string indicates that the character or punctuation that follows is to be treated as an instruction rather than as part of the string. indicates a new line. " indicates that the quote symbol is part of the string, not terminating it.

Solution to Question 15-5. Verbatim strings are taken “as is” and thus do not require escape characters. Where \ would indicate a single backslash in a normal string, in a verbatim string it indicates two backslashes. Verbatim strings must include an @ character before the first double quote.

Solution to Question 15-6. The fact that strings are immutable means they cannot be changed. When you appear to change a string, what actually happens is that a new string is created and the old string is destroyed by the garbage collector if it is no longer referenced.

Solution to Question 15-7. You can call the Concat method of the String class to join two strings, but it is more common to use the overloaded + operator.

Solution to Question 15-8. Given an array of delimiters, Split( ) returns the substrings of the original string, as broken up by the specified delimiters.

Solution to Question 15-9. StringBuilder objects are mutable. When the StringBuilder has the complete set of characters you want, you call ToString( ) to get back a string object, which is then immutable.

Solution to Question 15-10. Regular expressions constitute a language for identifying and manipulating strings using both literals and metacharacters.

Exercise Solutions

Solutoin to Exercise 15-1. Create the following six strings:

  • String 1: “Hello "

  • String 2: “World”

  • String 3 (a verbatim string): “Come visit us at http://www.LibertyAssociates.com"

  • String 4: a concatenation of strings 1 and 2

  • String 5: “world”

  • String 6: a copy of string 3

Once you have the strings created, do the following:

  1. Output the length of each string.

  2. Output the third character in each string.

  3. Output whether the character H appears in each string.

  4. Output which strings are the same as string 2.

  5. Output which strings are the same as string 2, ignoring case.

Creating the strings is relatively easy: you need to remember to keep the space in String 1 and to use a verbatim string (with an @ symbol) for String 3. You can concatenate Strings 1 and 2 using Concat( ) or the + operator, and you can use Copy( ) to create String 6.

For the other parts of the exercise, you can just put all the code directly in Test( ). You could put all the strings into an array, and iterate over the array for each test, but with only six elements it’s fine to test them each individually.

For part 1, you just need to output the Length of each string:

Console.WriteLine( "s1: {0} [{1}]", s1.Length, s1 );

Part 2 is also simple. To get the third character in each string, use the index operator, but remember that indexes start at zero, so the third character is at index [2]:

Console.WriteLine( "s1: {0} [{1}]", s1[2], s1 );

For part 3, to determine whether there’s a specific character in the string, you can use IndexOf( ) to test for that character. If the character isn’t in the string, IndexOf( ) returns –1. Therefore, if the returned index is greater than or equal to zero, the character is in the string. To be completely accurate about it, you can use ToUpper( ) or ToLower( ) on each string first so that you’re testing for both uppercase and lowercase instances of the character. We’re using the ternary operator here (from Chapter 4) to return “yes” or “nope”:

Console.WriteLine( "s1: {0} [{1}]",
     s1.ToUpper( ).IndexOf( 'H' ) >= 0 ? "yes" : "nope", s1 );

In part 4, you need to test whether a string is the same as String 2. That’s what the String.Compare( ) method is for. Again, we’re using the ternary operator for the output:

Console.WriteLine( "s1: {0} [{1}]",
     String.Compare( s1, s2 ) == 0 ? "Same!" : "Different", s1 );

Part 5 is very similar to part 4, but this time, you use the overloaded version of Compare( ) and set the third parameter to “true” so that Compare( ) will ignore case:

Console.WriteLine( "s1: {0} [{1}]",
     String.Compare( s1, s2, true ) == 0 ? "Same!" : "Different", s1 );

Example A-42 shows our code for conducting all the tests in one program.

Example A-42. Our solution to Exercise 15-1

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Exercise_15_1
{
    class Tester
    {
        public void Run( )
        {
            // creating the six strings
            string s1 = "Hello ";
            string s2 = "World";
            string s3 = @"Come visit us at http://www.LibertyAssociates.com";
            string s4 = s1 + s2;
            string s5 = "world";
            string s6 = string.Copy(s3);

            // returning the length of each string
            Console.WriteLine("Here's how long our strings are...");
            Console.WriteLine("s1: {0} [{1}]", s1.Length, s1);
            Console.WriteLine("s2: {0} [{1}]", s2.Length, s2);
            Console.WriteLine("s3: {0} [{1}]", s3.Length, s3);
            Console.WriteLine("s4: {0} [{1}]", s4.Length, s4);
            Console.WriteLine("s5: {0} [{1}]", s5.Length, s5);
            Console.WriteLine("s6: {0} [{1}]", s6.Length, s6);

            // returning the third character in each string
            Console.WriteLine("
Here's the third character
                                 in each string...");
            Console.WriteLine("s1: {0} [{1}]", s1[2], s1);
            Console.WriteLine("s2: {0} [{1}]", s2[2], s2);
            Console.WriteLine("s3: {0} [{1}]", s3[2], s3);
            Console.WriteLine("s4: {0} [{1}]", s4[2], s4);
            Console.WriteLine("s5: {0} [{1}]", s5[2], s5);
            Console.WriteLine("s6: {0} [{1}]", s6[2], s6);

            // testing for the character H in each string
            Console.WriteLine("
Is there an h in the string?");
            Console.WriteLine("s1: {0} [{1}]",
                     s1.ToUpper( ).IndexOf('H') >= 0 ? "yes" : "nope", s1);
            Console.WriteLine("s2: {0} [{1}]",
                     s2.ToUpper( ).IndexOf('H') >= 0 ? "yes" : "nope", s2);
            Console.WriteLine("s3: {0} [{1}]",
                     s3.ToUpper( ).IndexOf('H') >= 0 ? "yes" : "nope", s3);
            Console.WriteLine("s4: {0} [{1}]",
                     s4.ToUpper( ).IndexOf('H') >= 0 ? "yes" : "nope", s4);
            Console.WriteLine("s5: {0} [{1}]",
                     s5.ToUpper( ).IndexOf('H') >= 0 ? "yes" : "nope", s5);
            Console.WriteLine("s6: {0} [{1}]",
                     s6.ToUpper( ).IndexOf('H') >= 0 ? "yes" : "nope", s6);

            // testing for strings the same as String 2
            Console.WriteLine("
Which strings are the same as s2 [{0}]?", s2);
            Console.WriteLine("s1: {0} [{1}]",
                     String.Compare(s1, s2) == 0 ? "Same!" : "Different", s1);
            Console.WriteLine("s2: {0} [{1}]",
                     String.Compare(s2, s2) == 0 ? "Same!" : "Different", s2);
            Console.WriteLine("s3: {0} [{1}]",
                     String.Compare(s3, s2) == 0 ? "Same!" : "Different", s3);
            Console.WriteLine("s4: {0} [{1}]",
                     String.Compare(s4, s2) == 0 ? "Same!" : "Different", s4);
            Console.WriteLine("s5: {0} [{1}]",
                     String.Compare(s5, s2) == 0 ? "Same!" : "Different", s5);
            Console.WriteLine("s6: {0} [{1}]",
                     String.Compare(s6, s2) == 0 ? "Same!" : "Different", s6);

            // testing for strings the same as String 2, ignoring case
            Console.WriteLine("
Which strings are the same as s2 [{0}]
                                 ignoring case?", s2);
            Console.WriteLine("s1: {0} [{1}]",
                 String.Compare(s1, s2, true) == 0 ? "Same!" : "Different", s1);
            Console.WriteLine("s2: {0} [{1}]",
                 String.Compare(s2, s2, true) == 0 ? "Same!" : "Different", s2);
            Console.WriteLine("s3: {0} [{1}]",
                 String.Compare(s3, s2, true) == 0 ? "Same!" : "Different", s3);
            Console.WriteLine("s4: {0} [{1}]",
                 String.Compare(s4, s2, true) == 0 ? "Same!" : "Different", s4);
            Console.WriteLine("s5: {0} [{1}]",
                 String.Compare(s5, s2, true) == 0 ? "Same!" : "Different", s5);
            Console.WriteLine("s6: {0} [{1}]",
                 String.Compare(s6, s2, true) == 0 ? "Same!" : "Different", s6);
        }
        static void Main( )
        {
            Tester t = new Tester( );
            t.Run( );
        }
    }
}

Solution to Exercise 15-2. Take the following famous string:

To be, or not to be: That is the question: Whether ‘tis nobler in the mind to suffer the slings and arrows of outrageous fortune, or to take arms against a sea of troubles, and by opposing end them?

Reverse the order of the words in the string, and output the reversed string to the console.

The trick to reversing the order of words in a string is that you have to break the string apart into its component words, and then put the words back together into a new string. Taking a string apart is easy; that’s what Split( ) is for. In this case, the string contains spaces, commas, and colons, so you can use all three of those as delimiters.

Split( ) returns an array, and conveniently, the array class has the Reverse( ) static method, so you can quite easily get the words into reverse order. Once you have your reversed array, you just need a StringBuilder with a foreach loop to create the new, reversed string. Example A-43 shows one way to do it.

Example A-43. One solution to Exercise 15-2

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Exercise_15_2
{
    class Tester
    {
        public void Run( )
        {
            string myString = "To be, or not to be: That is the " +
                              "question: Whether 'tis nobler in " +
                              "the mind to suffer the slings and " +
                              "arrows of outrageous fortune, or to " +
                              "take arms against a sea of troubles, " +
                              "and by opposing end them?";

            char[] delimiters = {',', ':', ' '};

            String[] theStringArray = myString.Split(delimiters);
            Array.Reverse(theStringArray);

            StringBuilder sBuilder = new StringBuilder( );
            foreach (String subString in theStringArray)
            {
                sBuilder.AppendFormat("{0} ",subString);
            }

            Console.WriteLine(sBuilder);

        }
        static void Main( )
        {
            Tester t = new Tester( );
            t.Run( );
        }
    }
}

Solution to Exercise 15-3. Take the following famous string:

We choose to go to the moon. We choose to go to the moon in this decade and do the other things, not because they are easy, but because they are hard, because that goal will serve to organize and measure the best of our energies and skills, because that challenge is one that we are willing to accept, one we are unwilling to postpone, and one which we intend to win, and the others, too.

Write a program to determine and output to the screen the number of times the word the occurs in this string.

There are a number of ways to address this exercise. One valid way is to use the IndexOf( ) method to determine the index of the first instance of the string “the”. That works fine, but IndexOf( )finds only the first instance of the string. To find the next instance, you’ll need to use Substring( ) to cut off the beginning of the string you’re searching, from the first character up to the first character after the word the.

That’s not actually too hard, because IndexOf( ) returns the index of the letter t in the, so IndexOf("the ") + 4 gives you the index of the first word after the. It’s +4 instead of +3 because the search string includes a space—that way, you’ll find only instances of the word the, as opposed to the word these or thesaurus. Every time you find an instance of the, you take a substring and increment a counter. If you do it all in a while loop, you can chop down the string until there’s no instances of the remaining—when IndexOf("the ") returns –1. Example A-44 shows how we did it.

Example A-44. One solution to Exercise 15-3

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Exercise_15_3
{
    class Tester
    {
        public void Run( )
        {
            int theCount = 0;
            string theString = "We choose to go to the moon. " +
                               "We choose to go to the moon in " +
                               "this decade and do the other " +
                               "things, not because they are easy, " +
                               "but because they are hard, " +
                               "because that goal will serve to " +
                               "organize and measure the best of " +
                               "our energies and skills, because " +
                               "that challenge is one that we are " +
                               "willing to accept, one we are " +
                               "unwilling to postpone, and one which " +
                               "we intend to win, and the others, too. ";

            while (theString.IndexOf("the ") != -1)
            {
                theString = theString.Substring(theString.IndexOf("the ")
                                                + 4);
                theCount++;
            }
            Console.WriteLine("The word "the" occurs {0} times
                               in the string.", theCount);
        }
    }
    class Program
    {
        static void Main( )
        {
            Tester t = new Tester( );
            t.Run( );
        }
    }
}

Another way to solve this exercise would be to split the string into an array of substrings, and then compare each element in the array to the string “the”. That way is equally valid, but it creates a lot of strings in the array.

Solution to Exercise 15-4. Take the following string:

We hold these truths to be self-evident, that all men are created equal, that they are endowed by their Creator with certain unalienable Rights, that among these are Life, Liberty and the pursuit of Happiness.

and use a regular expression to split the string into words. Then create a new string that lists each word, one to a line, each prefaced with a line number.

There are a number of ways to accomplish splitting up a string into words. As you saw in the chapter, splitting a string with a Regex is more efficient than using the string’s Split( ) method. To do that, you’ll need to define a Regex with delimiters that match a comma, a space, or a comma followed by a space (you need that third one so that the Regex doesn’t separate commas from spaces). You then need to use the Split( ) method of the Regex class, as we showed you in Example 15-9, to split the string into its component words. Then you use a foreach loop, with a StringBuilder object to create the new string. Each time through the loop, you increment your counter to create the line number, and append a substring and a newline ( ) to the StringBuilder. Example A-45 shows one way to do it.

Be sure to add the using System.Text.RegularExpressions statement to the top of your program, or the Regex won’t work.

Example A-45. One solution to Exercise 15-4

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace Exercise_15_4
{
    class Tester
    {
        public void Run( )
        {
            string importantString = "We hold these truths to be self-evident, " +
                                     "that all men are created equal, that " +
                                     "they are endowed by their Creator with " +
                                     "certain unalienable Rights, that among " +
                                     "these are Life, Liberty and the pursuit " +
                                     "of Happiness.";

            Regex theRegex = new Regex(" |, |,");
            StringBuilder sBuilder = new StringBuilder( );
            int id = 1;
            foreach (string subString in theRegex.Split(importantString))
            {
                sBuilder.AppendFormat("{0}: {1}
", id++, subString);
            }
            Console.WriteLine("{0}", sBuilder);
        }
        static void Main( )
        {
            Tester t = new Tester( );
            t.Run( );
        }
    }
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset