0% found this document useful (0 votes)
3 views

Array

The document provides an extensive overview of C arrays, including single and multidimensional arrays, their creation, manipulation, and various applications such as sorting and random generation. It covers essential concepts like setting array sizes, copying arrays, and counting unique words from a file. Additionally, it includes code examples demonstrating these concepts in practice.

Uploaded by

Lê Hồng Minh
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views

Array

The document provides an extensive overview of C arrays, including single and multidimensional arrays, their creation, manipulation, and various applications such as sorting and random generation. It covers essential concepts like setting array sizes, copying arrays, and counting unique words from a file. Additionally, it includes code examples demonstrating these concepts in practice.

Uploaded by

Lê Hồng Minh
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 30

C Array

(C programming)

2024
Contents
C Arrays............................................................................................................................... 2
Arrays........................................................................................................................................................ 2
Sort............................................................................................................................................................ 3

Set Array Size....................................................................................................................... 4

C Array Size.......................................................................................................................... 4

Making Better Loops............................................................................................................. 5

Random Seting..................................................................................................................... 5

Array Copy........................................................................................................................... 7

Array Clone.......................................................................................................................... 7

Words.................................................................................................................................. 7

C Multidimensional Arrays..................................................................................................... 9

Change Elements in a 2D Array............................................................................................ 10

Loop Through a 2D Array..................................................................................................... 10

Array Applications.............................................................................................................. 10
Magic Squares.......................................................................................................................................... 10
Odd Magic Square (OMS)......................................................................................................................... 11
Even Magic Square (EMS)........................................................................................................................ 11
Rectangle Cypher.................................................................................................................................... 15
Stack........................................................................................................................................................ 17
Brackets................................................................................................................................................... 17
Postfix Syntax.......................................................................................................................................... 20
Tính trị của biểu thưc hậu tố.................................................................................................................... 20
Chuyển đổi biểu thức chính quy sang dạng Poland Postfix......................................................................22
Josephus Problem..................................................................................................................................... 26
Josephus Cypher...................................................................................................................................... 28

https://www.programiz.com/c-programming/online-compiler/
https://sourceforge.net/projects/orwelldevcpp/

C Arrays

Arrays
/* Arrays */
#include <stdio.h>
#include <stdlib.h>

#define Odd(e) (e) % 2 == 1


#define Even(e) !(Odd(e))

void Go() {
printf(" ? ");
char c = getchar();
if (c == 10) return; // ENTER
if (c == '.') exit(0);
}

void Swap(int a[], int i, int j) {


int tmp = a[i]; a[i] = a[j]; a[j] = tmp;
}

void Print(const char *msg, int a[], int d, int c) {


printf("%s", msg);
int i;
for (i = d; i <= c; ++i) printf(" %d ", a[i]);
}

void Rev(int a[], int d, int c) { // Lat


int i;
while(d < c) {
// Swap(a, d, c);
Swap(a, d++, c--);
//++d; --c;
}
}

void Test() {
int a[] = {25, 50, 75, 100};
int n = sizeof(a)/sizeof(int);
Print("\n Init a: ", a, 0, n-1);
printf("\n len a = %d", n);
printf("\n %d ", a[0]);
a[3] = 102;
Print("\n Update a: ", a, 0, n-1);
int i;
for(i = 0; i < n; ++i)
if (Odd(a[i])) ++a[i];
else --a[i];
Print("\n ++odd, --even a: ", a, 0, n-1);
Rev(a, 0, n-1);
Print("\n Rev a: ", a, 0, n-1);
}

int main() {
Test();
printf("\n T h e E n d");
return 0;
}

Sort
/* qsort */

#include <stdio.h>
#include <stdlib.h>

void Go() {
printf(" ? ");
char c = getchar();
if (c == 10) return; // ENTER
if (c == '.') exit(0);
}
void Print(char *msg, int a[], int d, int c) {
printf("%s",msg);
int i;
for (i = d; i <= c; ++i) printf("%d ",a[i]);
}

int Cmp(int *x, int *y) {


return *x - *y;
}

int CharCmp(char *x, char *y) {


return *x - *y;
}

main() {
int a[] = { 3, 3, 40, 10, 10, -1, 100, 90, 20, 25};
int n = sizeof(a)/sizeof(int);
Print("\n Init a: ", a, 0, n-1);
qsort(a, n, sizeof(int), Cmp);
Print("\n Sorted a: ", a, 0, n-1);
char s[] = "cxdmynba";
int len = strlen(s);
printf("\n Input s: %s", s);
qsort(s, len, sizeof(char), CharCmp);
printf("\n Sorted s: %s", s);
printf("\n T h e E n d");
return 0;
}

Set Array Size


Another common way to create arrays, is to specify the size of the array, and add elements later:
Example
// Declare an array of four integers:
int myNumbers[4];

// Add elements
myNumbers[0] = 25;
myNumbers[1] = 50;
myNumbers[2] = 75;
myNumbers[3] = 100;

Using this method, you should know the number of array elements in advance, in order for the program to
store enough memory.
You are not able to change the size of the array after creation.

C Array Size
sizeof(type); // bytes
Get Array Size or Length
To get the size of an array, you can use the sizeof operator:
Example
int myNumbers[] = {10, 25, 50, 75, 100};
printf("%lu", sizeof(myNumbers)); // Prints 20
Why did the result show 20 instead of 5, when the array contains 5 elements?
- It is because the sizeof operator returns the size of a type in bytes.
You learned from the Data Types chapter that an int type is usually 4 bytes, so from the example above, 4 x 5 (4
bytes x 5 elements) = 20 bytes.
Knowing the memory size of an array is great when you are working with larger programs that require good
memory management.
But when you just want to find out how many elements an array has, you can use the following formula (which
divides the size of the array by the size of one array element):
Example
int myNumbers[] = {10, 25, 50, 75, 100};
int length = sizeof(myNumbers) / sizeof(myNumbers[0]);

printf("%d", length); // Prints 5

Making Better Loops


In the array loops section in the previous chapter, we wrote the size of the array in the loop condition (i < 4).
This is not ideal, since it will only work for arrays of a specified size.
However, by using the sizeof formula from the example above, we can now make loops that work for arrays of
any size, which is more sustainable.
Instead of writing:
Example
int myNumbers[] = {25, 50, 75, 100};
int i;

