structured programming instructor: prof. k. t. tsang lecture 11: binary tree 1

Post on 04-Jan-2016

222 Views

Category:

Documents

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Structured Programming Instructor: Prof. K. T. Tsang

Lecture 11: Binary Tree

1

Binary tree• A structure similar to a

linked-list

• Each node links up to 2 nodes below it

struct bnode {

char data[20];

bnode *left;

bnode *right;

};

data

left right

data

left right

data

left right

node1

node2 node3

2

The tree structure• A node on the

binary tree may have no more than 2 nodes descend from it

• The node on top is called the “root node”

• The bottom nodes are “leaf nodes”

• A node on the binary tree may have no more than 2 nodes descend from it

• The node on top is called the “root node”

• The bottom nodes are “leaf nodes”

0

0 0 0

00

0 0 0 0 0 0 0 0

Root node

Leaf nodes3

Example - parents

struct bnode me, dad, mom;strcpy (me.data, “John”);strcpy (mom.data, “Mary”);strcpy (dad.data, “Lew”);me.left = &dad;me.right = &mom;mom.left = 0;mom.right = 0;dad.left = 0;dad.right =0;

“John”

left right

“Mary”

left right

“Lew”

left right

me

dad mom

0 00 0

4

Example - grandparents

struct bnode grandmom, grandpa, gdmom, gdpa;strcpy (grandmom.data, “Jane”);strcpy (grandpa.data, “Bill”);mom.left = &grandpa;mom.right = &grandmom;grandmom.left = 0;grandmom.right = 0;grandpa.left = 0;grandpa.right =0;

5

Recursive tree-printing

void print_tree (struct bnode *top) {

if (top == NULL) return; //nothing

print_tree (top->left) //print leftprintf ( “%s\n”, top->data); //print this

node

print_tree (top->right); //print right

}

6

Generate random number• int rand ( void );• Returns a pseudo-random integral number in the

range 0 to RAND_MAX, a constant defined in stdlib.h

• This number is generated by an algorithm that returns a sequence of apparently non-related numbers each time it is called. This algorithm uses a seed to generate the series, which should be initialized to some distinctive value using srand.

7

8

A typical way to generate pseudo-random numbers in a determined range using rand is to use the modulo of the returned value by the range span and add the initial value of the range:( value % 100 ) is in the range 0 to 99( value % 100 + 1 ) is in the range 1 to 100( value % 30 + 1985 ) is in the range 1985 to 2014

int num= (100*rand())/RAND_MAX;

In the following example, the random seed is initialized to a value representing the second in which the program is executed (time is defined in the header time.h). This way to initialize the seed is generally a good enough option for most random needs.

9

/* rand example: guess the number */#include <stdio.h>#include <stdlib.h>#include <time.h>int main (){ int iSecret, iGuess; /* initialize random seed: */ srand ( time(0) ); /* generate secret number: */ iSecret = rand() % 10 + 1;

do { printf ("Guess the number (1 to 10): "); scanf ("%d",&iGuess); if (iSecret<iGuess) puts ("The secret number is lower"); else if (iSecret>iGuess) puts ("The secret number is higher"); } while (iSecret!=iGuess);

puts ("Congratulations!"); return 0;}

Structured Programming Instructor: Prof. K. T. Tsang

Lecture 12: Miscellaneous:C Preprocessorand Debugging

10

The C Preprocessor• Part of the C compilation process that

analyzes some statements before analysis of the C program itself.

• Preprocessor statements begin with a “pound” sign, ‘#’.

• Some of these statements we have already learned:

#include <stdio.h>#define PI 3.14159#define YES 1#define NO 0

11

“#define” statement#define PI 3.141592654#define YES 1#define TWO_PI 2.0*PI

A defined name is not a variable. You cannot assign a value to it. You use it like a constant.

double area (double r) {return PI * r * r;

}double circum (double r) {

return TWO_PI * r ;} 12

More complicated “#define” - Macros

#define LEAP_YEAR(y) y%4 == 0 && y%100 != 0 || y%400 == 0

