Skip to content

Commit 245cdd0

Browse files
committed
Merge branch 'master' into develop
2 parents 7d9106e + 91282a9 commit 245cdd0

File tree

10 files changed

+257
-41
lines changed

10 files changed

+257
-41
lines changed

Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,9 @@ PROGRAMS = m_based_demo \
6666
scc_demo \
6767
sort_demo \
6868
bubble_sort_demo \
69-
selection_sort_demo
69+
selection_sort_demo \
70+
8queue_demo \
71+
palindrome_demo
7072

7173
all: $(PROGRAMS)
7274

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@
8888
K-Means
8989
Knuth–Morris–Pratt algorithm
9090
Disjoint-Set
91+
8-Queue Problem
92+
Palindrome
9193

9294
####贡献者 ( Contributors ) :
9395
Samana : for heavy work of MSVC compatability

include/8queen.h

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*******************************************************************************
2+
* DANIEL'1'S ALGORITHM IMPLEMENTAIONS
3+
*
4+
* /\ | _ _ ._ o _|_ |_ ._ _ _
5+
* /--\ | (_| (_) | | |_ | | | | | _>
6+
* _|
7+
* 8-Queue
8+
*
9+
* http://en.wikipedia.org/wiki/Eight_queens_puzzle
10+
******************************************************************************/
11+
12+
#ifndef __8QUEEN_H__
13+
#define __8QUEEN_H__
14+
15+
#include <stdio.h>
16+
#include <string.h>
17+
18+
namespace alg {
19+
class Queen8 {
20+
private:
21+
char board[8][8];
22+
int cnt;
23+
public:
24+
void solve() {
25+
memset(board, '0', sizeof(board));
26+
cnt = 0;
27+
_solve(0);
28+
}
29+
private:
30+
void _solve(int row) { // start from 0
31+
int i;
32+
for (i=0;i<8;i++) {
33+
board[row][i] = '1';
34+
if (check(row, i)) {
35+
if (row == 7) print();
36+
else _solve(row+1);
37+
}
38+
board[row][i] = '0'; // rollback
39+
}
40+
}
41+
42+
void print() {
43+
printf("chessboard: %d\n",++cnt);
44+
int i,j;
45+
for (i=0;i<8;i++) {
46+
for (j=0;j<8;j++) {
47+
printf("%c ", board[i][j]);
48+
}
49+
printf("\n");
50+
}
51+
}
52+
53+
bool check(int row, int col) {
54+
int i,j;
55+
56+
// cannot be same column
57+
for (i=0;i<row;i++) {
58+
if (board[i][col] == '1') {
59+
return false;
60+
}
61+
}
62+
63+
// cannot be diagnal
64+
i = row-1, j = col-1;
65+
while (i>=0 && j >=0) {
66+
if (board[i][j] == '1') {
67+
return false;
68+
}
69+
i--;
70+
j--;
71+
}
72+
73+
i = row-1, j = col+1;
74+
while (i>=0 && j <8) {
75+
if (board[i][j] == '1') {
76+
return false;
77+
}
78+
i--;
79+
j++;
80+
}
81+
82+
return true;
83+
}
84+
};
85+
}
86+
87+
#endif //__8QUEEN_H__

include/astar.h

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -107,13 +107,14 @@ namespace alg {
107107
as->path = NULL;
108108
as->num_nodes = 0;
109109

110+
// the main A*algorithm
110111
while(!m_openset.is_empty()) {
111112
uint32_t value = m_openset.min_value();
112113
int cx = value/ncol;
113114
int cy = value%ncol;
114115

115-
if(cx == (int)x2 && cy==(int)y2) { // we reached (x2,y2)
116-
// reconstruct path & return
116+
if(cx == (int)x2 && cy==(int)y2) { // great! we've reached the target position (x2,y2)
117+
// reconstruct path
117118
as->num_nodes = 2;
118119
uint32_t tmp = x2*ncol+y2;
119120
while((tmp=came_from[tmp]) != x1*ncol+y1) {
@@ -135,47 +136,55 @@ namespace alg {
135136
return as;
136137
}
137138

139+
// delete current positon from openset and move it into closed set.
138140
m_openset.delete_min();
139141
m_closedset(cx, cy) = true;
140142
m_openset_grid(cx, cy) = false;
141143

142-
// for each neighbor
144+
// for each valid neighbor of current position
143145
int nx, ny;
144146
for(nx=cx-1;nx<=cx+1;nx++) {
145-
if (nx<0 || nx>=(int)ncol) continue;
146147
for(ny=cy-1;ny<=cy+1;ny++) {
147-
if (ny<0 || ny>=(int)nrow) continue;
148-
149-
// except the wall;
150-
if(m_grid(nx,ny) == WALL) continue;
148+
// exclude invalid position
149+
if (nx<0 || nx>=(int)ncol || ny<0 || ny>=(int)nrow) continue;
151150
// except the cur itself
152151
if(nx == cx && ny==cy) continue;
153-
// if neighbour in the closed set
152+
// except the wall;
153+
if(m_grid(nx,ny) == WALL) continue;
154+
// exclude the neighbour in the closed set
154155
if(m_closedset(nx,ny)) continue;
155156

157+
// ok, we got a valid neighbour
156158
float tentative = g_score(cx,cy);
157-
if (nx == cx || ny == cy) {
158-
tentative += 1 + m_grid(nx,ny);
159-
} else {
160-
tentative += (1 + m_grid(nx,ny)) * SQRT2;
159+
if (nx == cx || ny == cy) { // horizontal/vertical neighbour is near
160+
tentative += 1;
161+
} else { // diagonal neighbour is farther.
162+
tentative += SQRT2;
161163
}
162164

163165
// if neighbour not in the openset or dist < g_score[neighbour]
164166
if (!m_openset_grid(nx,ny) || tentative < g_score(nx,ny)) {
165-
came_from[nx*ncol+ny] = cx*ncol+cy; // record path
166-
g_score(nx,ny) = tentative;
167-
f_score(nx,ny) = tentative + estimate(nx,ny,x2,y2);
168-
if (!m_openset_grid(nx,ny)) {
167+
came_from[nx*ncol+ny] = cx*ncol+cy; // record the path
168+
g_score(nx,ny) = tentative; // update path cost for current position
169+
f_score(nx,ny) = tentative + estimate(nx,ny,x2,y2); // record path cost to this neighbour
170+
if (!m_openset_grid(nx,ny)) { // only insert the neighbour if it hasn't been add to the openset.
169171
m_openset.insert(f_score(nx,ny), nx*ncol+ny);
170172
m_openset_grid(nx,ny) = true;
171173
}
172174
}
173175
}
174176
}
175177
}
178+
179+
// haven't reached target
176180
return as;
177181
}
178182
private:
183+
/**
184+
* Estimate the cost for going this way, such as:
185+
* acrossing the swamp will be much slower than walking on the road.
186+
* design for you game.
187+
*/
179188
inline float estimate(int x1, int y1, int x2, int y2) const {
180189
return sqrtf((x2-x1) * (x2-x1) + (y2-y1)*(y2-y1));
181190
}

include/palindrome.h

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*******************************************************************************
2+
* DANIEL'S ALGORITHM IMPLEMENTAIONS
3+
*
4+
* /\ | _ _ ._ o _|_ |_ ._ _ _
5+
* /--\ | (_| (_) | | |_ | | | | | _>
6+
* _|
7+
*
8+
* PALINDROMES
9+
*
10+
* WORDS LIKE:
11+
* RACECAR DEED LEVEL PIP
12+
* ROTOR CIVIC POP MADAM
13+
* EYE NUN RADAR TOOT
14+
*
15+
* This program will find the longest part of mirror.
16+
*
17+
* http://en.wikipedia.org/wiki/Palindrome
18+
******************************************************************************/
19+
20+
#ifndef _PALINDROME_H_
21+
#define _PALINDROME_H_
22+
23+
#include <stdio.h>
24+
#include <stdlib.h>
25+
#include <string.h>
26+
27+
namespace alg {
28+
static void palindrome(const char * S) {
29+
char *R= strdup(S);
30+
int len = strlen(S);
31+
// reverse
32+
for(int i=0;i<len;i++) {
33+
R[len-i-1] = S[i];
34+
}
35+
36+
int middle = 0;
37+
int maxlen = 0;
38+
for(int i=0;i<len;i++) {
39+
// compare S[0:i] with R[0:length-i-1] in reverse order
40+
int offset = 0;
41+
int curlen = 0;
42+
43+
// try odd
44+
while (i-offset>= 0 && len-i-1-offset >= 0) {
45+
if (S[i-offset] == R[len-i-1-offset]) {
46+
curlen++;
47+
} else {
48+
break;
49+
}
50+
offset++;
51+
}
52+
53+
if (curlen > maxlen) {
54+
maxlen = curlen;
55+
middle = i;
56+
}
57+
58+
// try even
59+
while (i-offset>= 0 && len-i-2-offset >= 0) {
60+
if (S[i-offset] == R[len-i-2-offset]) {
61+
curlen++;
62+
} else {
63+
break;
64+
}
65+
offset++;
66+
}
67+
68+
if (curlen > maxlen) {
69+
maxlen = curlen;
70+
middle = i;
71+
}
72+
}
73+
74+
printf("str:%s len:%d middle:%d\n",S, maxlen, middle);
75+
free(R);
76+
}
77+
}
78+
79+
#endif //

include/quick_sort.h

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,42 +19,63 @@
1919
#define __QUICKSORT_H__
2020

2121
#include <generic.h>
22+
#include <cassert>
2223

2324
namespace alg {
25+
26+
/**
27+
* Return median of begin, middle, and end.
28+
* Order these and hide the pivot.
29+
*/
30+
template<typename T>
31+
static const T & __median3(T list[], int begin, int end) {
32+
assert(begin + 2 <= end);
33+
int middle = end - (end - begin) / 2;
34+
if (list[middle] < list[begin])
35+
swap(list[middle], list[begin]);
36+
if (list[end] < list[begin])
37+
swap(list[end], list[begin]);
38+
if (list[end] < list[middle])
39+
swap(list[end], list[middle]);
40+
41+
//Place pivot at position [end - 1]
42+
swap(list[middle], list[end - 1]);
43+
return list[end - 1];
44+
}
45+
2446
/**
2547
* the quick-sort partition routine
2648
*/
2749
template<typename T>
2850
static int __partition(T list[],int begin, int end) {
29-
int pivot_idx = RANDOM(begin,end);
30-
T pivot = list[pivot_idx];
31-
swap(list[begin], list[pivot_idx]);
32-
33-
int i = begin + 1;
34-
int j = end;
35-
36-
while(i <= j) {
37-
while((i <= end) && (list[i] <= pivot))
38-
i++;
39-
while((j >= begin) && (list[j] > pivot))
40-
j--;
51+
T pivot = __median3<T>(list, begin, end);
52+
53+
int i = begin;
54+
int j = end - 1;
55+
56+
while(i < j) {
57+
while(list[++i] < pivot) {}
58+
while(pivot < list[--j]) {}
4159
if(i < j)
4260
swap(list[i],list[j]);
4361
}
4462

45-
swap(list[begin],list[j]);
46-
return j; // final pivot position
63+
swap(list[i],list[end - 1]);
64+
return i; // final pivot position
4765
}
4866

4967
/**
5068
* quick sort an array of range [begin, end]
5169
*/
5270
template<typename T>
5371
static void quicksort(T list[],int begin,int end) {
54-
if( begin < end) {
72+
if( begin + 1 < end) {
5573
int pivot_idx = __partition<T>(list, begin, end);
5674
quicksort(list, begin, pivot_idx-1);
5775
quicksort(list, pivot_idx+1, end);
76+
} else if ( begin + 1 == end) {
77+
if (list[begin + 1] > list[end])
78+
swap(list[begin + 1], list[end]);
5879
}
5980
}
6081
}

include/scc.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,15 @@ namespace alg {
3838
// step 1. discover vertices of G in decreasing of u.f
3939
Heap<int32_t> Q(g.vertex_count()) ;
4040
Graph::Adjacent * a;
41-
list_for_each_entry(a, &g.list(), a_node) {
41+
list_for_each_entry(a, &g.list(), a_node) {
4242
Q.insert(INT_MAX - a->f, a->v.id); // descending order of a->f
43-
}
43+
}
4444

4545
// step 2. discover
46-
// mark all vertex color to WHITE
47-
list_for_each_entry(a, &GT->list(), a_node) {
48-
a->color = Graph::WHITE;
49-
}
46+
// mark all vertex color to WHITE
47+
list_for_each_entry(a, &GT->list(), a_node) {
48+
a->color = Graph::WHITE;
49+
}
5050

5151
// step 3. call DFS(GT), but in the main loop of DFS, consider the vertices
5252
// in order of decreasing u.f (as computed in line 1)

src/8queue_demo.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#include <stdio.h>
2+
#include <8queen.h>
3+
4+
int main(void) {
5+
alg::Queen8 q;
6+
q.solve();
7+
}
8+

src/palindrome_demo.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#include "palindrome.h"
2+
#include <stdio.h>
3+
4+
int main() {
5+
alg::palindrome("banana");
6+
alg::palindrome("abba");
7+
alg::palindrome("aaaaa");
8+
}

0 commit comments

Comments
 (0)