for (i = 0; i < 4; i++) {


printf("%d\n", myNumbers[i]);
}

It is better to write:
Example
int myNumbers[] = {25, 50, 75, 100};
int length = sizeof(myNumbers) / sizeof(myNumbers[0]);
int i;
for (i = 0; i < length; i++) {
printf("%d\n", myNumbers[i]);
}

Random Seting
/*
Name: Random
Copyright: (C) 2024
Author: C Fan
Date: 21-08-24 16:14
Description:
Sinh tu dong int a
Sort
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void Go() {
printf(" ? ");
char c;
scanf("%c", &c);
if (c == 10) return; // ENTER
if (c == '.') exit(0);
}

void Print(char *msg, int a[], int d, int c) {


printf("%s", msg);
int i;
for (i = d; i <= c; ++i)
printf(" %d", a[i]);
}

// sinh so ngau nhien trong khoang d..c


int RandRange(int d, int c) {
int m = c+1-d;
return d+(rand() % m);
}

void SetValue(int a[], int n, int d, int c) {


int i;
for(i = 0; i < n; ++i)
a[i] = RandRange(d, c);
}

int H(int x) {
return (x < 10) ? x : (x % 10) + H(x / 10);
}

int Cmp(int *x, int *y) {


return H(*x)-H(*y);
}

// Tao array int a, gan tri random


int * Gen(int n, int d, int c) {
int *a = malloc(n*sizeof(int));
SetValue(a, n, d, c);
return a;
}

void Test1() {
printf("\n Test No 1");
int n = 20;
int a[n];
SetValue(a, n, 1, 100);
Print("\n Random Init a: ", a, 0, n-1);
qsort(a, n, sizeof(int), Cmp);
Print("\n Sorted a: ", a, 0, n-1);
}

void Test2() {
printf("\n Test No 2");
int n = 20;
int * a = Gen(n, 0, 500);
Print("\n Init a: ", a, 0, n-1);
qsort(a, n, sizeof(int), Cmp);
Print("\n Sorted a: ", a, 0, n-1);
}

main() {
srand(time(NULL));
Test1();
Test2();
printf("\n T h e E n d");
return 0;
}

Array Copy
#include <string.h>
memcpy(b,a,n*sizeof(int));

Array Clone
#include <string.h>

int * Clone(int a[], int n) {


int *c = malloc(n*sizeof(int));
memcpy(c,a,n*sizeof(int));
return c;
}

Words
File WORDS.INP chứa không quá 1000 từ tiếng Anh viết HOA cách nhau và kết thúc bằng dấu chấm (.). Hãy cho biết có
bao nhiêu từ khác nhau và mỗi từ xuát hiện bao nhiêu lần.
Output file WORDS.OUT :
Dòng đầu tiên: sô lượng từ
Từ dòng thứ hai trở đi: mỗi dòng hai giá trị w m
w là từ có trong input file, m là số lần xuất hiện của từ w trong input file.

WORDS.INP WORDS.OU
T
AND BEGIN END AND END 7
WHILE REPEAT BEGIN DO AND 8
FOR AND BEGIN END AND BEGIN 7
END DO 3
WHILE REPEAT BEGIN DO END 8
AND BEGIN END AND END FOR 2
FOR AND BEGIN END AND REPEAT 3
END WHILE 3
WHILE REPEAT BEGIN DO
.

Algorithm
Bài này có thể giải bằng hai cách
Cách thứ nhất: Dùng vector
 Đọc lần lượt các từ w trong input file, nạp vào vector<string> v. O(n), n là số lượng từ.
 Sắp tăng v . O(knlog(n)), k là chiều dài max của từ
 Đếm số lượng các từ khác nhau trong v. O(n)
 Ghi kết quả vào output file. O(n)
Program
/*
Name: Words
Copyright: (C) 2024
Author: C Fan
Date: 21-08-24 16:14
Description:
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FN "WORDS.INP"
#define GN "WORDS.OUT"
#define BL 32
#define ENDSTR '\0'
#define Equal(x,y) strcmp(x,y)==0
#define SLEN 50
#define MN 1001

typedef char Str[SLEN];


Str ss[MN];

void Go() {
printf(" ? ");
char c;
scanf("%c", &c);
if (c == 10) return; // ENTER
if (c == '.') exit(0);
}

int Cmp(int *i, int *j) {


return strcmp(ss[*i],ss[*j]);
}

void Words() {
FILE * f = fopen(FN, "r");
if (f == NULL) {
printf("unable open input file %s ", FN);
exit(1);
}

int n = 0;
while(1) {
fscanf(f, "%s", ss[n]);
printf(" |%s| ", ss[n]);
if (Equal(ss[n],".")) break;
++n;
}
fclose(f);
printf("\n n = %d ", n);
int i;
printf("\n Input ss ");
for (i = 0; i < n;++i)
printf("\n %s ", ss[i]);
int id[n];
for(i = 0; i < n; ++i) id[i] = i;
qsort(id, n, sizeof(int), Cmp);
printf("\n Sorted ss ");
for (i = 0; i < n;++i)
printf("\n %s ", ss[id[i]]);
// dem so tu khac nhau
int c = 1; // count
int j = 0;
for (i = 1; i < n; ++i) {
if (strcmp(ss[id[i]], ss[id[j]]) != 0) {
++c;
j = i;
}
}
printf("\n so tu khac nhau: %d \n", c);
// write to file GN
FILE * g = fopen(GN, "w");
if (g == NULL) {
printf("unable open out file %s ", GN);
exit(1);
}
fprintf(g, "%d\n",c);
j = 0;
c = 1;
for (i = 1; i < n; ++i) {
if (strcmp(ss[id[i]], ss[id[j]]) != 0) {
fprintf(g, "%s %d\n",ss[id[j]], c);
printf("%s %d\n",ss[id[j]], c);
j = i; c = 1;
}
else ++c;
}
fprintf(g, "%s %d\n",ss[id[j]], c);
printf("%s %d\n",ss[id[j]], c);
fclose(g);
}

main() {
Words();
printf("\n T h e E n d");
return 0;
}

C Multidimensional Arrays

Multidimensional Arrays
In the previous chapter, you learned about arrays, which is also known as single dimension arrays. These are
great, and something you will use a lot while programming in C. However, if you want to store data as a tabular
form, like a table with rows and columns, you need to get familiar with multidimensional arrays.
A multidimensional array is basically an array of arrays.
Arrays can have any number of dimensions. In this chapter, we will introduce the most common; two-
dimensional arrays (2D).

Two-Dimensional Arrays
A 2D array is also known as a matrix (a table of rows and columns).
To create a 2D array of integers, take a look at the following example:
int matrix[2][3] = { {1, 4, 2}, {3, 6, 8} };

The first dimension represents the number of rows [2], while the second dimension represents the number of
columns [3]. The values are placed in row-order, and can be visualized like this:
Access the Elements of a 2D Array
To access an element of a two-dimensional array, you must specify the index number of both the row and
column.
This statement accesses the value of the element in the first row (0) and third column (2) of the matrix array.
Example
int matrix[2][3] = { {1, 4, 2}, {3, 6, 8} };
printf("%d", matrix[0][2]); // Outputs 2

Remember that: Array indexes start with 0: [0] is the first element. [1] is the second element, etc.

Change Elements in a 2D Array


To change the value of an element, refer to the index number of the element in each of the dimensions:
The following example will change the value of the element in the first row (0) and first column (0):
Example
int matrix[2][3] = { {1, 4, 2}, {3, 6, 8} };
matrix[0][0] = 9;

printf("%d", matrix[0][0]); // Now outputs 9 instead of 1

Loop Through a 2D Array


To loop through a multi-dimensional array, you need one loop for each of the array's dimensions.
The following example outputs all elements in the matrix array:
Example
int matrix[2][3] = { {1, 4, 2}, {3, 6, 8} };

int i, j;
for (i = 0; i < 2; i++) {
for (j = 0; j < 3; j++) {
printf("%d\n", matrix[i][j]);
}
}

Array Applications
Magic Squares
Square nxn number 1..n2 all sums (row, colums, diagonals) are equals = Charcteristic Number
(dac so)
MS3 MS5 MS4 MS6
8 1 6 1 C = (1+..+n2)/n
3 5 7 = (n2+1)*n2 / (2n)
4 9 2 4 = (n2+1)*n / 2

3 C2 = 15, C4 = 35

2 C5 = 65, C6 = 111

Algorithm OMS (Odd Magic


Squere)
1. set all 0 to a
2. write 1 at (0, n/2)
3. for k = 2..n2:
3.1 Find cell a(i,j)
3.2 set a(i,j) = k
Go to direction North-East
(NE)

Odd Magic Square (OMS)


Even Magic Square (EMS)

1 2 3 4 5 6 tạo xâu mẫu s n = 6, n2 = 6/2 =


3 = len
7 8 9 1 1 1 len = n2 = n/2
0 1 2 k = n2/2 = 3/2 = 1
k = n2/2 kí tự T
1 1 1 1 1 1 s = TDN
nếu n2 lẻ thêm
3 4 5 6 7 8
DN
1 2 2 2 2 2 Têm # cho đủ len
9 0 1 2 3 4 = n2
2 2 2 2 2 3
5 6 7 8 9 0

3 3 3 3 3 3
1 2 3 4 5 6

3 5 3 4 2 3 TD
6 3 1 N

2 8 9 1 1 1 NT
5 0 1 2 D

1 1 1 1 1 1 DN
3 4 5 6 7 8 T

1 2 2 2 2 2
9 0 1 2 3 4

7 2 2 2 2 3
6 7 8 9 0

6 3 3 3 3 1
2 4 5
Program
/*
Name: Magic Square
Copyright: (C) 2024
Author: C Fan
Date: 21-08-24 16:14
Description:
Odd Magic Squares
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MN 50

int a[MN][MN];

void Go() {
printf(" ? ");
char c;
scanf("%c", &c);
if (c == 10) return; // ENTER
if (c == '.') exit(0);
}

void Print(int n) {
int i, j;
for (i = 0; i < n; ++i) {
printf("\n ");
for (j = 0; j < n; ++j)
printf(" %d", a[i][j]);
}
}

int Verify(int n) {
// dac so
int s = (1+n*n)*n/2;
printf("\n Characteristic Number = %d", s);
int i, j, er = 0;
int d, c, c1 = 0, c2 = 0;
for (i = 0; i < n; ++i) {
c1 += a[i][i]; c2 += a[i][n-1-i];
d = 0; c = 0;
for (j = 0; j < n; ++j) {
d += a[i][j]; c += a[j][i];
}
if (d != s) {
printf("\n Error in row %d", i);
++er;
}
if (d != s) {
printf("\n Error in column %d", j);
++er;
}
}
if (c1 != s) {
printf("\n Error in diagona l");
++er;
}
if (c2 != s) {
printf("\n Error in diagona 2");
++er;
}
if (er == 0) printf("\n Correct");
else printf("\n Total errors: %d", er);
}

void OddMS(int n) {
// Init
memset(a, 0, sizeof(a));
// Print(n);
int i = 0, j = n/2, k;
a[i][j] = 1;
int nn = n*n;
for(k = 2; k <= nn; ++k) {
// tim vi tri (i,j) dat k
// Theo huong Dong Bac
--i; ++j;
if (i < 0) {
if (j == n) { i += 2; --j; }
else i = n-1;
}
else {
if (j == n) j = 0;
}
if (a[i][j] > 0) { i += 2; --j; }
a[i][j] = k;
}
Print(n);
Verify(n);
}

int Num(int n, int i, int j) {


return i*n + j + 1;
}

// vertical symmety
void V(int n, int i, int j) {
// a[i][j] | a[i][n-1-j]
int jj = n-1-j;
a[i][j] = Num(n, i, jj);
a[i][jj] = Num(n, i,j);
}

// horizontal symmety
void H(int n, int i, int j) {
// a[i][j]
//--------
// a[n-1-i][j]
int ii = n-1-i;
a[i][j] = Num(n, ii, j);
a[ii][j] = Num(n, i, j);
}

// Central symmety
void C(int n, int i, int j) {
int ii = n-1-i, jj = n-1-j;
a[i][j] = Num(n, ii, jj);
a[ii][jj] = Num(n, i, j);
a[ii][j] = Num(n,i, jj);
a[i][jj] = Num(n,ii,j);
}

void EvenMS(int n) {
// Init
int nn = n*n;
int i, j, k = 1;
for(i = 0; i < n; ++i) {
for(j = 0; j < n; ++j)
a[i][j] = k++;
}
// Print(n);
int n2 = n/2;
int n4 = n/4;
char s[n2]; // xau mau
int c;
char ch;
for(i = 0; i < n4; ++i) s[i] = 'C'; // Center
c = n4;
if (n2 % 2 == 1) { s[c] = 'V'; ++c; s[c] = 'H'; ++c; }
for(i = c; i < n2; ++i) s[i] = 'B';
s[i] = '\0';
// printf("\n Init Xau mau: %s", s);
for(i = 0; i < n2; ++i) {
for(j = 0; j < n2; ++j) {
switch(s[j]) {
case 'V': // doi xung doc
V(n, i,j);
break;
case 'H': // doi xung ngay
H(n, i,j);
break;
case 'C': // Doi xung tam
C(n, i,j);
break;

} // switch
} // j
// quay xau mau 1234 4123
ch = s[n2-1];
for(k = n2-1; k > 0; --k) s[k] = s[k-1];
s[0] = ch;
// printf("\n Rotate Xau mau: %s", s);
} // i
Print(n);
Verify(n);
}

void MS(int n) {
printf("\n Magic Square of %d" , n);
if (n >= MN) {
printf("\n Big size %d", n);
return;
}
if (n == 1) {
printf("\n 1");
return;
}

if (n == 2) {
printf("\n No solutions");
return;
}
if (n % 2 == 1) OddMS(n);
else EvenMS(n);
}

main() {
int n;
for(n = 1; n < 10; ++n) {
MS(n); Go();
}
printf("\n T h e E n d");
return 0;
}

Rectangle Cypher
Mã chữ nhật với khóa k biến đổi string s thènh string w qua 2 bước sau:
Step 1: Xếp lần lượt các chữ cái của s vào ma trận có chiểu dài k
Step 2: Lấy lần lượt các chữ cái theo cột ghép vào w
Ví dụ
s = “Con*co*bay*la*bay*la.“, k = 5
Con*c
o*bay
*la*b
ay*la
.
w = “Co*a.o*lynba**a*lcyba“
Viết hàm mã w = Enode(s,k,w) và giải mã Decode(w,k,s).
Quy trình xuôi ngược

/*
Name: Rectangle Cypher
Copyright: (C) 2024
Author: DevC Fan
Date: 06-10-24 13:56
Description:
*/

