帐前卒专栏

code, software architect, articles and novels.
代码,软件架构,博客和小说

one day somebody’s gonna  have to make a stand.

one day, somebody’s gonna have to say enough.

老渔夫说出这么有哲理的话出来.是抱怨呢?还是just say to his son.
不过一般说这话的人都很难第一个站出来.否则也就不会说这就话了.因为他使用了somebody而不是…I.但是这话本身在这场电影里挺有气势的.

I never understood the gods, but even I don’t question that  you are saved for
some reason. And some day, that reason, is gonna take you far away from here.

换而言之,每个人呆在这个地球上都是有理由的.当然有可能是配角,上来便game over. 也有可能是主角,到最后怎么都不会game
over.所以努力活着…该over的时候就认命.

I can do this as a man.这话是鄙视人类还是鄙视要做的这件事本身呢? or both of them.

your journey does not  end well. Fate has spoken.女巫说了这样的话.加入相信,那就必死无疑.不相信,或许还能
证明女巫说错了.想到了算命的.没有什么准不准,自己把握着自己的命运.其实女巫说只有美杜莎可以杀死海妖,这事情我早就知道了.惊奇的发现拍片人的智商依旧那么低.
当然如果他们早就知道,估计就没有女巫那一场戏了.

I’d rather die in the mud with those men, than live forever as a
God.其实做God挺好…推荐他先看一下上帝也疯狂.

we live, we fight and we die for each other.生死患难,或许就是这句话的意思.

I have everything I need. Right here.主角这人其实活得很high…啥叫知足者常乐.

其实这部影片写的希腊神话被编剧改的面目全非.不过希腊神话就是神话,几乎所有神话都可以改写来改写去的.看电影其实是看看编辑的想象力.只不过我很好奇…美杜
莎跟所有编剧都有仇…不杀死她咋都没有办法完成任务.

这部影片中要献祭的公主其实就是仙女座,男主角是英仙座,皇后是仙后座,国王是仙王座.海怪是鲸鱼座.我终于理解日本人为啥要杀鲸鱼了…这是几千年的仇恨呀…

总体评价:

场面宏大,打斗火爆.话语有时很激情.配角比主角更出色.

有许多其实开始就知道即使尽力也很难实现。所以在结果出来之时,我还是询问下是否尽力了。尽力而为或者与虽败尤荣是同义词,只不过一个是在之前说,另外一个是在之后说
。说尽力是真话,反正也可以作为幌子。真与假只有自己评定。这是一份诚信的答卷,可是仍然可以写不诚信的答案。机会给了又给却还是不一定有机会。人何必执着,没有必要
为一个信念而活,就如同不要在一颗树上吊死一样。于是我说,那就在两棵树上吊死好了…都是死掉还分什么多少?墓葬的人可曾想到?…但是人的确是执着的,结果就
沦为固执。本来就是度的问题,结果因为不可量化而导致不同的结局。当然要看结局是什么。所有人都是结局论者,因为历史中没有假设。自己也是极端主义者,因为假设了所有
的人。运气是实力的一部分,我很赞同。因为在对的地点遇到对的人做对的事情本来就是攒了许多人品的运气。师兄的杯子留给了我,里面是黑黑的茶垢还有数不尽的细菌和病毒
,我准备用它来养花。但是首先要将它戳个洞。事情总要有先决条件,没有的话就是想到也做不成。因为我这里没有锥子。真实世界和计算机世界有太多不同,这就是许多技术牛
人至今仍然默默无闻的原因,这也是许多出了名的往往不是技术牛人的原因。混是很好的词,它反映了当今社会的主流趋势。所以即使你不想同流合污,也必须混成非主流。呓语
有终但无始。散文形散而意不散,我的形散意也散。真想将此文当资格评审卷考一下语文老师们。他们是无论如何也揣摩不出我的深层含义,当然你们也一样。这让我想到说的所
有话都是歧义句,我怎么可能有全部理解正确的时候?知道自己的信念就坚持走下去,总有人会跟随…换句话说也对,坚持走下去总会产生自己的信念,并为别人所信仰…
.

