1. 程式人生 > >面試算法總結

面試算法總結

打印 class clas pda nod b- mergesort 算法題 思想

#include <assert.h>
#include <string.h>
#include <stack>

//////////////////////////////////////////////////////////////////////////
// C++ 經典面試算法題

//1.實現strcpy.
char* MyStrCpy( char *pDest, const char *pSrc )
{
if( nullptr == pDest || nullptr == pSrc )
{
return nullptr;
}
if( pDest == pSrc )
{
return pDest;
}
char *pIter = pDest;
while( ( *pIter++=*pSrc++ ) !=‘\0‘ );
return pDest;
}

//2.實現strcat.
char* MyStrCat( char *pDest, const char *pSrc )
{
if( nullptr == pDest || nullptr == pSrc )
{
return nullptr;
}

char *pIter = pDest + strlen( pDest );
while( ( *pIter++=*pSrc++ ) != ‘\0‘ );
return pDest;
}

//3.實現CString字符串類缺省四個方法
class MyCString
{
public:

MyCString( char *pData = nullptr )
{
if( nullptr == pData )
{
mpData = new char[ 1 ];
assert( nullptr != mpData );
*mpData = ‘\0‘;
}
else
{
mpData = new char[ strlen( pData ) + 1 ];
assert( nullptr != mpData );
strcpy( mpData, pData );
}
}

MyCString( const MyCString &Other )
{
mpData = new char[ strlen( Other.mpData ) + 1 ];
assert( nullptr != mpData );
strcpy( mpData, Other.mpData );
}

~MyCString()
{
if( nullptr != mpData )
{
delete [] mpData;
mpData = nullptr;
}
}

const MyCString& operator =( const MyCString &Other )
{
if( this == &Other )
{
return *this;
}
delete [] mpData;
mpData = new char[ strlen( Other.mpData ) + 1 ];
assert( nullptr != mpData );
strcpy( mpData, Other.mpData );
return *this;
}

private:

char *mpData;
};

//4.不使用第三個變量交換兩個數的值
void SwapA( int &A, int &B )
{
if( A == B )
{
return;
}
A = A + B;
B = A - B;
A = A - B;
}
void SwapB( unsigned int &A, unsigned int &B )
{
if( A == B )
{
return;
}
A = A ^ B;
B = A ^ B;
A = A ^ B;
}

//5.C語言中字符串轉數字的方法是什麽( atoi ),請實現它
int Myatoi( const char *pString )
{
assert( nullptr != pString );
const int Len = strlen( pString );
int Value = 0;
int Times = 1;
for( int i = Len -1; i >= 0; --i, Times *= 10 )
{
Value += ( pString[ i ] - ‘0‘ ) * Times;
}
return Value;
}

//6.實現一個將字符串逆序的方法
char* MyInverted( char *pDest )
{
assert( nullptr != pDest );
const int Len = strlen( pDest );
char T = 0;
for( int i = 0; i < Len / 2; ++i )
{
T = pDest[ i ];
pDest[ i ] = pDest[ Len - i - 1 ];
pDest[ Len - i -1 ] = T;
}
return pDest;
}

//7.實現一個將字符串中所有字母轉換為大寫的方法
char* MyUpper( char *pDest )
{
assert( nullptr != pDest );
for( char *i = pDest; *i != ‘\0‘; ++i )
{
if( *i < ‘a‘ || *i > ‘z‘ )
{
continue;
}
*i -= ‘a‘ - ‘A‘;
}
return pDest;
}

//8.已知一個數組已經降序排序請用二分查字法找到其中的某個元素找到返回索引否則返回-1
int BinarySearch( int *pArray, int Count, int Value )
{
assert( nullptr != pArray );
int Left = 0;
int Right = Count -1;
int Mid = 0;
while( Left <= Right )
{
Mid = ( Left + Right ) / 2;
if( Value < pArray[ Mid ] )
{
Right = Mid - 1;
}
else if( Value > pArray[ Mid ] )
{
Left = Mid + 1;
}
else
{
return Mid;
}
}
return -1;
}

struct Node
{
Node *mpNext;
int mData;
};
//9.刪除鏈表中值為Value的所有元素( [Head]->[node1]->[node2]->...[noden] )
void DeleteFromList( Node *pHead, int Value )
{
Node *pPrev = pHead;
Node *pNext = pHead->mpNext;
while( nullptr != pNext )
{
if( pNext->mData != Value )
{
pPrev = pNext;
pNext = pNext->mpNext;
}
else
{
pPrev->mpNext = pNext->mpNext;
delete pNext;
pNext = pPrev->mpNext;
}
}
}