#include <stdio.h>
#define MN 500
#define ENDSTR '\0'

void Go() {
printf(" ? ");
int c = getchar();
if (c == 10) return; // ENTER
if (c == '.') exit(0);
}

void Encode(char s[], int k, char w[]) {


int n = 0; // counter for w
int lens = strlen(s);
int i, j;
for(i = 0; i < k; ++i)
for (j = i; j < lens; j += k)
w[n++] = s[j];
w[n] = ENDSTR;
}

void Decode(char w[], int k, char s[]) {


int i, j;
int lenw = strlen(w);
int n = 0; // counter for s
for(i = 0; i < k; ++i)
for (j = i; j < lenw; j += k)
s[j] = w[n++];
s[n] = ENDSTR;
}

// ed = 1: encode, ed = 0: deode
void Code(char s[], int k, char w[], int ed) {
int n = 0; // counter for w
int lens = strlen(s);
int i, j;
for(i = 0; i < k; ++i)
for (j = i; j < lens; j += k)
if (ed) w[n++] = s[j]; // encode
else w[j] = s[n++]; // decode
w[n] = ENDSTR;
}

main() {
char x[] = "Con*co*bay*la*bay*la\nBay*tu*cua*phu*bay*ra*canh*dong...\n(dan ca)";
// char x[] = "Posts and Telecommunications Institute of Technology";
printf("\n Input %s", x);
int k = 5;
char w[MN];
char s[MN];
Code(x, k, w, 1);
printf("\n w = %s", w);
Code(w,k,s,0);
printf("\n s = %s", s);
printf("\n T h e E n d");
return 0;
}

