Advanced Collections - csuohio.edugrail.cba.csuohio.edu/~matos/notes/ist-211/csNotes/...Advanced...
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
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
7
Two-Dimensional Arrays (continued)
type [ , ] identifier = new type [integral value, integral value];
int [ , ] calories = new int[7, 3];
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)
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
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
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()); }
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
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
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 ");
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
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>
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);
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 – 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 (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 –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>
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 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
//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> - 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(" ]"); }
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
TempAgency Application Example (continued)
C# Programming: From Problem Analysis to Program Design
126
Figure 8-12 TempAgency application output
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); }