#define SQUARE(x) x * x

if (LEAP_YEAR(year)) { … … }//replace by: if (year%4 == 0 && year%100 != 0 || year%400 == 0) if (LEAP_YEAR(next_year)) { … … }

Y = SQUARE ( n1 ) ; //replace by: n1 * n1Y = SQUARE ( u+1) ; //replace by: (u+1)*(u+1)

13

“include” statement

#include <stdio.h> //system include

#include “metric.h” //file provide by you

main () {

float x;

printf (“enter distance in miles\n”);

scanf(“%f”, &x)

printf (“%f miles = %f km\n”, x, MILE_KM * x);

}

14

“metric.h”

#define INCH_PER_CM 0.394

#define CM_PER_INCH 1.0/ INCH_PER_CM

#define MILE_KM 5280.0*12.0* CM_PER_INCH / 100000.0

15

Debugging with “#define”#include <stdio.h>#define DEBUG //same as “#define DEBUG 1”main() {

int i, j, k, nread;nread = scanf (“%d %d %d”, &I, &j, &k);

#ifdef DEBUGprintf (“number of integers read=%i\n”, nread);printf (“i=%i j=%i k=%i\n”, i, j, k);

#endif……

}//scanf returns the number of values successfully read and

assigned. 16

Define preprocessor “name” in the compiler command line

Most compiler allows you to define a name to the preprocessor when the program is compiled by using a special option to the compiler command:

gcc –D DEBUG myProgram.cpp

17

Example: use “ifdef” to debug

Use pointer to write a function with the prototype:char* strConcat(char* s1, char* s2);

to concatenate(连接 ) 2 strings s1 & s2 together and return a pointer points to the resulting string. Use this function in a program to show that it works.

18

#include <stdio.h>#define DEBUG