Output

Input Con*co*bay*la*bay*la
Bay*tu*cua*phu*bay*ra*canh*dong...
(dan ca)
w = Co*a
ta*rnn
o*lyBu*bahg(cnba*a*pa**.da*a*lychycd.a)cyba*uu*ao.n
s = Con*co*bay*la*bay*la
Bay*tu*cua*phu*bay*ra*canh*dong...
(dan ca)
T h e E n d
--------------------------------
Process exited after 0.06146 seconds with return value 0
Press any key to continue . . .
Stack

stack = stream with only ome


input/output port

stack 1 2 3 4 5 in push / out


s pop

queue out in


q 

Ngăn xếp (stack) là kiểu dữ liệu được tổ chức theo nguyên tắc vào sau – ra trước (LIFO: Last In First out): phần tử được
nạp vào sau thì sẽ được lấy ra trước. Khi ta tổ chức các hoạt động sau đây sẽ thường tuân thủ theo nguyên tắc của ngăn
xếp:

Tháo các chi tiết của một sản phẩm để sửa chữa, sau đó lại lắp các chi tiết vào sản phẩm

Xếp nguyên liệu vào các thùng đựng dạng đường ống với một đầu vào, sau đó lấy ra để sử dụng
Có thể mường tượng ngăn xếp như một đường ống st chỉ có một cửa đảm nhận chức năng vào/ra. Khi nạp một đói tượng
x vào st, st sẽ được tăng thêm một ngăn (trên cùng) để chứa x, khi cần lấy khỏi st một phần tử thì st sẽ xuất ra phần tử trên
cùng và do đó, số lượng sẽ được giảm đi 1.


Các thao tác cơ bản trên stack
Trong C ngăn xếp được cài đặt qua kiểu dữ liệu mảng như sau (ví dụ int):
 Khởi tạo stack rỗng: int st[len], p = -1; // con trỏ ngọn st
 Nạp đối tượng x vào stack: st[++p] = x: đối tượng x sẽ được nạp vào ngọn stack,
dung lượng của stack sẽ được tăng thêm 1 đơn vị.
 Xem ngọn stack: st[p]
 Lấy đối tượng trên ngọn stack ra khỏi stact: x = st[p--]; dung lượng của stack
sẽ được giảm bớt 1 đơn vị.
 Kiểm tra stck rỗng? p < 0
 Hiển thị nội dung stack: print(st)

Brackets
Một biểu thức toán học có thể chứa các cặp ngoặc thuộc ba dạng sau ( ), [ ] hoặc { }.
Hãy kiểm tra tinh hợp lệ của các biểu thức có chứa các cặp ngoặc?
Ví dụ