the simplest quick sort is like following:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include<iostream>

using namespace std;

int Partition(int * a, int start, int end){
swap(a[start],a[start+rand()%(end-start+1)]);
int p = a[start];
while(start<end){
while(start<end && a[end] >= p) end--;
swap(a[start],a[end]);
while(start<end && a[start]<= p) start++;
swap(a[start],a[end];)
}
return start;
}

void QuickSort(int * a, int start, int end){

if(end-start>=1){
int mid = Partition(a,start, end);
QuickSort(a,start,mid-1);
QuickSort(a,mid+1,end);
}
}

But If you want do some optimization in QuickSort, first when the number of elements is small than 10, do insert sort not quick sort. Second, To find the near-like middle element of array, and not use the random one. Third, when the array is already sorted , do not use quick sort. and Reduce the function call. You will the following codes:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include<iostream>

using namespace std;

void QuickSort(int *a, int start, int end){

if(end - start <= 0 ) // or you can throw some exceptions!
return ;

// if the number of element is less than 8, do insert sort;

if(end - start<7){

for(int i = start; i <= end; i++){

for(int j = i; j > start && a[j] < a[j-1]; j--)

swap(a[j],a[j-1]);

}

return;
}

// check if the array is sorted.

bool isSorted = true;
for(int i = start; i < end; i++){
if(a[i]>a[i+1])
isSorted = false;
}
if(isSorted)
return;

// get the near-like middle element, use 3 point middle method.

int dm = start+(end-start)/2;

int dl, dh;

if(end-start<40){

int d = (end-start+1)/8;

dl = mid(a, start,start+d,start+2*d);

dm = mid(a,dm-d,dm,dm+d);

dh = mid(a,end-2*d,end-d, end);

dm = mid(a,dl,dm,dh);

}

// do partition

swap(a[start],a[dm]);

int low=start, high = end, p = a[start];
while(low<high){
while(low < high && a[high]>= p) high--;
swap(a[low],a[high]);
while(low<high && a[low]<= p) low ++;
swap(a[low],a[high]);
}
QuickSort(a,start, low-1);
QuickSort(a,low+1,end);
}

写了一个upper_bound的实现。其中递归使用二分法求解最上界,虽然写的完全不像STL的风格,但是练手还是可以的。