//10.在鏈表Index位置插入新的值為Value的元素
void InsertFromList( Node *pHead, int Index, int Value )
{
Node *pIter = pHead;
for( int i = 0; i < Index && nullptr != pIter; ++i, pIter = pIter->mpNext );
assert( nullptr != pIter );
Node *pNew = new Node;
pNew->mData = Value;
pNew->mpNext = pIter->mpNext;
pIter->mpNext = pNew;
}

//11.將鏈表逆序
Node* InvertedFromList( Node *pHead )
{
//A->B->C
Node *pPrev = pHead; //A
Node *pNext = pHead->mpNext; //B
Node *pNextNext = nullptr; //C
while( nullptr != pNext )
{
pNextNext = pNext->mpNext; //C = B->C
pNext->mpNext = pPrev; //B->A

pPrev = pNext; //A = B
pNext = pNextNext; //B = C
}
pHead->mpNext = nullptr;//C->B->A->null
return pPrev; //return C( new head )
}

//12.判斷X年X月X日是這年的第幾天
int GetDay( int Year, int Month, int Day )
{
int MonthDays[ 13 ] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

if( ( Year % 4 == 0 && Year % 100 != 0 ) || ( Year % 400 == 0 ) )
{
++MonthDays[ 2 ];
}

int Days = 0;
for( int i = 1; i < Month; ++i )
{
Days += MonthDays[ i ];
}
Days += Day;

return Days;
}
//13.求斐波拉契數列第N項
int GetFibonacci1( int N )
{
if( 1 == N || 2 == N )
{
return 1;
}
if( 3 == N )
{
return 2;
}
int A = 2;
int B = 3;
int C = 5;
for( int i = 0; i < N - 4; ++i )
{
C = A + B;
A = B;
B = C;
}
return C;
}

//14.遞歸求斐波拉契數列數列第N項
int GetFibonacci2( int N )
{
if( 1 == N || 2 == N )
{
return 1;
}
return GetFibonacci2( N - 1 ) + GetFibonacci2( N - 2 );
}
//15.實現一個產生[N-M]區間數字的隨機方法
int GetRandomRange( int N, int M )
{
if( N == M )
{
return N;
}
if( N > M )
{
N = N + M;
M = N - M;
N = N - M;
}
return N + ( rand() % ( M - N + 1 ) );
}

//16.實現一個產生[0~1]之間的隨機浮點數
double GetRandomRange()
{
return rand() / static_cast< double >( RAND_MAX );
}
//17.實現一個打印出1-1000之間的所有素數的方法
void PrintfPrime()
{
//1不是素數
//2是最小非奇數素數
//直接從3開始
printf( "2\n" );
bool b = false;
for( int i = 3; i <= 1000; ++i )
{
b = true;
for( int j = 2; j <= i / 2; ++j )
{
if( i % j == 0 )
{
b = false;
break;
}
}
if( b )
{
printf( "%d\n", i );
}
}
}

//18.已知Z = X + Y 其中 Z, X, Y 均為無符號int型 定義一個宏判斷Z是否已經越界
#define IS_OVER_FLOW( Z, X, Y ) ( Z < ( ( X ) < ( Y ) ? ( Y ) : ( X ) ) )

//19.請用棧實現隊列
int QueuePop( std::stack< int > &StackA )
{
std::stack< int > StackB;
while( false == StackA.empty() )
{
StackB.push( StackA.top() );
StackA.pop();
}

const int top = StackB.top();
StackB.pop();

while( false == StackB.empty() )
{
StackA.push( StackB.top() );
StackB.pop();
}
return top;
}