BRACKETS.IN OUTPUT
P
a*(b+c*d) Correct
a*(b+c*d)) Syntax Error:
a*([b+c]*d) Unmatched )
{a*[b+c]-d} Correct
{a*{[b+c]*d Correct
)) Syntax Error:
{a*{(b+c]*d Unmatched )
}} Syntax Error:
{a*{(b+c)*d Unmatched ]
}} Correct

Understanding
Ta cần hiểu thế nào là một cặp ngoặc được bố trí hợp lệ?
Đời thường có thể hiểu mỗi cặp ngoặc gồm có nồi (dấu mở ngoặc) và vung (dáu đóng ngoặc tương ứng). Như vậy, các
cặp ngoặc cùng loại có thể chứa nhau giống như một dãy nồi-vung có thể đặt lồng nhau.
Algorithm
Ta thể hiện dãy nồi-vung dưới dạng một stack st. Gặp dấu mở ngoặc (nồi) ta nạp vào st để chờ sau này
sẽ gặp vung tương ứng. Gặp dấu đóng ngoặc (vung) ta xét ngọn st có chứa nồi cùng loại hay không.
Nếu có thì ta lấy nồi đó ra để thu được một cặp nồi-vung cùng loại. Dễ thấy hai tình huống không hợp
lệ khi gặp vung (đóng ngoặc) sau đây:
 st rỗng: có vung mà không có nồi cùng loại trong st
 ngăn trên của st không chứa nồi cùng loại.
Bạn nên thêm một phần tử đệm, ví dụ SHAP = '#', vào đáy stack để tiện kiểm tra stack.
Trước khi kêt thúc chương trình, bạn kiểm tra lại stack. Nếu st còn chứa các phần tử khác SHAP tức là còn có những dấu
mở ngoặc chưa gặp các dấu đóng ngoặc tương ứng.
Program

/*
Name: Brackets
Copyright: (C) 2024
Author: DevC Fan
Date: 06-10-24 13:56
Description:
*/

#include <stdio.h>
//#include <string.h>
#define MN 100
#define SHAP '#'
#define BL 32
#define FN "BRACKETS.INP"

void Go() {
printf(" ? ");
int c = getchar();
if (c == 10) return; // ENTER
if (c == '.') exit(0);
}

// c is open symbol ?
int IsOpen(char c) {
return c == '(' || c == '[' || c == '{';
}

// c is close symbol ?
int IsClose(char c) {
return c == ')' || c == ']' || c == '}';
}

// return open symbol


char GetOpen(char c) {
switch(c) {
case ')': return '(';
case ']': return '[';
case '}': return '{';
}
}

void Test(char s[]) {


printf("\n\n %s", s);
int n = strlen(s);
char st[n];
int p = -1;
st[++p] = SHAP; // guard
int i;
char c;
for(i = 0; i < n; ++i) {
c = s[i]; // xet tung symbol c
// neu c is open: nap st
if (IsOpen(c)) { st[++p] = c; continue; }
// neu c is close timopen tuong ung
if (IsClose(c)) {
if (st[p] == GetOpen(c)) --p;
else {
printf("*** Syntax Error: Unmatched %c", c);
return;
} // else
continue;
} // if close
} // for
if (st[p] == SHAP) {
printf(" Correct");
return;
} // shapap
printf("*** Syntax Error: Unmatched %c", st[p--]);
}

void Run() {
FILE *f = fopen(FN, "r");
if (f == NULL) {
printf("\n unable open input file %s", FN);
exit(1);
}
char s[MN], w[MN];
int j, i;
while (fgets(s, MN, f)) {
// bo cac BL
j = 0;
for(i = 0; s[i]; ++i)
if (s[i] != BL) w[j++] = s[i];
if (j > 0) Test(w);
}
fclose(f);
}

main() {
Run();
printf("\n T h e E n d");
return 0;
}
Output
a*(b+c*d)
Correct

a*(b+c*d))
***Syntax Error: Unmatched )

a*([b+c]*d)
Correct

{a*[b+c]-d}
Correct

{a*{[b+c]*d))
***Syntax Error: Unmatched )

{a*{(b+c]*d}}
***Syntax Error: Unmatched ]

{a*{(b+c)*d}}
Correct

T h e E n d

Postfix Syntax
Năm 1924, nhà toán học Poland Lukasiewicz đề xuất phương pháp ghi các biểu thức toán
học dưới dạng dấu phép toán được đặt sau các toán hạng, ví dụ, thay vì viết c(d+h) thì ta
viết c d h + 
Ký pháp này có đặc điểm là không phải dùng đến các dấu ngoặc để chỉ rõ thứ tự thực hiện
các phép tính trung gian. Sau khoảng gần nửa thế kỷ, khi máy tính điện tử ra đời (năm
1949), các nhà tin học phát hiện ra rằng nếu chuyển các biểu thức toán học sang dạng hậu
tố thì rất tiện lợi cho việc thực hiện tính toán kết quả trên một ngăn xếp. Có lẽ, vì thế mà
mọi người thường gọi ký pháp hậu tố là ký pháp Ba Lan nhằm tôn vinh quê hương ông.

Tính trị của biểu thưc hậu tố


Gia sử ta có một biểu thức hậu tố dưới dạng string
pol = "c d h + * "
Đây là dạng Poland của biểu thức chính quy c * (d + h). Ta sẽ triến khai hàm Exe(pol) tính toán trị của biểu thức pol với
các quy ước sau đây:
Mỗi biến trong pol có tên là một chữ cái viết thường trong bảng chữ cái tiếng Anh, a, b, c, ... và được nhận giá trị mặc
định theo thứ tự a = 0, b = 1, ...
Hàm Exe khi đó sẽ được thực hiện trên một ngăn xếp st kiểu nguyên như sau:
Exe(pol):
Khởi tạo ngăn xếp rỗng st
for each symbol c in pol do
if c là biến then nạp trị của c vào st
else if c là phép toán @ then
thực hiện phép toán @ trên các toán hạng nằm trên ngọn của st,
đồng thời lấy các toán hạng ra khỏi ngọn st,
ghi kết quả trung gian vào ngọn của st
end if
return kết quả là giá trị trên ngọn của st
Ta minh hoạ quá trình tính trị của dạng hậu tố Poland pol = 'c d h + *' như sau:
Exe('c d h + *') = ?
Khởi trị st = []
'c nạp Val('c') = 2 vào st: st = [2]
'
'd nạp Val('d') = 3 vào st: st = [2, 3]
'
'h nạp Val('h') = 7 vào st: st = [2, 3,
' 7]
'+ thực hiện st[-2] += st[- st = [2, 10]
' 1]:
'* thực hiện st[-2] *= st[- st = [20]
' 1]:
return 20
Program