#include #include #include #include
using namespace std; int UpperBound(int* a, int start, int end , const int&
value){ int mid = 0; int index = 0; int up_index = 0; if(a[end]<value) //
特判比最后一个数大时,end+1 return end+1; //这里是经典的二分 while(start<= end){ mid = start +
(end - start)/2; if(a[mid] == value){ index = mid + 1; // 去递归的找一下上界 up_index =
UpperBound(a,mid+1,end,value); // 如果找到的上界比现在的还小,那么就用现在的 return up_index >
index? up_index : index; } else if(a[mid]<value){ start = mid+1; } else{ end =
mid-1; // 记录上界 index = mid; } } return index; }

如果原数组中没有存在那个元素,就根本没有调用那个递归程序,递归只有在出现多个此元素时才会调用。另外中间递归调用段地方还可以改写为:

if(a[mid] == value){ index = mid + 1; /* up_index =
UpperBound(a,mid+1,end,value); return up_index > index? up_index : index; */
// 因为只有在递归调用中start>end时,才会返回一个index = 0 return (mid+1>end) ? index :
UpperBound(a,mid+1,end,value); }

这样写完后写一下测试代码,顺便wrap一层upper_bound:

int upper_bound(int * a,int n, const int& value){ // 使用宏可以在编译时去除 #ifdef TEST
// pre-condition assert(NULL != a && n>0); // check the array a is sorted by
elements for(int i = 1; i < n; i++){ assert(a[i-1]<=a[i]); } int * tmp_a = new
int[n]; memcpy(tmp_a,a,sizeof(int)*n); #endif int index =
UpperBound(a,0,n-1,value); #ifdef TEST // post-condition //check whether the
array is changed or not for(int i = 0; i < n; i++) assert(a[i] == tmp_a[i]);
if(index == 0){ // min assert(a[index]>value); } else if(index == n){ // max
assert(a[index-1]<=value); } else{ assert(a[index]>value &&
a[index-1]<=value); } delete [] tmp_a; #endif return index; }

如果希望别人不调用UpperBound而只调用upper_bound,可以使用static 关键字, 将UpperBound限制在只在本文件中使用。别人调用
就只能调用upper_bound()函数。不过STL的教学源码比我这精简的多,根本无须使用递归。真正的STL源码变量名称会使用下划线__作为起始。

template <class ForwardIterator, class T> ForwardIterator upper_bound (
ForwardIterator first, ForwardIterator last, const T& value ) {
ForwardIterator it; iterator_traits::distance_type count,
step; count = distance(first,last); while (count>0) { it = first;
step=count/2; advance (it,step); if (!(value<*it)) // or: if
(!comp(value,*it)), for the comp version { first=++it; count-=step+1; } else
count=step; } return first; }

这里的advance()函数定义类似:

template<class Iterator, class Distance> void advance(Iterator& i, Distance
n); 类似于 i = x.begin()+n; i is an iterator of x

最后把主函数贴上做结:

int main(int argc, char* argv[]) { // 这里你可以使用random的方法进行测试。 int x[] =
{1,2,3,4,5,5,5,5,9}; vector v(x,x+9); sort(v.begin(),v.end()); cout <<
(int)(upper_bound(v.begin(),v.end(),9)-v.begin()); cout << upper_bound(x,9,9);
return 0; }

package test; import java.util.*; // Key class class A{ public int a; public
int b; A(int a, int b){ this.a = a; this.b = b; } public boolean equals(Object
o){ A x = (A)o; if(x.a == this.a && x.b == this.b) return true; return false;
} public int hashCode(){ return a+b; } } public class HashTableTest { /** *
@param args */ public static void main(String[] args) { // TODO Auto-generated
method stub HashMap<A,Integer> hm = new HashMap<A,Integer>(); A a1 = new
A(2,3); A a2 = new A(4,5); A a4 = new A(2,3); A a3 = new A(3,2); hm.put(a1,
new Integer(1)); hm.put(a2, new Integer(3));
System.out.print(hm.containsKey(a4)); } }

对于Key这个类,这里需要重载boolean  equals(Object o) 和int hashCode()
两个函数。这两个函数必须都要重载,否则会导致key找到不到。这里要说为什么,估计是HashMap中使用key相等的策略是
if(key1.equals(key2) && key1.hashCode() == key2.hashCode()),
因为hashcode可能会有多个不同的实例对应于一个hashCode, 所以这个东东会重叠。对于判断两个对象是否相等,java默认使用的是引用相等,即a
== b。但是对于String等其他内置的类来说,他们有自己的重载equals()方法。另外java
doc中也提到,当重载equals()方法时,最好把hashCode()方法也重载掉。这样看来if(key1.equals(key2) &&
key1.hashCode() == key2.hashCode())这句应该变为:

Key k = this.Get(key2.hashCode()); if (k.equals(key2)) return …





这篇文章是写如何在界面上只输出一行,而不用写到另外一行的方法。中文不知道专业名称是什么,英语也不知道怎么说这个才能被搜索到。

this article is about how to print one row only, and do not need to write infos to another row. I don’t know how to describe it in Chinese or English. And I also don’t know this article how to be searched.

This effect is like use wget to downloading files. You will see the process bar moving. How to display this effect? Use the following code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include&lt;cstdio&gt;
#include&lt;unistd.h&gt;
using namespace std;

int main(){
printf("====&gt;\r");
fflush(stdout); #flush buffer
sleep(2); # wait
printf("======&gt;\r");
fflush(stdout);
sleep(3);
printf("========&gt;\n");
return 0;
}

In the above code, ‘\r’ is “Enter” character, and ‘\n’ is “newline” character. If input ‘\n’ into printf(), it will go to a new line. If input ‘\r’ into printf(), the output cursor will go to the beginning. If you do not use fflush(stdout); you will never your output without ‘\n’.

How to get absolute (integer) only use bit operators and +-*/.(In gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5)  )
  • if number >= 0 , then number >> 31 == 0
  • if number < 0   , then number >> 31 == 0xFFFFFFFF
If some number exclusive or( xor ) 0xFFFFFFFF means each bit becomes its "opposite" number. (1 becomes 0, and 0 becomes 1).And If a number xor 0x00000000 means nothing happened to this number. So:
  • number ^ 0xFFFFFFFF = ~number
  • number ^ 0x00000000 = number
In this question, you should also know something about complement number(see two's complement). When a number is negative, |number| = ~number +1 or you can use |number| = !number + 1. When a number is positive, |number| = number.

If you know above, then the goal of |x| = (x^(x>>31))+(~(x>>31)+1).

(x^(x>>31)) means:

  • x >= 0, x^(x>>31) = x^0x00000000 = x
  • x < 0, x^(x>>31) = x^0xFFFFFFFF = ~x
And (~(x>>31)+1)means:
  • x >= 0, ~(x>>31)+1 = 0xFFFFFFFF+1 = 0
  • x < 0, ~(x>>31)+1 = 0x00000000+1 = 1
And we should take care of those brackets, because the priorities of operators are: ~ > */ > + - > bit operators(&,^,|)
Level Operator Description Grouping
1 :: scope Left-to-right
2 () [] . -> ++ -- dynamic_cast static_cast reinterpret_cast const_cast typeid postfix Left-to-right
3 ++ -- ~ ! sizeof new delete unary (prefix) Right-to-left
* & indirection and reference (pointers)
+ - unary sign operator
4 (type) type casting Right-to-left
5 .* ->* pointer-to-member Left-to-right
6 * / % multiplicative Left-to-right
7 + - additive Left-to-right
8 << >> shift Left-to-right
9 < > <= >= relational Left-to-right
10 == != equality Left-to-right
11 & bitwise AND Left-to-right
12 ^ bitwise XOR Left-to-right
13 | bitwise OR Left-to-right
14 && logical AND Left-to-right
15 || logical OR Left-to-right
16 ?: conditional Right-to-left
17 = *= /= %= += -= >>= <<= &= ^= |= assignment Right-to-left
18 , comma Left-to-right

In c language, there are three methods for memory allocation: malloc(), calloc(), realloc(). And one method to free memory: free().

The malloc function prototype is : void* malloc(size_t size); This function will allocates a block of size bytes of memory, returning a pointer to the beginning of the block. Attention: this function is only for allocating memory! So the initial value of these memory will be Non-Zero. Maybe sometimes, it will be zero. Code for example:

1
2
3
4
5
6
7
8
9
10
11
#include&lt;stdio.h&gt;
#include&lt;stdlib.h&gt;
int main(){

int * a = NULL;
a = malloc(sizeof(int)*4);
// like int a[4], but those memory is in heap
for(int i = 0; i&lt; 4; i++)
printf("%d ",a[i]);
return 0;
}

The realloc function prototype is : void* realloc(void* ptr, size_t size); This function will reallocates a block of size bytes of memory, returning a pointer to the beginning of the block. If size is zero and ptr is not NULL, it will be used as free(). If prt is NULL and size is not zero, it will be used as malloc(). If ptr is NULL and size is zero, return value is some kind of memory which contains zero elements! Wooo~~~~. Look at the following codes:

1
2
3
4
5
6
7
8
char * p = NULL;
printf("%x",(int)p); // will output 0

p = (char*)realloc(p,0);
printf("%x",(int)p); // will output non-zero

p = (char*)realloc(p,0);
printf("%x",(int)p);

why?! Because if this function is called successfully, it will return non-zero memory address. And you will see the third output subtract the second output will be 16 bytes. If ptr is not NULL , and size is non-zero, and current block can simply expand without moving,  the return value is the same as ptr. But there is not enough space for simply expand, it will execute free(ptr) and return malloc(size). This function will become very dangerous!

1
2
3
char * k = (char*)realloc(NULL,100);
char * kbigger = (char*)realloc(k,104);
char * kbiggest = (char*)realloc(k,106); <span style="color: #ff0000;">// crash!</span>

Safety called will be like the following:

1
2
3
char * k = (char*)realloc(NULL,100);
k = (char*)realloc(k,4); // k's address is not changed
k = (char*)realloc(k,104); // k's address is changed

If there is not enough free memory to be allocated, this function will return NULL.Attention: this function will not initialize those memory also.

calloc's prototype is void* calloc(int num, size_t size).

1
2
3
4
5
6
char* p = (char*)calloc(20,sizeof(char));

// it is equal to

char* p = (char*)malloc(20*sizeof(char));
memset(p,0,20*sizeof(char));

But calloc is efficient!

free function is to delete memory which has been allocated. But free function will not assign the point to zero.

1
2
3
4
5
6
7
8
char * p = (char*)calloc(100);

p[0] = 'a';
printf("%c",p[0]); // output 'a'
printf("%x",(int)p);
free(p);
printf("%c",p[0]); // output nothing
printf("%x",(int)p); // the value is the same as the first.

And all of those functions will not recommend to be used in c++, because those functions will not initialize class structure or v_ptr. free() function will not destruct parent class when sub class is destructed. In c++, maybe should always use new and delete!

package queens; import java.io.FileNotFoundException; import
java.io.IOException; import org.sat4j.csp.SolverFactory; import
org.sat4j.reader.ParseFormatException; import org.sat4j.reader.XMLCSPReader;
import org.sat4j.specs.ContradictionException; import
org.sat4j.specs.IProblem; import org.sat4j.specs.ISolver; import
org.sat4j.specs.TimeoutException; import org.sat4j.tools.ModelIterator; public
class Solver { public static void main(String[] args) { ISolver solver =
SolverFactory.newDefault(); solver.setTimeout(360); ModelIterator mi = new
ModelIterator(solver); XMLCSPReader reader = new XMLCSPReader(solver); try {
if (reader != null) reader.parseInstance(“queens.xml”); IProblem problem = mi;
boolean unsat = true; int count = 1; while (problem.isSatisfiable()) { unsat =
false; System.out.print(“[” + count + "] “); for (int i = 0; i <
mi.model().length; i++) { System.out.print(mi.model()[i] + " “); }
System.out.println(””); // Call mi.model() to be sure you iterate to the next
solution mi.model(); count++; } if (unsat) {
System.out.println(“Unsitisfied”); } } catch (TimeoutException e) {
System.out.println(“Timeout”); } catch (FileNotFoundException e) {
System.out.println(“File not found”); } catch (IOException e) {
System.out.println(“IO Exception”); } catch (ParseFormatException e) {
System.out.println(“ParseFormatException”); } catch (ContradictionException e)
{ System.out.println(“Contradiction”); } catch (java.lang.NullPointerException
e) { System.out.print(“NullPointerException”); } } }

上面一段代码不知道如何,一直报NULL Point Exception. 最后发现并非是代码写错,而是因为jre不对。需要使用opensdk-1.6。

然后:

java

然后:

java

选中java-opensdk1.6 然后在外面选中刚才的JavaSE-1.6 :

有时候eclipse报出Class Not Found错误,可能是因为jar包应该放在external
jar的地方,但是你却放错了位置。添加external jar的地方。如果想添加external jars,需要在:

选中propertise,然后:

左边add external jars, 添加需要的jar即可。

如果发生了selection dose not contain a main type,
那么就需要重新创建一个Project,然后将你的文件再重新导入到新的Project中。或者粘贴过去。不知道为什么eclipse经常发生这个错误。

上面一个XMLCSPReader的各种jar文件需要在sat4j.org 上下载。该下模块的都下,但是注意版本号。

if you will throw something, you should catch it as the same type. like following:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
int main(){
try{
throw 20;
}catch(int i){
cout &lt;&lt; "Exception Num is NO."&lt;&lt;i&lt;&lt;endl;
}
try{
throw 'X';
}catch(char c){
cout &lt;&lt; "this exception is a char:"&lt;&lt;c&lt;&lt;endl;
}

try{
throw "abc";
}catch(const char * e){
cout &lt;&lt; "this is string exception:"&lt;&lt;e&lt;&lt;endl;
}

try{
int *d = new int(65);
throw d;
}catch(const int * e){
cout &lt;&lt; "this is int point exception:"&lt;&lt;*e&lt;&lt;endl;
}
/* ok, catch will handle everything, if you throw correct type.*/
}

and if you want create classes for exceptions. You should add #include<exception> and inherit exception class, and then override the function “what”.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include&lt;iostream&gt;
#include&lt;exception&gt;
using namespace std;

/// this exception class is from #include&lt;exception&gt;
/// you should override the function what() to generate your exception string
class MyException: public exception{
virtual const char* what() const throw(){
return "myExceptions!!!!!!!";

}

};

class SubException: public MyException{
virtual const char* what()const throw(){
return "sub exception !!!!!!";
}

};

int main(){
try{
throw MyException();
}catch(exception&amp; e){
cout &lt;&lt; e.what()&lt;&lt;endl;

}
try{
throw SubException();
}catch(bad_alloc&amp;){
// this will not occur, just test this type.
// if it is occured, your computer will be locked.
cout &lt;&lt; "nothing"&lt;&lt;endl;
}catch(exception&amp; e){
cout &lt;&lt; e.what()&lt;&lt;endl;

}

}

There are some standard exceptions in exception.h. These exceptions are:

bad_alloc

A bad_alloc is thrown by new if an allocation failure occurs.

bad_cast

A bad_cast is thrown by dynamic_cast when it fails with a referenced type.

bad_exception

A bad_exception is thrown when an exception type doesn’t match any catch

bad_typeid

A bad_typeid is thrown by typeid

ios_base::failure

An ios_base::failure is thrown by functions in the iostream library.

in #include<stdexecpt> can use these exception:
class logic_error; // : public exception
class domain_error; // : public logic_error
class invalid_argument; // : public logic_error
class length_error; // : public logic_error
class out_of_range; // : public logic_error
class runtime_error; // : public exception
class range_error; // : public runtime_error
class overflow_error; // : public runtime_error
class underflow_error; // : public runtime_error

If you don’t know which kind of exception will occur. you should use catch(…)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
try{
srand(time(NULL));
int i = rand()%4;

switch(i){
case 0:
throw; // terminate called without an active exception
// Aborted, ... will not catch it.
break;
case 1:
throw 'x';
break;
case 2:
throw 50;
break;
case 3:
throw "my string";
break;
default:
break;

}

}catch(...){
cout &lt;&lt; "I don't know which exception will occur!"&lt;&lt;endl;
}

But when i == 0, the program will execute throw;, and it will exit and print:

terminate called without an active exception

Aborted


You should specify something to throw. throw; is only be used within catch clauses.

1
2
3
4
5
6
7
8
9
try{
try{
throw 2;
}catch(int i){
throw; // here I use it again!
}
}catch(...){
cout &lt;&lt; "re-throw it!!!!"&lt;&lt;endl;
}

you can declare your functions using throw(). But it is just declare!  you can throw everything! But you declare it will throw bad_exception, and use set_unexpected(), it will process some unexpected exceptions.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void foo() throw(int,bad_exception){

throw "abc";
}
void myunexpected(){
cout &lt;&lt; "I get unexpected exceptions!"&lt;&lt;endl;
throw;
}

// in main

set_unexpected(myunexpected);
try{
foo();
}catch(int){
cout &lt;&lt; "catch a integer"&lt;&lt;endl;
}catch(bad_exception&amp;){
cout &lt;&lt; "bad_exception"&lt;&lt;endl;
}
// you can use catch(...)

output is

I get unexpected exceptions! bad_exception
If the program or your function can not process some kind of situation. you should throw something out.  Sometime, someone argued that it will reduce the usability. But If you don't stop the processing(program or function), it will create a disaster.  Remember, by all means, throw it! But should we catch those exceptions and how we catch those? e....as your wish. Some bug will not appear, if you use not appropriate catch and process those exceptions in unsuitable way. If your program have some bug, and it is difficult to find, please delete all catches!

In some languages which have finally clauses. But in c++, it dose not have finally clauses.

0%