//20.已知X班X成績0-100分編寫一個方法實現0-59打印不合格,60-69打印合格,70-79打印良好,80-100打印優秀
//不能使用if,:?,switch
void PrintScore( int Score )
{
assert( Score >= 0 && Score <= 100 );
const char *pString[] =
{
"不合格",
"不合格",
"不合格",
"不合格",
"不合格",
"不合格",
"合格",
"良好",
"優秀",
"優秀",
"優秀",
};
printf( "%s\n", pString[ Score / 10 ] );
}
//21.實現strncpy
char *Mystrncpy( char *pDest, const char *pSrc, int Count )
{
assert( NULL != pDest && NULL != pSrc );
if( pDest == pSrc )
{
return pDest;
}
if( Count <= 0 )
{
return pDest;
}
char *pStart = pDest;
while( ( Count-- ) > 0 && ( *pStart++=*pSrc++ ) );
*pStart = ‘\0‘;
return pDest;
}
//22.C語言中數字轉字符串的方法是什麽?(itoa)請實現他
char* Myitoa( char *pDest, int val, int radix )
{
assert( NULL != pDest );
assert( radix > 1 );
const bool IsMinu = val < 0;
char buffer[ 16 ] = {};
int count = 0;

do
{
buffer[ count++ ] = abs(val) % radix;
val /= radix;
}
while( val );


if( IsMinu )
{
pDest[ 0 ] = ‘-‘;
for( int i = 0; i < count; ++i )
{
pDest[ i + 1 ] = ‘0‘ + buffer[ count - i - 1 ];
}
pDest[ count + 1 ] = ‘\0‘;
}
else
{
for( int i = 0; i < count; ++i )
{
pDest[ i ] = ‘0‘ + buffer[ count - i - 1 ];
}
pDest[ count ] = ‘\0‘;
}
return pDest;
}
//23.如何判斷鏈表是否有環
bool IsLoop( Node *pHead )
{
//[H->A->B->C->A]
assert( NULL != pHead );
Node *pNext = pHead->mpNext;
Node *pNextNext = pHead->mpNext;
while( NULL != pNext && NULL != pNextNext->mpNext )
{
pNext = pNext->mpNext;//[ B、C、A ]
pNextNext = pNextNext->mpNext->mpNext;//[C、B、A]
if( pNext == pNextNext )
{
return true;
}
}
return false;
}
//24.統計出一個字符串每種字母出現的次數要求時間復雜度為O(n)
void CountLetter( const char *pSrc )
{
int count[ 256 ] = {};
for( ; *pSrc !=‘\0‘; ++pSrc )
{
const char &c = *pSrc;
if( ( c < ‘A‘ || c > ‘z‘) && ( c < ‘a‘ || c > ‘z‘ ) )
{
continue;
}
++count[ c ];
}
}
//25.選擇排序的思想是什麽?( 每次找到最大或最小的值放在數組的低位上 )請實現它
void SelectSort( int *pArray, int count )
{
for( int i = 0; i < count; ++i )
{
//默認低位元素最小
int MinValue = pArray[ i ];
//默認保存低位元素的索引
int MinIndex = i;
//除開第一個元素找是否還有比它還小的元素( 升序 )
for( int j = i + 1; j < count; ++j )
{
//發現找到比它還小的元素重新賦值和保存索引
if( pArray[ j ] < MinValue )
{
MinValue = pArray[ j ];
MinIndex = j;
}
}
//將找到最小元素放在數組低位上面
const int Temp = pArray[ i ];
pArray[ i ] = MinValue;
pArray[ MinIndex ] = Temp;
}
}

//26.冒泡排序的思想是什麽?(升序排序中越小的數往低位走,越大的數往高位走,每次與相鄰元素比較導致的特點)請實現它
void BubbleSort( int *pArray, int count )
{
//eg.[6][8][8][0][9][1]
//i = 0,j < 5 [6][8][0][8][1][9]
//i = 1,j < 4 [6][0][8][1][8][9]
//i = 2,j < 3 [0][6][1][8][8][9]
//i = 3,j < 2 [0][1][6][8][8][9]

//到此為止已經排序OK了
//i = 4,j < 1 [0][1][6][8][8][9]
//i = 5,j < 0 [0][1][6][8][8][9]
for( int i = 0; i < count; ++i )
{
for( int j = 0; j < count - i - 1; ++j )
{
if( pArray[ j ] > pArray[ j + 1 ] )
{
const int Temp = pArray[ j ];
pArray[ j ] = pArray[ j + 1 ];
pArray[ j + 1 ] = Temp;
}
}
}
}

//27.已知兩個數組有序實現一個方法將他們合並後任然有序
void MergeSort( int *pMerge, int *p1, int p1len, int *p2, int p2len )
{
assert( nullptr != pMerge && nullptr != p1 && nullptr != p2 );
int i = 0;
int j = 0;
int k = 0;
while( i < p1len && j < p2len )
{
if( p1[ i ] < p2[ j ] )
{
pMerge[ k ] = p1[ i ];
++k;
++i;
}
else
{
pMerge[ k ] = p2[ j ];
++k;
++j;
}
}
while( i < p1len )
{
pMerge[ k ] = p1[ i ];
++k;
++i;
}
while( j < p2len )
{
pMerge[ k ] = p2[ j ];
++k;
++j;
}
}

//28.實現一個算法找到數組中第二大的數
int FindSec( int *p, int len )
{
assert( nullptr != p );
int maxv = p[ 0 ];
int secv = p[ 0 ];
for( int i = 1; i < len; ++i )
{
if( maxv < p[ i ] )
{
secv = maxv;
maxv = p[ i ];
}
}
return secv;
}

面試算法總結