/*
Name: Postfix expression
Copyright: (C) 2024
Author: DevC Fan
Date: 06-10-24 13:56
Description:
Value of postfix expression
*/

#include <stdio.h>
#define SHAP '#'
#define BL 32
#define FN "BRACKETS.INP"
#define Var(c) (c) >= 'a' && c <= 'z'
#define Val(c) (c) - 'a'

void Go() {
printf(" ? ");
int c = getchar();
if (c == 10) return; // ENTER
if (c == '.') exit(0);
}

int Exe(char pol[]) {


printf("\n %s", pol);
int n = strlen(pol);
int st[n];
int p = -1;
char c;
int i;
for(i = 0; i < n; ++i) {
c = pol[i];
if (Var(c)) { st[++p] = Val(c); continue; }
switch(c) {
case '+': st[p-1] += st[p]; --p; break;
case '-': st[p-1] -= st[p]; --p; break;
case '*': st[p-1] *= st[p]; --p; break;
case '/': if (st[p] == 0) {
printf(" Run eror: divide by zero %d", st[p]);
return -1;
}
st[p-1] /= st[p]; --p; break;
case '%': if (st[p] == 0) {
printf(" Run eror: divide by zero %d", st[p]);
return -1;
}
st[p-1] %= st[p]; --p; break;
} // switch
} // for
return st[p];
}

main() {
// a bcdef ghijk lmnop qrstu vwxyz
// c*(d+h) -> cdh+* = 2*(3+7) = 2*10 = 20
int r = Exe("c d h + *");
printf("\n Result: %d", r);
printf("\n T h e E n d");
return 0;
}
Output
Input Postfix expression: c d h + *
Result: 20
T h e E n d
Testing
Bạn hãy mở rộng chương trình trên để có thể thực hiện các phép toán sau đây:
 Các phép toán 2 ngôi +, -, *, /, %
 Các phép toán 1 ngôi:
 ~x đảo dấu của x: cho ra giá trị -x
 x> tăng x thêm 1: cho ra giá trị x+1
 x< giảm x bớt 1: cho ra giá trị x-1
 x! tính giai thừa x! = 1*2*…*n
Hãy chuyển đổi các biểu thức sau đây sang dạng Poland và test chương trình để kiểm tra kết quả:
c+d*k
d*d - c*d*h + h*h
c-d>!+k*d
(k-c*d)-(c+(d+b*e))
-(e-b)
-(-e-b)
Đáp án
c+d*k -> cdk*+ : 32
d*d-c*d*h+h*h -> dd*cd*h*-hh*+ : 16
c-d>!+k*d -> cd>!-kd*+ : 8
(k-c*d)-(c+(d+b*e)) -> kcd*-cdbe*++- : -5
-(e-b) -> eb-~ : -3
-(-e-b) -> e~b-~ : 5

Chuyển đổi biểu thức chính quy sang dạng Poland Postfix
Để chuyển biểu thức chính quy e sang dạng Poland chúng ta cần những quy tắc sau đây:
Quy tắc xây dựng biểu thức chính quy
Ta quy định các biểu thức được xây dựng từ các biến a, b, c,…. nhận các giá trị nguyên a=0, b=1,. c=2, … và các phep
toán như đã trình bày ở phần trên.
Quy định thứ tự ưu tiên của các phép tóan
Khi tính toán giá trị một biểu thức số học ngươi ta thường quy định một trật tự ưu tiên như sau:
1. Tính trị của các biểu thức trong ngoặc
2. Tính trị các lời gọi hàm
3. Tính trị các phép toán một ngôi
4. Tính trị các phép toán hai ngôi
Như vậy, phép toán có độ ưu tiên nhỏ thì được ưu tiên hơn.
Nếu hai phép toán có cùng độ ưu tiên thì thực hiện từ trái qua phải. Trong Python, nếu gặp các phép toán lũy thừa thì
thực hiện từ phải qua trái, ví dụ
2**2**3 = 2**(2**3) = 2**8 = 256
Ví dụ, biểu thức
e = c - d > ! + k*d
sẽ được thực hiện theo trật tự sau đây:
t1 = d>
t2 = t1!
t3 = c-t2
t4 = k*d
t5 = t3+t4
Như vậy dạng Poland chính là một biểu thức thể hiện trật tự tính toán nói trên:
pol = c d > ! - k d * +
Chúng ta tạm quy định thứ tự ưu tiên cho các phép toán như sau:
Phép Độ ưu
toán tiên
> 100
< 100
! 100
* 200
/ 200
% 200
+ 300
- 300
Algorithm
Gọi Compile(e) là hàm chuyển đổi biểu thức chính quy e sang dạng Poland pol.
Ta duyệt từng kí tự c trong e và xét các tình huống:
 Nếu c là biến: đưa c ra pol
 Nếu c là phép toán @: rỡ các phép toán đã nạp trước trên stack có độ ưu tiên bằng hoặc nhỏ hơn độ ưu tiên của @
đưa ra pol. Cuối cùng nạp phép toan @ vào stack để chờ xử lý sau.
 Nếu c là dấu mở ngoặc '(': đưa c lên stack để chờ sau này gặp ')' sẽ xử lý sau
 Nếu c là dấu đóng ngoặc ')': rỡ các phép toán trên ngọn stack đưa ra pol cho đến khi gặp dấu mở ngoặc '(' thì bỏ
đi.
Cuối cùng ta vét nốt các phép toán trên stack đưa ra pol.
Minh họa

