Advanced Collections - csuohio.edugrail.cba.csuohio.edu/~matos/notes/ist-211/csNotes/...Advanced...

136
C# Programming: From Problem Analysis to Program Design 1 Advanced Collections C# Programming: From Problem Analysis to Program Design 4th Edition 8

Transcript of Advanced Collections - csuohio.edugrail.cba.csuohio.edu/~matos/notes/ist-211/csNotes/...Advanced...

C# Programming: From Problem Analysis to Program Design

1

Advanced

Collections

C# Programming: From Problem Analysis to Program Design

4th Edition

8

2

Chapter Objectives

3

Chapter Objectives (continued)

4

Two-Dimensional Arrays

Two-Dimensional Arrays (continued)

int [ , ] calories = { {900, 750, 1020}, {300, 1000, 2700},

{500, 700, 2100}, {400, 900, 1780},

{600, 1200, 1100}, {575, 1150, 1900},

{600, 1020, 1700} };

C# Programming: From Problem Analysis to Program Design

5

6

Two-Dimensional Representation

7

Two-Dimensional Arrays (continued)

type [ , ] identifier = new type [integral value, integral value];

int [ , ] calories = new int[7, 3];

8

Two-Dimensional Arrays (continued)

Figure 8-2 Two-dimensional calories array

9

Two-Dimensional Arrays (continued)

Console.WriteLine(calories.Length); // Returns 21

• GetLength( )

– GetLength(0)

– GetLength(1)

Console.WriteLine(calories.GetLength(1)); //Display 3 (columns)

Console.WriteLine(calories.GetLength(0)); //Display 7 (rows)

Console.WriteLine(calories.Rank); // returns 2 (# dimen)

Two-Dimensional Arrays (continued)

int [ , ] calories = new int[7, 3];

Console.WriteLine(calories.GetUpperBound(0)); // Returns 6 (row index)

foreach (int cal in calories) // Displays all values

Console.Write(cal + " ");

for (int r = 0; r < calories.GetLength(0); r++)

for (int c = 0; c < calories.GetLength(1); c++)

calories[r, c] = 0; // Initializes all cells (redundant)

10

Two-Dimensional Arrays (continued)

public static double[ ] CalculateAverageByDay (int[ , ] calories)

{

int sum = 0;

double[ ] dailyAverage = new double[7];

for (int r = 0; r < calories.GetLength(0); r++)

{

for (int c = 0; c < calories.GetLength(1); c++)

sum += calories[r, c];

dailyAverage[r] = (double)sum / calories.GetLength(1);

sum = 0;

}

return dailyAverage;

}

11

Two-Dimensional Arrays (continued)

public static double[ ] CalculateAverageByMeal(int[ , ] calories)

{

int sum = 0;

double[ ] mealAverage = new double[3];

for (int c = 0; c < calories.GetLength(1); c++)

{

for (int r = 0; r < calories.GetLength(0); r++)

sum += calories[r, c];

mealAverage[c] = (double)sum / calories.GetLength(0);

sum = 0;

}

return mealAverage;

}

C# Programming: From Problem Analysis to Program Design

12

Method returns array of

averages…col averages

Two-Dimensional Arrays (continued)

public static void DisplayAverageCaloriesPerMeal (int[ , ] calories)

{

double sum = 0;

for (int day = 0; day < calories.GetLength(0); day++)

for (int meal = 0; meal < calories.GetLength(1); meal++)

sum += calories[day, meal];

Console.WriteLine("\nCaloric Average Per Meal: {0:N0}",

sum / calories.Length);

}

13

Two-Dimensional Arrays (continued)

14

Two-Dimensional Arrays (continued)

Console.WriteLine("{0,-10}: {1,6}", mealTime[c ], mealAverage[c ].ToString("N0"));