char* strConcat(char *s1, char *s2){int i = 0, c=0;char *s, s3[99];while (*s1 != '\0') { //check the content is non-null *(s3+i) = *s1;#ifdef DEBUGprintf ("%c", *(s3+i));#endif s1++; i++; //pointer arithmetic to scan the array s1} //end first while loop

19

while (*s2 != '\0') { //check the content is non-null *(s3+i) = *s2;#ifdef DEBUGprintf ("%c", *(s3+i));#endif s2++; i++; //pointer arithmetic to scan the array s2} //end second while loops3[i] = '\0';s = s3; //set pointer to beginning of character array

#ifdef DEBUGprintf ("\n%s\ntotal number of characters : %d\n", s, i);#endif

return s;}

20

int main(){

char str1[99], str2[99], *s0, *s1, *s2; //declare pointers

printf ("Enter 2 strings:");scanf ("%s %s", str1, str2);

//points to the beginning of an character arrays1 = str1;s2 = str2;

//pointers in the arguments and returns0 = strConcat (s1, s2);printf ("After strConcat :%s\n", s0);

return 0;}

21

Summary

• Preprocessor statements begin with a “pound” sign, ‘#’.

• #define statement

• Macros – more complicated use of #define

• #include statement

• Conditional compilation with #ifdef…#endif

• Debugging with #ifdef

22

23

More on Algorithm:1. Write a C function that takes two positive integers as input, then compute and return their Greatest Common Divisor (GCD). This problem can be solved by Euclidean algorithm, an efficient method for computing the GCD and based on the fact that the greatest common divisor of two numbers does not change if the smaller number is subtracted from the larger number. For example, 4 is the GCD of 28 and 12; since 28 − 12 = 16, the GCD of 12 and 16 is also 4. Since the larger of the two numbers is reduced, repeating this process gives successively smaller numbers until one of them is zero.

24

2. Euler's totient function φ(n) of a positive integer n is defined as the number of positive integers less than n that are coprime (or relatively prime, i.e. having no common factor other than 1) to n. In particular φ(1) = 1 since 1 is coprime to itself (1 is the only natural number with this property, and 1 is counted as being relatively prime to all natural numbers). For example, φ(9) = 6 since the six numbers 1, 2, 4, 5, 7 and 8 are coprime to 9. There are eight coprimes of 24 that are less than 24 (1, 5, 7, 11, 13, 17, 19, 23), so φ(24)=8. For a prime number p, φ(p)=p-1, since all numbers less than p are relatively prime to p. Use the gcd function developed in the previous problem to implement a function phi(n) to compute and return the Euler's totient function φ(n) of an input positive integer n.

25

3. Write a C-program to find the relative frequency distribution of the English alphabets by reading a long input text file that contains an English article and count the number of occurrence of each alphabet (disregard whether it is lower or upper cases), then divide it by the total number of the alphabets. Your program should be able to read an input English text file and perform the statistical analysis. Print the result out to a file and the standard output. Check your answer by comparing it with the histogram shown below.

26

#include <stdio.h>void main(){

FILE *f1, *f2; char c; int i, fq[26], n1=0, nt=0; float freq[26];//initialize fq to 0

f1 = fopen (“input.txt”, “r”);f2 = fopen (“output.txt”, “w”);if (f1 == NULL) {printf (“input.txt cannot be opened”); exit(1); }if (f2 == NULL) {printf (“output.txt cannot be opened”); exit(1);}printf (“input.txt & output.txt opened successfully”);

while ((c=getc(f1)) != EOF) {putc(c, f2); printf( “%c”, c); nt++;

if(c==‘a’ || c==‘A’) fq[0]++; //…}

printf (“\n\nTotal characters read: %d\n\n”, nt); fprintf(f2, “\n\nTotal characters read: %d\n\n”, nt); for (i=0; i<26; i++) n1=n1+fq[i]; for (i=0; i<26; i++) freq[i]=float(fq[i])/float(n1); for (i=0; i<26; i++) fprintf(f2, “relative freq: %f\n”, freq[i]);

fclose (f1); fclose (f2);}

27

Caesar Cipher - mono-alphabetic cipher

• replace each letter of message by a letter a fixed distance away (e.g. use the 3rd letter on)

• reputedly used by Julius Caesar

• e.g.

L FDPH L VDZ L FRQTXHUHG

I CAME I SAW I CONQUERED

28

29

The mapping is ABCDEFGHIJKLMNOPQRSTUVWXYZDEFGHIJKLMNOPQRSTUVWXYZABC

30

4. Write a program that can encrypt and decrypt using the general Caesar cipher, also known as an additive cipher.

5. In cryptography, the Cæsar Cipher can be broken by statistical frequency analysis. By knowing the expected distribution of the letters in the original language of the plaintext, we can easily spot the value of the shift by looking at the displacement of particular features of the graph. This is known as frequency analysis. For example in the English language the plaintext frequencies of the letters E, T, (usually most frequent), and Q, Z (typically least frequent) are particularly distinctive. The histogram shown previously exhibits the expected relative frequency distribution of the English alphabets.

31

The simplest numerical integration of a one-dimensional function, f(x), in the range, [a, b], samples function values at regular intervals, f(xn = a + (n - 1/2) Δx) (n = 1, ..., M; Δx = (b − a)/M)

The Monte Carlo method instead generates a sequence of random numbers, rn, in the range, [a, b], and approximates the integral as (the only difference being random instead of regular points)

32

33

Random-number generator in the standard library: The Unix standard library includes a random-number generator, int rand(). Note the header file, #include <stdlib.h>. Successive calls to this routine generate a sequence of random numbers in the range, [0, 231 − 1 = 2,147,483,647].

34

35

36

RAND_MAX is the maximum random number, 2 31 − 1 = 2,147,483,647, defined in /usr/include/stdlib.h. The expression, rand()/(float)RAND_MAX, generates a random number in the range, [0,1].

void srand( (unsigned) time((int *)0) );To initialize the sequence of random numbers, use void srand(unsigned seed), where seed is a random starting point of a sequence. In the above, the seed depends on the time the program is run. The int time(int *tloc) system call returns the time since 00:00:00 GMT, January 1, 1970, measured in seconds. If tloc is nonzero, the return value is also stored in the place to which tloc points.

top related