奇数の本が偶数の前にくるように配列の順序を調整します
トピック
整数配列を入力し、すべてのカウントが配列の前半にあり、すべての偶数が配列の後半にあるように、配列内の数値の順序を調整する関数を実装します。
初期分析
もちろん、最も簡単な方法は、配列を最初からスキャンすることです。偶数に遭遇するたびに、番号は最後に配置されます。つまり、番号の後の番号を前に移動する必要があります。
O(n)の数は偶数に遭遇するたびに移動するため、合計時間計算量はO(n ^ 2)です。
より良い方法
配列には奇数または偶数の2種類の数値しかないためです。それで、奇数の前に偶数が表示されているのを見つけたら、それらの順序を入れ替えても大丈夫ですか?
したがって、2つのポインターを維持する必要があります
。初期化時に最初の番号を指す最初のポインターは、後方にのみ移動できます。
2番目のポインタは、初期化されたときに最後の番号を指し、前方にのみ移動できます。
2つのポインターが出会う前に、最初のポインターが偶数で2番目のポインターが奇数の場合は、それらの位置を入れ替えます。
例えば
入力配列:{1、2、3、4、5}
プロセス:
1。最初に、最初のポインターは1を指し、2番目のポインターは5 2を指します
。1は奇数であるため、最初のポインターは偶数2を指すまで後方に移動します。
3.このとき、2番目のポインターは5を指しているため、スワップして両方が移動します。
4.次に、2つが出会うまで続けます
イラスト:
次のコードを取得できます:
void ReorderOddEven(int* pData,unsigned int length)
{
if(pData==nullptr || length==0)
return;
int* pBegin=pData;
int* pEnd=pData+length+1;
while(pBegin<pEnd)
{
//向后移动pBegin 直到它指向偶数
while(pBegin<pEnd && (*pBegin & 0x1)!=0)
pBegin++;
//向前移动pEnd 直到指向奇数
while(pBegin<pEnd && (*pEnd & 0x1)==0)
pEnd--;
if(pBegin<pEnd)
{
int temp=*pBegin;
*pBegin=*pEnd;
*pEnd=tmp;
}
}
}
拡張モジュラー処理
上記の問題は解決され、完璧に見えますが、同様の問題がある場合はどうなりますか?
質問:配列が正と負の2つの部分に分割され、負の数が非負の数の前にある場合、どのように対処しますか?
A:新しい関数を再定義するには、の判断条件を変更するだけです。 2番目と3番目のwhileループ。別の質問をします。2つの部分に分割すると、1つの部分は3で割り切れ、前の部分は3で割り切れず、後の部分は3で割り切れます。
もう一度答えてください:または、新しい関数を再定義して、もう一度変更してください...割り込み:停止して停止します。これ以上の方法はありませんか?
上記の質問を見ると、答えは間違っていないので、条件を変更するだけです。
しかし、上記は間違っています、これは上記だけです
変更が必要なのは単なる判断条件なので、毎回同じコードを繰り返す必要があるのはなぜですか?
残りのコードを再利用できないように、判断が必要な条件をカプセル化してみませんか?
そうです、正式な質問者が望んでいた答えです!
したがって、関数ポインターを導入し、上記のコードをロジックと操作の2つの部分に分割するだけで済みます。このように、多数の計算を繰り返すのではなく、毎回論理関数を書き直すだけで済み、再利用性が大幅に向上します。
void ReorderOddEven(int* pData,unsigned int length,bool (*func)(int))
{
if(pData==nullptr || length==0)
return;
int* pBegin=pData;
int* pEnd=pData+length+1;
while(pBegin<pEnd)
{
//向后移动pBegin 直到它指向偶数
while(pBegin<pEnd && !func(*pBegin))
pBegin++;
//向前移动pEnd 直到指向奇数
while(pBegin<pEnd && func(*pEnd) )
pEnd--;
if(pBegin<pEnd)
{
int temp=*pBegin;
*pBegin=*pEnd;
*pEnd=tmp;
}
}
}
bool IsEven(int n)
{
return (n&0x1)==0;
}
—————————————————————————————————————————————————— ————
参考書:「ソードフィンガーオファー」