({0,-10}

{1,6}

N0

15

16

Jagged Arrays

int[ ] [ ] anArray = new int[4] [ ];

anArray [0] = new int[ ] {100, 200};

anArray [1] = new int[ ] {11, 22, 37};

anArray [2] = new int[ ] {16, 72, 83, 99, 106};

anArray [3] = new int[ ] {1, 2, 3, 4};

for (int row = 0; row < anArray.GetLength(0); row++)

{

for (int col = 0; col < anArray[row].GetLength(1); col++)

Console.Write("[{0}][{1}]= {2}\t ",

row, col, anArray[row][col]);

Console.WriteLine();

}

17

Multidimensional Arrays

type [ , , ] identifier = new type [integral value1, integral value2, integral value3];

• Example (rectangular) int [ , , ] calories = new int [4 ,7 ,3];

(4 week; 7 days; 3 meals)

Allocates

storage for

84 elements

C# Programming: From Problem Analysis to Program Design

18

Multidimensional

Arrays (continued)

Upper bounds

on the indexes

are 3, 6, 2

Figure 8-4 Three-dimensional

array

Multidimensional Arrays (continued)

int [ , , ] calories = new int [4, 7, 4];

// Loop to place the row total in the last column, indexed by 3

for (int wk = 0; wk < calories.GetLength(0); wk++)

{

for (int da = 0; da < calories.GetLength(1); da++)

{

for (int ml = 0; ml < calories.GetLength(2) - 1; ml++)

{

calories[wk, da, 3] += calories[wk, da, ml];

}

}

}

C# Programming: From Problem Analysis to Program Design

19

Review CalorieCounter Example

Multidimensional Arrays (continued)

C# Programming: From Problem Analysis to Program Design

20

Index from the

calories array

for the day

number used

as index for

the string day

name array

21

String Class

String Class

string sValue = "C# Programming";

char c0 = sValue[0]; // c holds 'C'

char c1 = sValue[1]; // c holds '#'

char c2 = sValue[13]; // c holds 'g'

22

0 1 2 3 4 5 6 7 8 9 10 11 12 13

C # P r o g r a m m i n g

23

String Class

24 Table 8-2 Members of the string class

String Class

25 Table 8-2 Members of the string class (continued)

String Class

26 Table 8-2 Members of the string class (continued)

String Class

27 Table 8-2 Members of the string class (continued)

String Class

28 Table 8-2 Members of the string class (continued)

String Class

29 Table 8-2 Members of the string class (continued)

String Class

30 Table 8-2 Members of the string class (continued)

String Class

31 Table 8-2 Members of the string class (continued)

String Class

Compare Concat Copy

s = string.Copy(sValue);

Console.WriteLine(@"hello \t world");

//Displays: hello \t world

32

String Class

33

String Class – Example1 1 of 5

// create some strings to work with string s1 = "abcd"; string s2 = "ABCD"; string s3 = @"I see trees of green, red roses too I see them bloom for me and you and I think to myself what a wonderful world"; int result; // hold the results of comparisons // compare two strings, cas sensitive result = string.Compare(s1, s2); Console.WriteLine("compare s1: {0}, s2: {1}, result: {2}\n", s1, s2, result); // overloaded compare, takes boolean "ignore case" //(true = ignore case) result = string.Compare(s1, s2, true); Console.WriteLine("compare insensitive\n"); Console.WriteLine("s4: {0}, s2: {1}, result: {2}\n", s1, s2, result);

34

String Class – Example1 2 of 5

// concatenation method string s6 = string.Concat(s1, s2); Console.WriteLine("s6 concatenated from s1 and s2: {0}", s6); // use the overloaded '+' operator string s7 = s1 + s2; Console.WriteLine("s7 concatenated from s1 + s2: {0}", s7); // the string copy method string s8 = string.Copy(s7); Console.WriteLine("s8 copied from s7: {0}", s8); // use the overloaded '=' operator string s9 = s8; Console.WriteLine("s9 = s8: {0}", s9);

35

String Class – Example1 3 of 5

// three ways to compare for equality. Console.WriteLine("\nDoes s9.Equals(s8)?: {0}", s9.Equals(s8)); Console.WriteLine("Does Equals(s9,s8)?: {0}", string.Equals(s9, s8)); Console.WriteLine("Does s9==s8?: {0}", s9 == s8); // Two useful properties: the index and the length Console.WriteLine("\nString s9 is {0} characters long. ", s9.Length); Console.WriteLine("The 5th character is {1}\n", s9.Length, s9[4]); // test whether a string ends with a set of characters Console.WriteLine("s3:{0}\nEnds with wonderful?: {1}\n", s3, s3.EndsWith("wonderful"));

36

String Class – Example1 4 of 5

// return the index of the substring Console.WriteLine("\nThe first occurrence of wonderful "); Console.WriteLine("in s3 is {0}\n", s3.IndexOf("wonderful")); // insert the word excellent before "training" string s11 = s3.Insert(s3.IndexOf("wonderful"), "really "); Console.WriteLine("s11: {0}\n", s11); //tokenize the string, copy its words to array of strings char[] separators = { ' ', ',', '.', }; string[] tokens = s3.Split(separators, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < tokens.Length; i++) { Console.WriteLine("{0, -4} {1}", i,tokens[i].Trim()); }

37

String Class – Example1 5 of 5

38

String Class – Finding Substrings 1 of 3

// create some strings to work with string s1 = "One Two Three Four"; string sx = (string)s1.Clone(); //shallow copy string sx = (string)s1.Clone(); //shallow copy Console.WriteLine(Object.ReferenceEquals(s1, sx)); sx += "Five"; Console.WriteLine(Object.ReferenceEquals(s1, sx)); Console.WriteLine(sx); // get the index of the last space int ix = s1.LastIndexOf(" "); // get the last word. string s2 = s1.Substring(ix + 1);

• Substring( )

39

// set s1 to the substring starting at 0 // and ending at ix (the start of the last word // thus s1 has: one two three s1 = s1.Substring(0, ix); // find the last space in s1 (after two) ix = s1.LastIndexOf(" "); // set s3 to the substring starting at // ix, the space after "two" plus one more // therefore s3 = "three" string s3 = s1.Substring(ix + 1); // reset s1 to the substring starting at 0 // and ending at ix, thus the string "one two" s1 = s1.Substring(0, ix); // reset ix to the space between // "one" and "two" ix = s1.LastIndexOf(" "); // set s4 to the substring starting one // space after ix, thus the substring "two" string s4 = s1.Substring(ix + 1);

String Class – Finding Substrings 2 of 3

40

// reset s1 to the substring starting at 0 // and ending at ix ("one") s1 = s1.Substring(0, ix); // set ix to the last space, but there is // none so ix now = -1 ix = s1.LastIndexOf(" "); // set s5 to the substring at one past // the last space. there was no last space // so this sets s5 to the substring starting // at zero string s5 = s1.Substring(ix + 1); Console.WriteLine("s2: {0}\ns3: {1}", s2, s3); Console.WriteLine("s4: {0}\ns5: {1}\n", s4, s5); Console.WriteLine("s1: {0}\n", s1);

String Class – Finding Substrings 3 of 3

Strings – Example2

41

Strings – Example2

42

string str = "madamimadam"; string s = str.ToUpper().Trim(); //TODO remove whitespaces from str Console.WriteLine("\n\n" + s); int n = s.Length; while (n > 1) { char first = s[0]; char last = s[n - 1]; if (first != last) { Console.WriteLine("No, {0} is not a palindrome", str); return; } s = s.Substring(1, n - 2); Console.WriteLine(s); n = s.Length; } Console.WriteLine("Yes, {0} is a palindrome", str);

Strings – Example3

43

Strings – Example3

44

Strings – Example3

45

Account

number 7 9 9 2 7 3 9 8 7 1 x

Double

every

other 7 18 9 4 7 6 9 16 7 2 x

Sum

digits 7 9 9 4 7 6 9 7 7 2 x

Strings – Example3

46

char c = '7'; // The following statement converts the numeric character '7' to integer 7

int nc = c - '0';

// Converting integer value 7 to character '7' could be done as follows

c = (char)('0' + nc);

47

StringBuilder Class

• System.Text.StringBuilder

• String StringBuilder

Example: Make a string holding a greeting msg written in various languages. string s = "Hello World"; char c = s[6]; //c = 'W' s[6] = "w"; //ERROR: s is un-mutable //Works, but not the best possible performance s = s + " Hola mundo "; s = s + " Ciao mondo "; s = s + " Bonjour le monde "; //Better approach! System.Text.StringBuilder sb = new System.Text.StringBuilder(); sb.Append("Hello world "); sb.Append("Hola mundo "); sb.Append("Ciao modo "); sb.Append("Bonjour le monde ");

48

StringBuilder Class

49

StringBuilder Class – Example4A

//Reverse a string using a StringBuilder object string s = "hello world"; System.Text.StringBuilder sb = new System.Text.StringBuilder(); for (int i = s.Length - 1; i >= 0; i--) { sb.Append(s[i]); Console.WriteLine(sb.ToString()); } Console.WriteLine("StringBuilder: {0}",sb); string strVersion = sb.ToString(); Console.WriteLine("Plain string: {0}", strVersion);

50

StringBuilder Class – Example4B

//Assume string is "123abcxcba321" private static bool IsPalindrome(string s) { //detecting Palindromes StringBuilder sb = new StringBuilder(s); while(sb.Length >= 2) { char first = sb[0]; char last = sb[sb.Length - 1]; if (first != last) return false; sb.Remove(sb.Length-1, 1); sb.Remove(0, 1); } return true; }

madam nurses run

.NET Collection Classes

– ArrayLists

– Generic List<T>

– BitArray

– Dictionary (and HashTable)

– Set (and HashSet)

– Stack

– Queue

– LinkedList

51

52

ArrayList Class

ArrayList Class (continued)

ArrayList list0 = new ArrayList();

ArrayList list1 = new ArrayList() { 11.50, 99, "X" };

53

using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace TestingIdeas { class Program { static void Main(string[] args) { ArrayList list1 = new ArrayList(); ... } } }

54

ArrayList Class

55

ArrayList Example5

0 1 2 3 4 5

aaa bbb ccc ddd eee fff

6

xxx

list.Add(Obj)

list

2

yyy

list.Insert(2,Obj)

list.Remove()

list.RemoveAt(2)

Count

56

ArrayList Example5

0 1 2 3 4 5

aaa bbb ccc ddd eee fff

list

list.RemoveAt(2)

0 1 2 3 4

aaa bbb ddd eee fff

list.Remove ("aaa")

0 1 2 3

bbb ddd eee fff

57

ArrayList Example5

list

list.Insert(2, "yyy")

list.Add ("xxx")

0 1 2 3

bbb ddd eee fff

0 1 2 3 4

bbb ddd yyy eee fff

0 1 2 3 4 5

bbb ddd yyy eee fff xxx

ArrayList Class – Methods

Methods Description

Add(Object) Adds an object to the end of the ArrayList.

AddRange(ICollection) Adds the elements of an ICollection to the end of the ArrayList.

BinarySearch(Int32, Int32,

Object, IComparer)

Searches a range of elements in the sorted ArrayList for an element using the specified comparer and returns the zero-based index of the element.

BinarySearch(Object) Searches the entire sorted ArrayList for an element using the default comparer and returns the zero-based index of the element.

BinarySearch(Object,

IComparer)

Searches the entire sorted ArrayList for an element using the specified comparer and returns the zero-based index of the element.

Clear() Removes all elements from the ArrayList.

Clone() Creates a shallow copy of the ArrayList.

Contains(Object) Determines whether an element is in the ArrayList.

CopyTo(Array) Copies the entire ArrayList to a compatible one-dimensional Array, starting at the beginning of the target array.

CopyTo(Array, Int32) Copies the entire ArrayList to a compatible one-dimensional Array, starting at the specified index of the target array.

CopyTo(Int32, Array, Int32,

Int32)

Copies a range of elements from the ArrayList to a compatible one-dimensional Array, starting at the specified index of the target array.

58

Methods Description

Equals(Object) Determines whether the specified object is equal to the current object.(Inherited from Object.)

GetRange(Int32, Int32) Returns an ArrayList which represents a subset of the elements in the source ArrayList.

IndexOf(Object) Searches for the specified Object and returns the zero-based index of the first occurrence within the entire ArrayList.

IndexOf(Object, Int32) Searches for the specified Object and returns the zero-based index of the first occurrence within the range of elements in the ArrayList that extends from the specified index to the last element.

IndexOf(Object, Int32, Int32) Searches for the specified Object and returns the zero-based index of the first occurrence within the range of elements in the ArrayList that starts at the specified index and contains the specified number of elements.

Insert(Int32, Object) Inserts an element into the ArrayList at the specified index.

InsertRange(Int32, ICollection) Inserts the elements of a collection into the ArrayList at the specified index.

LastIndexOf(Object) Searches for the specified Object and returns the zero-based index of the last occurrence within the entire ArrayList.

LastIndexOf(Object, Int32) Searches for the specified Object and returns the zero-based index of the last occurrence within the range of elements in the ArrayList that extends from the first element to the specified index.

Remove(Object) Removes the first occurrence of a specific object from the ArrayList.

RemoveAt(Int32) Removes the element at the specified index of the ArrayList.

RemoveRange(Int32, Int32) Removes a range of elements from the ArrayList.

Repeat(Object, Int32) Returns an ArrayList whose elements are copies of the specified value.

ArrayList Class – Methods

59

Methods Description

Reverse() Reverses the order of the elements in the entire ArrayList.

Reverse(Int32, Int32) Reverses the order of the elements in the specified range.

SetRange(Int32, ICollection) Copies the elements of a collection over a range of elements in the ArrayList.

Sort() Sorts the elements in the entire ArrayList.

Sort(IComparer) Sorts the elements in the entire ArrayList using the specified comparer.

Sort(Int32, Int32, IComparer) Sorts the elements in a range of elements in ArrayList using the specified comparer.

ToArray() Copies the elements of the ArrayList to a new Object array.

ToArray(Type) Copies the elements of the ArrayList to a new array of the specified element type.

ToString() Returns a string that represents the current object.(Inherited from Object.)

TrimToSize() Sets the capacity to the actual number of elements in the ArrayList.

ArrayList Class – Methods

60

ArrayList – Example6

ArrayList list1 = new ArrayList()

{ "aaa", "bbb", "ccc", "ddd", "eee","fff" };

ShowList("original list1", list1);

list1.RemoveAt(2);

ShowList("after list1.RemoveAt(2)", list1);

list1.Remove("aaa");

ShowList("after list1.Remove(\"aaa\")", list1);

list1.Insert(2, "yyy");

ShowList("after list1.Insert(2, \"yyy\")", list1);

list1.Add(2, "xxx");

ShowList("after list1.Add(2, \"xxx\")", list1);

61

ArrayList Example7

private static void ShowList(string msg, ArrayList list)

{

Console.WriteLine("\n" + msg);

Console.Write ("\t[");

for (int i = 0; i < list.Count; i++)

{

Console.Write("{0}:{1}, ",i, list[i]);

}

Console.Write("]");

Console.WriteLine();

}

62

Using ArrayLists (a little digression)

Source http://www.csharp-examples.net/culture-names/ Visited 2/5/2018

63

// get culture names List<string> list = new List<string>(); foreach (CultureInfo ci in CultureInfo.GetCultures(CultureTypes.AllCultures)) { string specName = "(none)"; try { specName = CultureInfo.CreateSpecificCulture(ci.Name).Name; } catch { } list.Add(String.Format("{0,-12}{1,-12}{2}", ci.Name, specName, ci.EnglishName)); } list.Sort(); // sort by name // write to console Console.WriteLine("CULTURE SPEC.CULTURE ENGLISH NAME"); Console.WriteLine(new string('-',62)); foreach (string str in list) Console.WriteLine(str);

Using ArrayLists

Internalization (sample output)

Source http://www.csharp-examples.net/culture-names/ Visited 2/5/2018 64

Using ArrayLists

(another digression)

65

double value = 1234.56; DateTime dt = DateTime.UtcNow.Date; CultureInfo.CurrentCulture = new CultureInfo("es-VE"); //español-VENEZUELA Console.WriteLine("\nCurrent Culture: {0}", CultureInfo.CurrentCulture.Name); Console.WriteLine("Local Money\t {0:C2}", value); Console.WriteLine("Local Numb.\t {0:N2}", value); Console.WriteLine("Date Now \t {0}", dt); CultureInfo.CurrentCulture = new CultureInfo("en-US"); //english-USA Console.WriteLine("\nCurrent Culture: {0}", CultureInfo.CurrentCulture.Name); Console.WriteLine("Local Money\t {0:C2}", value); Console.WriteLine("Local Numb.\t {0:N2}", value); Console.WriteLine("Date Now \t {0}", dt); CultureInfo.CurrentCulture = new CultureInfo("fr-CA"); //french-CANADA Console.WriteLine("\nCurrent Culture: {0}", CultureInfo.CurrentCulture.Name); Console.WriteLine("Local Money\t {0:C2}", value); Console.WriteLine("Local Numb.\t {0:N2}", value); Console.WriteLine("Date Now \t {0}", dt);

Generic List<T>

66

• List<T>

ArrayList

0 1 2 n-2 n-1

Generic List<T>

67

Suggestion:

• ArrayLists should not be used in new designs, treat

them as 'legacy' structures.

• Instead, choose the generic List<T> class for dynamic

lists.

Generic List<T>

68

List<String> listX = new List<String>(); List<String> list1 = new List<String>() { "aaa", "bbb", "ccc", "ddd", "eee", "fff" }; list1.RemoveAt(2); // aaa, bbb, ddd, eee, fff list1.Remove("aaa"); // bbb, ddd, eee, fff list1.Insert(2, "yyy"); // bbb, ddd, yyy, eee, fff list1.Add("xxx"); // bbb, ddd, yyy, eee, fff, xxx

In this example all

entries are strings

Generic List<T>

69

private static void ShowList<T>(string msg, List<T> list) { Console.WriteLine("\n" + msg); Console.Write("\t["); for (int i = 0; i < list.Count; i++) { Console.Write("{0}:{1}, ", i, list[i]); } Console.Write("]"); Console.WriteLine();

}

Example of a Generic Method

Generic List<T> - Example8

70

Sort OrderBy Max(), Min()

List<int>

FindMax FindMin FindNthLargest

Random random = new Random(); int value1 = random.Next(); //produce an arbitrary random value int value2 = random.Next(10, 21); //make a no. 10..20 (inclusive) int value3 = random.Next(21); // return a number 0..20

Generic List<T> - Example8

71

private static List<int> CreateIntList()

(Try following methods without sorting!)

private static void ShowList(List<int> list) private static int FindMax(List<int> list) private static int FindMin(List<int> list)

private static int FindNthLargest(int n, List<int> list)

Generic List<T> - Example8B 1 of 2

72

class Student { //Private data members and Properties private string studName; private int studGpa; public int StudGpa { get { return studGpa; } set { studGpa = value; } } public string StudName { get { return studName; } set { studName = value; } } //constructors public Student() { StudName = "n.a"; StudGpa = 0; } public Student(string studNameValue, int studGpaValue) { StudName = studNameValue; StudGpa = studGpaValue; } //user-defined methods public override string ToString() { return "Student [Name: " + StudName + " GPA: " + StudGpa + "]"; } }

Generic List<T> - Example8B 2 of 2

73

Student s1 = new Student("Harry Potter", 3.99); Student s2 = new Student("Hermione Granger", 4.0); //create a list for the entire school (Hogwarts) holding two students List<Student> listHogwarts = new List<Student>() { s1, s2 }; ShowGenericList("original list", listHogwarts); //add more students to the school listHogwarts.Add(new Student("Draco Malfoy", 3.5)); listHogwarts.Insert(0, new Student("Ron Weasley", 3.55)); ShowGenericList("after insertions", listHogwarts); //create a list for Gryffindor House List<Student> listGriffindor = new List<Student>(); listGriffindor.Add(listHogwarts[0]); //add Ron listGriffindor.Add(listHogwarts[1]); //add Harry listGriffindor.Add(listHogwarts[2]); //add Hermione //put Draco in his own Slytherin list List<Student> listSlytherin = new List<Student>() { listHogwarts[3] }; ShowGenericList("Gryffindor House", listGriffindor);

Generic List<T> - Example8B 2 of 2

74

Generic List<T> - Example9

75

List<int> list1 list2

76

var list1 = new List<int>() { 1, 3, 5 }; var list2 = new List<int>() { 2, 3, 5, 6, 7 }; var list3 = list1.Union(list2); ShowList("union", list3); //prints 1, 3, 5, 2, 6, 7 // --------------------------------------------------------------- private static void ShowGenericList<T>(string msg, IEnumerable<T> list) { Console.WriteLine("\n" + msg); Console.Write("\t["); int i = 0; foreach (T val in list) { Console.Write("{0}:{1}, ", i, val); } Console.Write("]"); Console.WriteLine(); }

Extension methods are a new

feature in C# 3.0. An extension

method enables us to

add methods to existing types

without creating a new derived type,

recompiling, or modify the original

types. An extension method is a

static method to the existing static

class.

The new implicit type var is used for

convenience. The compiler determines

the type. The following two declarations

of i are functionally equivalent

var i = 10; // implicitly typed int i = 10; //explicitly typed

Generic List<T> - Example9

In c#, IEnumerable is the abstract collection

superclassand IEnumerator is the abstract Iterator.

BitArray class

77

0 1 2 3 4 5

true true true false false false

1 1 1 0 0 0

Index →

Values →

Bits →

OR True False

True True True

False True False

AND True False

True True False

False False False

XOR True False

True True False

False False True

NOT

True False

False True

BitArray class

// combine heroes from the houses of winterFell and dragonStone

BitArray allies = winterFell.Or(dragonStone);

winterFell = { true, true, true, false, false, false } dragonStone = { false, false, false, false, false, true }

heroe array

allies = { true, true, true, false, false, true}

0 1 2 3 4 5

BitArray class

79

String[] dragon = { "Drogo", "Rhaegal", "Viserion", }; BitArray meanDragon = new BitArray(3, true); //all dragons are mean String[] heroe = { "Sansa", "Arya", "Jon", "Tyrion", "Cersei", "Daenerys" }; BitArray winterFell = new BitArray(new bool[] { true, true, true, false, false, false }); BitArray kingsLanding = new BitArray(new bool[] { false, false, false, true, true, false }); BitArray dragonStone = new BitArray(new bool[] { false, false, false, false, false, true }); // An alliance between the houses of winterFell and dragonStone could be // represented by the bit-wise OR operator which generates // the sequence { true, true, true, false, false, true }. This result applied // to the heroe collection identifies {Sansa, Arya, Jon, -, -, Daenerys }

BitArray allies = winterFell.Or(dragonStone);

BitArray class – Example10

80

BitArray ba1 = new BitArray(new bool[] { true, true, false, false}); BitArray ba1Copy = ba1; BitArray ba2 = new BitArray(new bool[] { true, false, true, false }); ShowBitArray("BitArray ba1 ", ba1); ShowBitArray("BitArray ba2 ", ba2); ba1 = ba1Copy; ba1.SetAll(false);//ba1 = {false, false, false, false} ShowBitArray("ba1 after ba1.SetAll(false) ", ba1); ba1 = ba1Copy; ba1.Set(2,true);//ba1 = {true, true, true, false} ShowBitArray("ba1 after ba1.Set(2,true) ", ba1); ba1 = ba1Copy; ba1.And(ba2); //ba1 = {true, false, false, false} ShowBitArray("ba1 after ba1.And(ba2) ", ba1); ba1 = ba1Copy; ba1.Or(ba2); //ba1 = {true, true, true, false} ShowBitArray("ba1 after ba1.Or(ba2) ", ba1); ba1 = ba1Copy; ba1.Xor(ba2); //ba1 = {false, true, true, false} ShowBitArray("ba1 after ba1.Xor(ba2) ", ba1); ba1 = ba1Copy; ba1.Not();//ba1 = {false, false, true, true} ShowBitArray("ba1 after ba1.Not() ", ba1);

This example uses

BitArray methods:

SetAll(), Set(), And(),

Or(), Xor(), and Not()

BitArray Methods

81

And(BitArray) Performs the bitwise AND operation between the elements of the current BitArray object and the corresponding elements in the specified array. The current BitArray object will be modified to store the result of the bitwise AND operation.

Clone() Creates a shallow copy of the BitArray.

CopyTo(Array, Int32) Copies the entire BitArray to a compatible one-dimensional Array, starting at the specified index of the target array.

Equals(Object) Determines whether the specified object is equal to the current object.(Inherited from Object.)

Get(Int32) Gets the value of the bit at a specific position in the BitArray.

Not() Inverts all the bit values in the current BitArray, so that elements set to true are changed to false, and elements set to false are changed to true.

Or(BitArray) Performs the bitwise OR operation between the elements of the current BitArray object and the corresponding elements in the specified array. The current BitArray object will be modified to store the result of the bitwise OR operation.

Set(Int32, Boolean) Sets the bit at a specific position in the BitArray to the specified value.

SetAll(Boolean) Sets all bits in the BitArray to the specified value.

ToString() Returns a string that represents the current object.(Inherited from Object.)

Xor(BitArray) Performs the bitwise exclusive OR operation between the elements of the current BitArray object against the corresponding elements in the specified array. The current BitArray object will be modified to store the result of the bitwise exclusive OR operation.

Dictionary<K,V> - Hashtable

82

Dictionary – HashTable – Methods and Properties

Note: To write your own hash algorithm,

– Override the GetHashCode() method and provide a new algorithm for the hash

function

– Should also override the Equals() method to guarantee that two objects

considered equal have the same hash code 83

Dictionary – Example11 1 of 2

// VERSION 1

// Create a new dictionary to store the association

// between a country and its capital city

// Observe that KEY and VALUE are both of string type

Dictionary<string, string> dictionary = new Dictionary<string, string>();

// Add some elements to the dictionary.

dictionary.Add("USA", "Washington");

dictionary.Add("Italy", "Rome");

dictionary.Add("Spain", "Madrid");

dictionary.Add("India", "New Delhi");

Console.WriteLine(dictionary["Italy"]); //Rome

84

KEY VALUE

USA Washington

Italy Rome

Spain Madrid

India New Delhi

Dictionary – Example11 2 of 2

// VERSION 2

// Create a new dictionary to store the association

// between a country and its capital city

// Observe that KEY and VALUE are both of string type

Dictionary<string, string> dictionary = new Dictionary<string, string>()

{

{"USA", "Washington"},

{"Italy", "Rome" },

{ "Spain", "Madrid"},

{ "India", "New Delhi"},

};

Console.WriteLine(dictionary["Italy"]); //Rome

85

KEY VALUE

USA Washington

Italy Rome

Spain Madrid

India New Delhi

Hashtable- Example12 // Create a new hash table to store the association

// between file extension and its default app

// Observe that no type constraint is asked of Key or Value

Hashtable hTable= new Hashtable();

// Add some elements to the hash table. There are no

// dup. keys, but some of the values are duplicates.

hTable.Add("pdf", "acrord32.exe"); //Acrobat Reader

hTable.Add("jpg", "mspaint.exe"); //MS-Paint

hTable.Add("doc", "winword.exe"); //MS-Word

hTable.Add("xls", "excel.exe"); //MS-Excel

Console.WriteLine(hTable["pdf"]); //acrord32.exe

WARNING: Hashtables have no type checking – Potentially dangerous!

hTable.Add("odd", 12345); //would be accepted – value is a number

hTable.Add(123, "XYZ"); //would be accepted – key is a number

hTable.Add("123", "ABC"); //would be accepted – key is a quoted number

86

87

Dictionary – Example11B 1 of 4

Cookie Starts With C Now what starts with the letter C? Cookie starts with C Let's think of other things that starts with C Oh, who cares about the other things? C is for cookie, that's good enough for me C is for cookie, that's good enough for me C is for cookie, that's good enough for me Oh, cookie, cookie, cookie starts with C C is for cookie, that's good enough for me C is for cookie, that's good enough for me C is for cookie, that's good enough for me Oh, cookie, cookie, cookie starts with C Hey you know what? A round cookie with one bite out of it Looks like a C A round donut with one bite out of it also looks like a C But it is not as good as a cookie Oh and the moon sometimes looks like a C But you can't eat that, so C is for cookie, that's good enough for me, yeah! C is for cookie, that's good enough for me C is for cookie, that's good enough for me Oh, cookie, cookie, cookie starts with C, yeah! Cookie, cookie, cookie starts with C, oh boy! Cookie, cookie, cookie starts with C! Umm-umm-umm-umm-umm

88

Dictionary – Example11B 2 of 4

static void Main(string[] args) { // Cookie Starts With C by Joe Raposo string lyrics = @" Cookie Starts With C Now what starts with the letter C? Cookie starts with C Let's think of other things that starts with C Oh, who cares about the other things? C is for cookie, that's good enough for me C is for cookie, that's good enough for me C is for cookie, that's good enough for me Oh, cookie, cookie, cookie starts with C C is for cookie, that's good enough for me C is for cookie, that's good enough for me C is for cookie, that's good enough for me Oh, cookie, cookie, cookie starts with C Hey you know what? A round cookie with one bite out of it Looks like a C A round donut with one bite out of it also looks like a C But it is not as good as a cookie Oh and the moon sometimes looks like a C But you can't eat that, so C is for cookie, that's good enough for me, yeah! C is for cookie, that's good enough for me C is for cookie, that's good enough for me Oh, cookie, cookie, cookie starts with C, yeah!

89

Dictionary – Example11B 3 of 4

Cookie, cookie, cookie starts with C, oh boy! Cookie, cookie, cookie starts with C! Umm-umm-umm-umm-umm"; // No-Break character &nbsp; (ASCII 160 = 00A0) is not the same as space char[] separators = new char[] { ',', '!', '?', ' ', '-', '\n', '\t', '\r', '\u00A0' }; string[] token = lyrics.ToUpper().Split(separators, StringSplitOptions.RemoveEmptyEntries); Dictionary<string, int> dictionary = new Dictionary<string, int>(); for (int i=0; i<token.Length; i++) { Console.WriteLine("{0} \t {1}", i, token[i]); string keyWord = token[i]; if (dictionary.ContainsKey(keyWord)) { //add 1 to existing count int value = dictionary[keyWord]; dictionary[keyWord] = ++value; value = dictionary[keyWord]; } else { //introduce new word in the dictionary dictionary[keyWord] = 1; } } PrintDictionary(dictionary); Console.Read(); }//Main

90

Dictionary – Example11B 4 of 4

private static void PrintDictionary(Dictionary<string, int> dictionary) { Console.WriteLine("\n\nDictionary (Size {0})\n", dictionary.Count); Console.WriteLine("Key Count Frequency%"); double total = (double)dictionary.Count; foreach(string key in dictionary.Keys) { int value = dictionary[key]; Console.WriteLine("{0, -11} {1, 3:N0} {2, 5:N0}", key, value, 100*value/total); } }

LinkedList<T>

LinkedListNode<T> node

91

Previous Value Next

A reference

to predecessor

Node or null

This field accepts

any data item of

type T

A reference

to successor

Node or null

LinkedList<T>

92

Previous Value Next

null JON

Previous Value Next

ARYA

Previous Value Next

SANSA null

FIRST LAST

LinkedList<String>

LinkedList<T>

93

Previous Value Next

null JON

Previous Value Next

ARYA

Previous Value Next

SANSA null

First

Before

Previous Value Next

null JON

Previous Value Next

ARYA

Previous Value Next

SANSA null

After

Last

First Last

Previous Value Next

BRAN

LinkedList<T>

94

Before

Previous Value Next

null JON

Previous Value Next

ARYA

Previous Value Next

SANSA null

First Last

Previous Value Next

BRAN

After

Previous Value Next

null JON Previous Value Next

SANSA null

First Last

Previous Value Next

BRAN

Example13 – Using Linked List 1 of 5

static void Main(string[] args)

{

// Create the linked list, using given words string[] words = { "the", "fox", "jumped", "over", "the", "dog" }; LinkedList<string> sentenceList = new LinkedList<string>(words); // Traversing (Version-1) - using default iterators foreach (string singleWord in sentenceList) { Console.WriteLine( singleWord); } Console.WriteLine("\n"); // NOTE: There is no indexed access, sentenceList[i] is not defined! // Get ready to visit each node Console.WriteLine("{0, -10} : [ {1, -10} {2, -10} {3, -10}]", "Reference", "Previous", "Next", "Value"); Console.WriteLine(new String('-', 53));

95

Example13 – Using Linked List 2 of 5

// traversing (version-2)- using references to Next and Previous LinkedListNode<string> node = sentenceList.First; while (node != null) { Console.WriteLine("{0, -10} : [ {1, -10} {2, -10} {3, -10}]", GetReference(node), GetReference(node.Previous), GetReference(node.Next), node.Value ); node = node.Next; // advance to next node } }//Main // ---------------------------------------------------------------- private static Object GetReference(LinkedListNode<string> node) { if (node == null) return "NULL"; else return node.GetHashCode(); //object's unique internal reference }

96

Example13 – Using Linked List 3 of 5

97

n

u

l

l

t

h

e

f

o

x

j

u

m

p

e

d

o

v

e

r

t

h

e

d

o

g

n

u

l

l

First

@ 54267293

Last

@ 48285313

Example13 – Using Linked List 4 of 5

98

n

u

l

l

t

h

e

f

o

x

j

u

m

p

e

d

o

v

e

r

t

h

e

d

o

g

n

u

l

l

First

@ 54267293

Last

@ 48285313

l

a

z

y

o

l

d

//Find the last occurrence of the word "dog" LinkedListNode<String> nodeDog = sentenceList.FindLast("dog"); if(nodeDog != null) { //two ways to add data in front of the node holding the word "dog" LinkedListNode<String> nodeLazy = new LinkedListNode<string>("lazy"); sentenceList.AddBefore(nodeDog, nodeLazy); sentenceList.AddBefore(nodeDog, "old"); }

Add new nodes

Example13 – Using Linked List 5 of 5

99

private static void ShowLinkedList<T>(LinkedList<T> sentenceList) { // traversing - using references to Next and Previous Console.WriteLine("{0, -10} : [ {1, -10} {2, -10} {3, -10}]", "Reference", "Previous", "Next", "Value"); Console.WriteLine(new String('-', 53)); LinkedListNode<T> node = sentenceList.First; while (node != null) { Console.WriteLine("{0, -10} : [ {1, -10} {2, -10} {3, -10}]", GetReference(node), GetReference(node.Previous), GetReference(node.Next), node.Value); node = node.Next; // advance to next node } } private static Object GetReference<T>(LinkedListNode<T> node) { if (node == null) return "NULL"; else return node.GetHashCode(); //object's unique internal reference }

ShowLinkedList(sentenceList);

LinkedList<T> Methods and Attributes

100

AddAfter(LinkedListNode<T>, T)

AddAfter(LinkedListNode<T>,

LinkedListNode<T>)

Adds a new node containing the specified value after the specified existing node in

the LinkedList<T>.

AddBefore(LinkedListNode<T>, T)

AddBefore(LinkedListNode<T>,

LinkedListNode<T>)

Adds a new node containing the specified value before the specified existing node in

the LinkedList<T>.

AddFirst(T) Adds a new node containing the specified value at the start of the LinkedList<T>.

AddFirst(LinkedListNode<T>) Adds the specified new node at the start of the LinkedList<T>.

AddLast(T) Adds a new node containing the specified value at the end of the LinkedList<T>.

AddLast(LinkedListNode<T>) Adds the specified new node at the end of the LinkedList<T>.

Clear() Removes all nodes from the LinkedList<T>.

Contains(T) Determines whether a value is in the LinkedList<T>.

CopyTo(T[], Int32) Copies the entire LinkedList<T> to a compatible one-dimensional Array, starting at

the specified index of the target array.

Find(T) Finds the first node that contains the specified value.

FindLast(T) Finds the last node that contains the specified value.

GetHashCode() Serves as the default hash function. (Inherited from Object.)

Remove(T) Removes the first occurrence of the specified value from the LinkedList<T>.

Remove(LinkedListNode<T>) Removes the specified node from the LinkedList<T>.

RemoveFirst() Removes the node at the start of the LinkedList<T>.

RemoveLast() Removes the node at the end of the LinkedList<T>.

Generic Queue<T>

From http://compsci.hunter.cuny.edu/~sweiss/course_materials/csci235/lecture_notes/chapter_07.pdf

101

front back

Dequeue() Enqueue()

Inserting into and deleting from a Queue

C# Programming: From Problem Analysis to Program Design

102

Queue<T> Methods

Method Description

Clear() Removes all objects from the Queue.

Clone() Creates a shallow copy of the Queue.

Contains(Object) Determines whether an element is in the Queue.

Dequeue() Removes and returns the object at the beginning of the Queue.

Enqueue(Object) Adds an object to the end of the Queue.

Peek() Returns the object at the beginning of the Queue without removing it.

ToArray() Copies the Queue elements to a new array.

TrimToSize() Sets the capacity to the actual number of elements in the Queue.

Queue<String> q = new Queue<String>(); q.Enqueue("aa"); q.Enqueue("bb"); q.Enqueue("cc"); while (q.Count > 0) { string header = q.Dequeue(); Console.Write ("{0} ", header ); }

Queue –Example 14

103

aa bb cc

aa

aa bb tail

head tail

tail

Queue –Example 15

104

Queue –Example16 - Radix Sort 1 of 3

IBM Sorting Machine.

Circa 1949.

http://www.youtube.com/watch?v=2RCgIrZiC6c

Queue –Example16 – Radix Sort 2 of 3

106

private static void RadixSort() { Queue<int>[] qBin = new Queue<int>[10]; //Bin-0, Bin-1, ..., Bin-9 //int[] data = { 91, 46, 85, 15, 92, 35, 31, 22 }; //assume all are two-digit numbers int[] data = { 191, 246, 885, 315, 192, 835, 331, 422 }; //initialize each Bin to an empty queue for (int p = 0; p < qBin.Length; p++) { qBin[p] = new Queue<int>(); } // extract i-th significant digit (beginning from rightmost position), // use extracted digit to allocate the number in the corresponding Bin int NUM_DIGITS = data[0].ToString().Length; for (int i = 0; i < NUM_DIGITS; i++) { qBin[i] = new Queue<int>(); int div = Convert.ToInt32(Math.Pow(10, i )); for (int d = 0; d < data.Length; d++) { int digit = data[d] / div % 10; qBin[digit].Enqueue(data[d]); } MoveBinsToArray(qBin, data); } }

Queue –Example16 – Radix Sort 3 of 3

107

private static void MoveBinsToArray(Queue<int>[] qBin, int[] data) { // starting with Bin-0 transfer all queued data items to data array for (int p = 0, i=0; p < qBin.Length; p++) { Console.Write("\nBin:{0} ", p); while (qBin[p].Count > 0) { int number = qBin[p].Dequeue(); data[i++] = number; Console.Write("{0}, ", number); } }

Generic Stack<T>

108

Generic Stack<T>

When / Where are Stacks used?

109

Generic Stack<T>

110

Method Description

Clear() Removes all objects from the Stack

Clone() Creates a shallow copy of the Stack.

Contains(Object) Determines whether an element is in the Stack.

Peek() Returns the object at the top of the Stack without

removing it.

Pop() Removes and returns the object at the top of the Stack.

Push(Object) Inserts an object at the top of the Stack.

ToArray() Copies the Stack to a new array.

Stack<int> stk = new Stack<int>(); stk.Push(11); stk.Push(22); stk.Push(33); while (stk.Count > 0) { Console.WriteLine( "Remaining elements: {0} (Peeking) Top: {1} ", stk.Count, stk.Peek()); int topElement = stk.Pop(); Console.WriteLine("Removed element: {0}", topElement); }

Stack – Example17

111

33

22

11

← top

Stack – Example18 1 of 2

112

( [ { A } ( B ) ] )

{

[

(

top A } ( B ) ] )

Stack – Example18 2 of 2

113

private static bool IsExpBalanced(string exp) { //GOAL: The method decides if a mathematical expression (exp) is balanced. //e.g. ([{A}]), ((A)B), and ([A](B{C}D)) are balanced, however (({A B)] is not. string openParenthesis = "({["; string closeParenthesis = ")}]"; Stack<char> stack = new Stack<char>(); int openPos, closePos; foreach (char ch in exp) { openPos = openParenthesis.IndexOf(ch); closePos = closeParenthesis.IndexOf(ch); if (openPos != -1) { stack.Push(ch); } if (closePos != -1) { if (stack.Count == 0) return false; //pop symbol from stack, check if extracted parenthesis matches ch char cOpen = stack.Pop(); bool okMatch = ((cOpen == '(' && ch == ')') || (cOpen == '{' && ch == '}') || (cOpen == '[' && ch == ']')); if (!okMatch) return false; } } if (stack.Count > 0) return false; return true; }

Stacks and Queues – Example20

Stacks and Queues – Example20

//simulation of a railroad car rearrangement at a switching station

//right and center tracks are stacks (only the head car could be moved)

//left track is a queue; cars are attached at the rear portion. There are 4 car

Stack<int> rightStack = new Stack<int>(); //1 should be the top

rightStack.Push(4);

rightStack.Push(3);

rightStack.Push(2);

rightStack.Push(1); // top is 1

Stack<int> centerStack = new Stack<int>();

Queue<int> leftQueue = new Queue<int>();

// prepare left sequence: 4, 2, 3, 1

centerStack.Push(rightStack.Pop()); // push car 1 on center stack

centerStack.Push(rightStack.Pop()); // push car 2 on center stack

centerStack.Push(rightStack.Pop()); // push car 3 on center stack

centerStack.Push(rightStack.Pop()); // push car 4 on center stack

leftQueue.Enqueue(centerStack.Pop()); //add car 4 to left track (done with 4)

rightStack.Push(centerStack.Pop()); // send car 3 back to right track

leftQueue.Enqueue(centerStack.Pop()); //add car 2 to left track

centerStack.Push(rightStack.Pop()); //add car 3 to center stack;

leftQueue.Enqueue(centerStack.Pop()); //add car 3 to left track

leftQueue.Enqueue(centerStack.Pop()); // add car 1 to left track

Generic HashSet<T>

116

Generic HashSet<T>

117

Generic HashSet<T> - Example21

118

HashSet<int> set = new HashSet<int>(); set.Add(11); set.Add(22); set.Add(22); set.Add(33); foreach (int element in set) Console.WriteLine(element); Console.WriteLine("Is 33 in the set? {0}", set.Contains(33)); Console.WriteLine( "Remove 33 {0}", set.Remove(33)); for (int i = 0; i < set.Count; i++) { Console.WriteLine("Pos {0} holds {1}", i, set.ElementAt(i)); }

Generic HashSet<T> - Example22 1of 2

119

public void TestSetOperations() { HashSet<int> set1 = new HashSet<int>() { 11, 33 }; HashSet<int> set2 = new HashSet<int>() { 22, 33, 44, 55 }; ShowSet("set2", set2); // compute UnionWith. Observe set3 is modified! HashSet<int> set3 = new HashSet<int>(set1); set3.UnionWith(set2); ShowSet("Union", set3); // compute InstersectWith set3 = new HashSet<int>(set1); set3.IntersectWith(set2); ShowSet("Intersect", set3); // compute Minus (custom made) set3 = new HashSet<int>(set1); set3 = Minus(set3, set2); ShowSet("Minus", set3); }

Generic HashSet<T> - Example22 2 of 2

120

Problem.

Explore set operations UnionWith, InsectWith, and custom Minus

// custom made version of Minus operator public static HashSet<T> Minus<T>(HashSet<T> s1, HashSet<T> s2){ HashSet<T> sTemp = new HashSet<T>(); foreach(T element in s1){ if (!s2.Contains(element)) { sTemp.Add(element); } } return sTemp; } // print contents of the set public static void ShowSet<T>(string msg, HashSet<T> set) { Console.Write("\n {0}\n [", msg); foreach (T element in set) { Console.Write(" {0}", element); } Console.WriteLine(" ]"); }

121

TempAgency Application Example

Figure 8-8 Problem specification for Manatee example

TempAgency Application Example (continued)

C# Programming: From Problem Analysis to Program Design

122

Table 8-3 Instance field members for the TempAgency class

C# Programming: From Problem Analysis to Program Design

123

TempAgency Application Example (continued)

Figure 8-9 Prototype

C# Programming: From Problem Analysis to Program Design

124

TempAgency Application Example (continued)

Figure 8-10 Class diagrams

125

TempAgency

Application Example

(continued)

TempAgency Application Example (continued)

C# Programming: From Problem Analysis to Program Design

126

Figure 8-12 TempAgency application output

Coding Standards

C# Programming: From Problem Analysis to Program Design

127

C# Programming: From Problem Analysis to Program Design

128

C# Programming: From Problem Analysis to Program Design

129

Chapter Summary

Appendix A: Temp-Agency (our approach) pp.1

130

namespace ConsoleApplication1

{

//From Figure 8.8, Temp Agency Problem class TempAgencyDemo

{

public void Main(string[] args)

{

//SalesPerson sp1 = new SalesPerson("Maria Macarena", 1000.00); //testing

SalesPerson sp1 = CreateSalesPersonObject();

sp1.CalculateFutureSales();

Console.WriteLine(sp1.ShowPersonData());

}//Main

131

// Method: CreateSalesPersonObject()

// This method prompts the user to enter fullname and initial target amount,

// it returns a new SalesPerson object holding values collected from the user.

// Observe that intentionally this method has not been included in the

// SalesPerson class. Instead it is part of the 'static' test program.

private SalesPerson CreateSalesPersonObject()

{

Console.WriteLine("Temp Agency Demo - Enter Person Name");

string fullName = Console.ReadLine();

string[] names = fullName.Split(' ');

Console.WriteLine("Enter {0}'s target amount ", names[0]);

int targetAmount = int.Parse(Console.ReadLine());

Console.WriteLine("target amount for {0} is {1}", names[0], targetAmount);

return new SalesPerson(fullName, targetAmount);

}

}

}

Appendix A: Temp-Agency (our approach) pp.2

132

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication1 { class SalesPerson { string personName; double[] sales; const int MONTHS = 4; public SalesPerson(string nameValue, double firstTargetValue) { string[] nameParts = nameValue.Split(' '); personName = nameParts[1] + ", " + nameParts[0]; //last name, first sales = new double[MONTHS]; sales[0] = firstTargetValue; }

Appendix A: Temp-Agency (our approach) pp.3

133

public void CalculateFutureSales() {

double pct = 0.05; for (int i = 1; i < MONTHS; i++) { sales[i] = sales[i - 1] * (1 + pct); }

} public string ShowPersonData() {

string result = String.Format("{0:20s}", personName); ; for (int i = 0; i < MONTHS; i++) { string currencyValue = String.Format("{0,15:C}", sales[i] ); if (i == 0) result += " " + currencyValue; else result += ", " + currencyValue; } return result;

}

}//class }//namespace

Appendix A: Temp-Agency (our approach) pp.4

134

Appendix B: Find n-th largest in List<int>

private static int FindNthLargest(int n, List<int> list) { //check for impossible cases (e.g. find second largest in an array of only one element) if (list.Count < n) return -1; //create BitArray to remember what values have already been recognized BitArray bitArray = new BitArray(list.Count, false); int posLargest = 0; //find position of first candidate to be largest (we must make n passes over the list) for (int pass= 0; pass < n; pass++) { for (posLargest = 0; posLargest < list.Count; posLargest++) { if (!bitArray[posLargest]) break; } //begin your exploration for largest for (int i = 0; i < list.Count; i++) { if (!bitArray[i] && (list[i] > list[posLargest])) { posLargest = i; } } bitArray[posLargest] = true; } return posLargest; }

135

Appendix C: Luhn's Check Sum Algorithm 1 of 2

private static void LuhnCheckSumKey() { string key = "7992739871"; Console.WriteLine("\nOriginal Key: {0}\n", key); StringBuilder sb = new StringBuilder(key); int n = key.Length; for (int i = n-1; i >= 0; i-=2) { // double every other digit, begining with rightmost cell char c = sb[i]; // determine integer represented by character ('7' becomes 7) int numDigit = c - '0'; int twiceDigit = 2* numDigit; // if calculate value > 9 add the numbe's digits if (twiceDigit > 9) { twiceDigit = 1 + twiceDigit % 10; } // from numeric digit to character (7 becomes '7') // adjust the key's digit in corresponding position sb[i] = (char)('0' + twiceDigit); Console.WriteLine("Digit: {0, 3} Doubled: {1, 3} Adjusted: {2, 3}", c, 2 * numDigit, sb[i]); }

136

Appendix C: Luhn's Check Sum Algorithm 2 of 2

Console.WriteLine("\nAdjusted key: {0}", sb); //add digits of the transformed key int sum = 0; for (int i = 0; i < n; i++) { char c = sb[i]; int nc = c - '0'; sum += nc; } Console.WriteLine("Sum of all digits: {0}", sum); //subtract from 10 the last digit from sum int checksum = 10 - (sum % 10); // attach checksum digit to original key string protectedKey = key + (char)('0' + checksum); Console.WriteLine("Protected Lunh's Key: {0} Checksum: {1}", protectedKey, checksum); }