Compile('c*(d + e - b*h)') = ?
st pol
Khởi trị [#] ''
'c đưa 'c' ra pol 'c'
'
'* nạp '*' vào st ['*']
'
'( nạp '(' vào st ['*', '(']
'
'd đưa 'd' ra pol 'cd'
'
'+ nạp '+' vào st ['*','(','+']
'
'e đưa 'e' ra pol 'cde'
'
'- rỡ '+' từ st ra pol ['*','(','-'] 'cde+'
' nạp '-' vào st
'b đưa 'b' ra pol 'cde+b'
'
'* nạp '*' vào st ['*','(','-','
' *']
'h đưa 'h' ra pol 'cde+bh'
'
') rỡ st ra pol đế n khi ['*'] 'cde+bh*-
' gặp '(' '
thì bỏ '('
Hết input: vét not st 'cde+bh*-
ra pol *'
return pol 'cde+bh*-
*'

Một phép toán một ngôi có thể được sinh ra trong qua trình chuyển đổi biểu thức sang dạng Poland. Đó là hép đổi dấu. Ví
dụ e = -b cần được hiểu là đổi dấu của số, b do đó -b cần được dịch sang dạng Ba Lan là b~, với ~ là kí hiệu phép toán đổi
dấu. Quan sát kỹ bạn sẽ phát hiện ra rằng phép tóan - được chuyển thành phép đổi dấu khi và chỉ khi nó là phép toán 1
ngôi, cụ thể là khi - đứng đầu biểu thức hoặc ngay sau dấu '(". Ví dụ
-(b+c) sẽ được dịch thành bc+~
(-b+c) sẽ được dịch thành b~c+
Để tiện xử lí. ta bỏ các dấu cách trong biểu thức e và thêm phần tử đệm '#' vào đầu biểu thức e và ngăn đầu tiên (ngăn số
0) của stack.
Chương trình dưới đây thực hiện hai pha: Pha đầu tiên dịch biểu thức toán học e sang dạng Poland pol. Pha thứ hai thực
hiện tính toán trên pol. Cả hai pha đều sử dụng stack.
Program

/*
Name: Postfix expression
Copyright: (C) 2024
Author: DevC Fan
Date: 06-10-24 13:56
Description:
Value of postfix expression
*/

#include <stdio.h>
#define SHAP '#'
#define BL 32
#define FN "BRACKETS.INP"
#define Var(c) (c) >= 'a' && c <= 'z'
#define Val(c) (c) - 'a'
#define MN 1000
#define OP "><!+-*/%"

char pol[MN];

void Go() {
printf(" ? ");
int c = getchar();
if (c == 10) return; // ENTER
if (c == '.') exit(0);
}

int Op(char c) {
int len = strlen(OP);
int i;
for(i = 0; i < len; ++i)
if (OP[i] == c) return 1;
return 0;
}

void SynErr(int r) {
printf("\n Syntax Error %d: ",r);
switch(r) {
case 1: printf("( exprcted"); break;
} // switch
exit(1);
}

int Deg(char c) {
switch(c) {
case '>': // return 100;
case '<': // return 100;
case '!': return 100;
case '*':
case '/':
case '%': return 200;
case '+':
case '-': return 300;
default: return 1000;
} // switch
}

void Compile(char e[]) {


int ii = -1; // counter for pol
int n = strlen(e);
char st[n];
int p = -1; // counter for st
st[++p] = SHAP;
char c;
int i;
for(i = 0; i < n; ++i) {
c = e[i];
// printf("%c", c);
if (Var(c)) { pol[++ii] = c; continue; }
if (c == '(') { st[++p] = c; continue; }
if (c == ')') {
while(st[p] != '(') {
if (st[p] == SHAP) SynErr(1);
pol[++ii] = st[p]; --p;
}
// gap (
--p;
continue;
}
if (Op(c)) {
while(Deg(st[p]) <= Deg(c)) {
pol[++ii] = st[p]; --p;
}
st[++p] = c;
continue;
}
} // for
while(st[p] != SHAP) { pol[++ii] = st[p]; --p; }
//pol[ii] = '\0';
}
void RunErr(int r) {
printf("\n Run Error %d: ",r);
switch(r) {
case 1: printf(" Divide by zero"); break;
case 2: printf(" Negative parameter"); break;
} // switch
exit(1);
}

int Fac(int n) {
int p = 1;
int i;
for(i = 2; i <= n; ++i) p *= i;
return p;
}

int Exe(char pol[]) {


// printf("\n %s", pol);
int n = strlen(pol);
int st[n];
int p = -1;
char c;
int i;
for(i = 0; i < n; ++i) {
c = pol[i];
if (Var(c)) { st[++p] = Val(c); continue; }
switch(c) {
case '>': ++st[p]; break;
case '<': --st[p]; break;
case '!': if (st[p] < 0) RunErr(2);
st[p] = Fac(st[p]); break;
case '+': st[p-1] += st[p]; --p; break;
case '-': st[p-1] -= st[p]; --p; break;
case '*': st[p-1] *= st[p]; --p; break;
case '/': if (st[p] == 0) RunErr(1);
st[p-1] /= st[p]; --p; break;
case '%': if (st[p] == 0) RunErr(1);
st[p-1] %= st[p]; --p; break;
} // switch
} // for
return st[p];
}

main() {
// a bcdef ghijk lmnop qrstu vwxyz
// c*(d+h) -> cdh+* = 2*(3+7) = 2*10 = 20
// char *e = "c*(d+h)";

char *e = "c>>!*(d+h) + c*(d+h) ";


Compile(e);
printf("\n %s -> %s", e, pol);
int r = Exe(pol);
printf("\n Result: %d", r);

//printf("\n %d", strlen(OP));


printf("\n T h e E n d");
return 0;
}

Josephus Problem
Trò chơi chọn duy nhất một tù trưởng trong số n người có tài ngang nhau được thực hiện như sau:
Xếp vòng tròn n người. Bắt đầu từ người thứ nhất đếm k người, loại khỏi vòng tròn người thứ k. Khi nào còn lại 1 người
thì người đó được bầu làm tù trưởng.
Ví dụ

n = 12, k = 5
Thành 1 2 3 4 5 6 7 8 9 10 11 12
viên
Trật tự loại d 3 5 1 d d d 4 2 d 6

Trúng cử: 1

Algorithm
Bài này có nhiều cách giải.
Cách giải thứ nhất. Mô phỏng qua dãy số. Gọi a là dãy số 1..n. Duyệt a theo vòng tròn gặp người thứ k thì loại bằng phép
gán trị a[v] = 0. Độ phức tạp O(n)
Program

Cách giải thứ 2. Mô phỏng qua hàng đợi q. Gọi q là dãy số với các giá trị khởi đầu 1..n. Duyệt q để chuyển k-1 người từ
đầu q về cuối q, loại phần tử thứ k khỏi q. Người cuối cùng còn lại trong q là kết quả. Mô hình hóa theo hàng đợi có tính
trực quan hơn theo dãy số về thao tác loại bỏ phần tử. Giả sử ta có vòng tròn n = 12 người và ta phải loại bỏ người thứ k
= 5 sau mỗi lượt đếm theo bước 5. Ta có
Khởi trị: q = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
Lượt đếm thứ nhất q = [6, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4] (loại người số5)
Lượt đếm thứ hai q = [11, 12, 1, 2, 3, 4, 6, 7, 8, 9] (loại người số10)
...
Độ phức tạp
O(n)
Program

/*
Name: Josephus Problem
Copyright: (C) 2024
Author: DevC Fan
Date: 06-10-24 13:56
Description:
n nguoi dung vong tron, dem tu 1 loai nguoi thu k.
Ai la nguoi cpn lai cuoi cuing
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void Go() {
printf(" ? ");
int c = getchar();
if (c == 10) return; // ENTER
if (c == '.') exit(0);
}

int Count(int a[], int n, int k, int j) {


int t = a[j];
while(t < k) { j = (j+1)%n; t += a[j]; }
// printf("\n delete %d", j);
a[j] = 0;
while(a[j] == 0) j = (j+1)%n;
return j;
}

void Print(char *msg, int a[], int n) {


printf("%s", msg);
int i;
for(i = 0; i < n; ++i) printf(" %d", a[i]);
}

int JP(int n, int k) {


int a[n];
int i;
// init
for(i = 0; i < n; ++i) a[i] = 1;
int j = 0;
for(i = 1; i < n; ++i)
j = Count(a,n,k,j);
return j+1;
}

main() {
int n = 12, k = 5; // r = 1
// int n = 33, k = 5;
int r = JP(n, k);
printf("\n %d", r);
printf("\n T h e E n d.");
return 0;
}

Bình luận 1
Một phương án giải khác dựa trên hàm đệ quy như sau. Gọi V(n, k) là số hiệu của người còn lại khi thực hiện trò chơi
Josephus với n người và bước đếm k. Ta thấy,
nếu n = 1 thì V(n, k) = 1
nếu n > 1 thì V(n,k) = (V(n-1, k) + (k-1)) % n + 1
Bạn có thể cài đặt phương án này qua hàm lặp Rest như sau:
int Rest(int n, int k) {
if (n == 1) return 1;
--k; ++n;
int v = 1, i;
for (i = 2; i < n; ++i) v = ((v+k) % i) + 1;
return v;
}
Điều thú vị là bài Josephus gợi ý cho chúng ta xây dựng một loại mật mã mới. Mỗi loại mật mã gồm hai hàm: mã hóa và
giải mã.

Josephus Cypher

Hàm mã hóa Encode(s, key,w) nhận vào một string cần mã hoa theo khóa k. Hàm cho ra string w là dãy các kí tự bị xóa
khỏi s trong trò chơi Josephus with key. Ta gọi s là bản rõ, w là bản mật.
Hàm giải mã Decode(w, key, s) nhận vào bản mật w và khóa k. Hàm cho ra bản rõ s. Dễ thấy hai hàm này thực hiện các
thao tác xuôi-ngược nhau.
Vậy ta chỉ cần một hàn JP(s, key, code=1) với tham biến ngầm định code bao quát cả hai trường hợp. Nếu code = 1 thì ta
có hàm Encode; ngược lại, khi code != 1 thì ta có hàm Decode.
Hàm JP(s, key) sẽ xếp các đối tượng trong s thành vòng tròn và lần lượt đếm theo khóa k trong key để chuyển mỗi đối
tượng cần loại khỏi vòng tròn sang string w.
/*
Name: Josephus Cypher
Copyright: (C) 2024
Author: DevC Fan
Date: 06-10-24 13:56
Description:
*/

//#include <stdio.h>
//#include <stdlib.h>
//#include <string.h>
#define ENDSTR '\0'
#define MN 500

void Go() {
printf(" ? ");
int c = getchar();
if (c == 10) return; // ENTER
if (c == '.') exit(0);
}

int Del(int a[], int n, int k, int j) {


int t = a[j];
while(t < k) { j = (j+1)%n; t += a[j]; }
return j;
}

void Encode(char s[], int k, char w[]) {


int i, n = strlen(s);
int a[n];
// init
for(i = 0; i < n; ++i) a[i] = 1;
int j = 0;
int v = 0; // counter for w
for(i = 1; i < n; ++i) {
j = Del(a,n,k,j); // xoa phan tu thu j
w[v++] = s[j];
a[j] = 0;
while (a[j] == 0) j = (j+1)%n;
}
w[v++] = s[j]; w[v] = ENDSTR;
}

void Decode(char w[], int k, char s[]) {


int i, n = strlen(w);
int a[n];
// init
for(i = 0; i < n; ++i) a[i] = 1;
int j = 0;
int v = 0; // counter for w
for(i = 1; i < n; ++i) {
j = Del(a,n,k,j); // xoa phan tu thu j
// w[v++] = s[j];
s[j] = w[v++];
a[j] = 0;
while (a[j] == 0) j = (j+1)%n;
}
s[j] = w[v];
s[n] = ENDSTR;
}

void Code(char inp[], int k, char out[], int ed) {


int i, n = strlen(inp);
int a[n];
// init
for(i = 0; i < n; ++i) a[i] = 1;
int j = 0;
int v = 0; // counter for w
for(i = 1; i < n; ++i) {
j = Del(a,n,k,j); // xoa phan tu thu j
if (ed) out[v++] = inp[j]; // encode
else out[j] = inp[v++];
a[j] = 0;
while (a[j] == 0) j = (j+1)%n;
}
if (ed) out[n-1] = inp[j];
else out[j] = inp[v];
out[n] = ENDSTR;
}

void Demo() {
//char x[] = "Posts and Telecommunications Institute of Technology";
char x[] = "*Con*co*bay*la*bay*la...";
printf("\n Input %s", x);
int k = 5;
char w[MN];
char s[MN];
Code(x, k, w, 1);
printf("\n w = %s", w);
Code(w,k,s, 0);
printf("\n s = %s", s);
}

main() {
Demo();
printf("\n T h e E n d");
return 0;
}

You might also like