寫程式 大概有1/3時間 或更多是在debug
debug的工具非常重要(除此之外test case也很重要)
我認為一個成熟的程式需要經過相當多的測試
聽一個老師說過在台灣測試工程師都是菜鳥,但國外相反
反而測試的人相當重要( 這點我相當同意 )
用visual studio有提供相當方便的debug 工具( 唉 人總是會想往安逸的道路走 )
雖然GDB也很好用 但實在是不夠user friendly
IDE整合開發式環境 還是有其存在的必要的 !
ACM 101 第二次就過了,有兩個秘訣 1. 先找Test Case自己測試 2. 多用Debugger
// ACM101.cpp: 主要專案檔。
#include
using namespace std;
class Block {
public:
Block( int i )
{
myNum = i;
CurrentNum = i;
Nstacks = 0;
Stacks = new Block*[ 24 ];
MyBase = this;
}
void ReturningMe() {
CurrentNum = myNum;
Nstacks = 0;
MyBase = this;
}
void ReturningStacks() {
for( int i = 0; i < Nstacks; ++i ) {
Stacks[ i ]->ReturningMe();
}
Nstacks = 0;
}
void StackLeave(bool MeLeave) {
if ( MyBase != this ) {
MyBase->Nstacks -= ( ( int )MeLeave + Nstacks );
for( int i = 0; i <>Nstacks; ++i ) {
if( MyBase->Stacks[ i ] == this ) break;
MyBase->Stacks[ i ]->Nstacks -= ( ( int )MeLeave + Nstacks );
}
}
}
int myNum;
int CurrentNum;
int Nstacks;
Block **Stacks;
Block *MyBase;
};
struct instruction {
char action[5];
char style[5];
int a;
int b;
};
bool Parse(struct instruction &o) {
cin >> o.action;
if( !strcmp( o.action, "quit" ) ) return false;
cin >> o.a;
cin >> o.style;
cin >> o.b;
return true;
};
/* move onto */
bool operator-( Block &a, Block &b )
{
// puts block a onto block b after returning any blocks that are stacked on top of blocks a and b to their initial positions.
a.StackLeave(true);
a.ReturningStacks();
b.StackLeave(false);
b.ReturningStacks();
a.CurrentNum = b.CurrentNum;
a.MyBase = b.MyBase;
b.Nstacks = 1;
b.Stacks[ 0 ] = &a;
if( b.MyBase != &b ) {
b.MyBase->Nstacks += 1;
b.MyBase->Stacks[ b.MyBase->Nstacks - 1 ] = &a;
for( int i = 0; i <>Nstacks; ++i ) {
if( b.MyBase->Stacks[ i ] == &b ) break;
b.MyBase->Stacks[ i ]->Nstacks += 1;
b.MyBase->Stacks[ i ]->Stacks[ b.MyBase->Stacks[ i ]->Nstacks - 1 ] = &a;
}
}
return true;
}
/* move over */
bool operator-=( Block &a, Block &b )
{
// puts block a onto the top of the stack containing block b, after returning any blocks that are stacked on top of block a to their initial positions.
a.StackLeave(true);
a.ReturningStacks();
a.CurrentNum = b.CurrentNum;
a.MyBase = b.MyBase;
for( int i = 0; i < b.Nstacks; ++i ) {
b.Stacks[ i ]->Nstacks += 1;
b.Stacks[ i ]->Stacks[ b.Stacks[ i ]->Nstacks - 1 ] = &a;
}
b.Nstacks += 1;
b.Stacks[ b.Nstacks - 1 ] = &a;
if ( b.MyBase != &b ) {
b.MyBase->Nstacks += 1;
b.MyBase->Stacks[ b.MyBase->Nstacks - 1 ] = &a;
for( int i = 0; i <>Nstacks; ++i ) {
if( b.MyBase->Stacks[ i ] == &b ) break;
b.MyBase->Stacks[ i ]->Nstacks += 1;
b.MyBase->Stacks[ i ]->Stacks[ b.MyBase->Stacks[ i ]->Nstacks - 1 ] = &a;
}
}
return true;
}
/* pile onto */
bool operator|( Block &a, Block &b )
{
// moves the pile of blocks consisting of block a, and any blocks that are stacked above block a, onto block b. All blocks on top of block b are moved to their initial positions prior to the pile taking place. The blocks stacked above block a retain their order when moved.
a.StackLeave(true);
b.StackLeave(false);
b.ReturningStacks();
a.CurrentNum = b.CurrentNum;
a.MyBase = b.MyBase;
for( int i = 0; i < a.Nstacks; ++i ) {
a.Stacks[ i ]->CurrentNum = b.CurrentNum;
a.Stacks[ i ]->MyBase = b.MyBase;
}
b.Nstacks = 1;
b.Stacks[ 0 ] = &a;
for( int i = 0; i < a.Nstacks; ++i ) {
b.Nstacks += 1;
b.Stacks[ b.Nstacks - 1 ] = a.Stacks[ i ];
}
if( b.MyBase != & b ) {
b.MyBase->Nstacks += 1;
b.MyBase->Stacks[ b.MyBase->Nstacks - 1 ] = &a;
for( int i = 0; i < a.Nstacks; ++i ){
b.MyBase->Nstacks += 1;
b.MyBase->Stacks[ b.MyBase->Nstacks - 1 ] = a.Stacks[ i ];
}
for( int i = 0; i <>Nstacks; ++i ) {
if( b.MyBase->Stacks[ i ] == &b ) break;
b.MyBase->Stacks[ i ]->Nstacks += 1;
b.MyBase->Stacks[ i ]->Stacks[ b.MyBase->Stacks[ i ]->Nstacks - 1 ] = &a;
for( int j = 0; j < a.Nstacks; ++j ) {
b.MyBase->Stacks[ i ]->Nstacks += 1;
b.MyBase->Stacks[ i ]->Stacks[ b.MyBase->Stacks[ i ]->Nstacks - 1 ] = a.Stacks[ j ];
}
}
}
return true;
}
/* pile over */
bool operator|=( Block &a, Block &b )
{
// puts the pile of blocks consisting of block a, and any blocks that are stacked above block a, onto the top of the stack containing block b. The blocks stacked above block a retain their original order when moved.
a.StackLeave(true);
a.CurrentNum = b.CurrentNum;
a.MyBase = b.MyBase;
for( int i = 0; i < a.Nstacks; ++i ) {
a.Stacks[ i ]->CurrentNum = b.CurrentNum;
a.Stacks[ i ]->MyBase = b.MyBase;
}
for( int i = 0; i < b.Nstacks; ++i ) {
b.Stacks[ i ]->Nstacks += 1;
b.Stacks[ i ]->Stacks[ b.Stacks[ i ]->Nstacks - 1 ] = &a;
for( int j = 0; j < a.Nstacks; j++ ) {
b.Stacks[ i ]->Nstacks += 1;
b.Stacks[ i ]->Stacks[ b.Stacks[ i ]->Nstacks - 1 ] = a.Stacks[ j ];
}
}
b.Nstacks += 1;
b.Stacks[ b.Nstacks - 1 ] = &a;
for( int i = 0; i < a.Nstacks; ++i ) {
b.Nstacks += 1;
b.Stacks[ b.Nstacks - 1 ] = a.Stacks[ i ];
}
if( b.MyBase != & b ) {
b.MyBase->Nstacks += 1;
b.MyBase->Stacks[ b.MyBase->Nstacks - 1 ] = &a;
for( int i = 0; i < a.Nstacks; ++i ){
b.MyBase->Nstacks += 1;
b.MyBase->Stacks[ b.MyBase->Nstacks - 1 ] = a.Stacks[ i ];
}
for( int i = 0; i <>Nstacks; ++i ) {
if( b.MyBase->Stacks[ i ] == &b ) break;
b.MyBase->Stacks[ i ]->Nstacks += 1;
b.MyBase->Stacks[ i ]->Stacks[ b.MyBase->Stacks[ i ]->Nstacks - 1 ] = &a;
for( int j = 0; j < a.Nstacks; ++j ) {
b.MyBase->Stacks[ i ]->Nstacks += 1;
b.MyBase->Stacks[ i ]->Stacks[ b.MyBase->Stacks[ i ]->Nstacks - 1 ] = a.Stacks[ j ];
}
}
}
return true;
}
int main()
{
int Num_Block;
struct instruction ReadIn;
cin >> Num_Block;
Block **Blocks = new Block*[ Num_Block ];
for( int i = 0; i < Num_Block; ++i ) {
Blocks[ i ] = new Block( i );
}
bool Valid;
while( Parse( ReadIn ) ) {
Valid = true;
if( ReadIn.a == ReadIn.b ) Valid = false;
for( int i = 0; i <>Nstacks; ++i ) {
if( Blocks[ ReadIn.a ]->Stacks[ i ]->myNum == ReadIn.b ) {
Valid = false;
break;
}
}
for( int i = 0; i <>Nstacks; ++i ) {
if( Blocks[ ReadIn.b ]->Stacks[ i ]->myNum == ReadIn.a ) {
Valid = false;
break;
}
}
if( Valid == false ) continue;
if( strcmp( ReadIn.action, "move" ) == 0 ) {
if( strcmp( ReadIn.style, "onto" ) == 0 ) {
*Blocks[ ReadIn.a ] - *Blocks[ ReadIn.b ];
}else if(strcmp( ReadIn.style, "over" ) == 0 ) {
*Blocks[ ReadIn.a ] -= *Blocks[ ReadIn.b ];
}
}else if( strcmp( ReadIn.action, "pile" ) == 0 ) {
if( strcmp( ReadIn.style, "onto" ) == 0 ) {
*Blocks[ ReadIn.a ] | *Blocks[ ReadIn.b ];
}else if(strcmp( ReadIn.style, "over" ) == 0 ) {
*Blocks[ ReadIn.a ] |= *Blocks[ ReadIn.b ];
}
}
/*
//Debug
for( int i = 0; i < Num_Block; ++i ) {
cout << i << ":" ;
for( int j = 0; j < Num_Block; ++j ) {
if( Blocks[ j ]->CurrentNum == i && Blocks[ j ]->MyBase == Blocks[ j ] ) {
cout << " " <<>myNum;
for( int k = 0; k < ( Blocks[ j ]->Nstacks ); ++k ) {
cout << " " <<>Stacks[ k ]->myNum;
}
break;
}
}
cout << endl;
}*/
}
for( int i = 0; i < Num_Block; ++i ) {
cout << i << ":" ;
for( int j = 0; j < Num_Block; ++j ) {
if( Blocks[ j ]->CurrentNum == i && Blocks[ j ]->MyBase == Blocks[ j ] ) {
cout << " " <<>myNum;
for( int k = 0; k < ( Blocks[ j ]->Nstacks ); ++k ) {
cout << " " <<>Stacks[ k ]->myNum;
}
break;
}
}
cout << endl;
}
system( "pause" );
return 0;
}
2007年11月8日 星期四
Debug的重要性
訂閱:
張貼留言 (Atom)
1 則留言:
程式分析設計工具 我想也很重要
但是不要過於迷戀 快樂最重要
在我心目中寫程式仍然是藝術
張貼留言