質問
最近のインタビューで、ある奇妙な質問が尋ねられました
a[]= { 1,2,3,4,5,6,7,8,9,10}
指定された開始インデックスで配列が指定された場合、走査するまでそれを反復する必要があります すべての要素。
つまり、開始インデックスが「5」であると仮定します。 6,7,8,9,10,5,4,3,2,1
から開始する必要があります。シーケンスを注意深く見てください。どのようにReset()を作成できますか。
現在、何とか...?。
ただし、インタビュアーは、要求どおりにシーケンスを実行しましたが、コードは表示しませんでした。
このような奇妙な要件のロジックを実際に開発できますか?
解決
2つのループを使用します。
IEnumerable<int> ForwardsBackwards(int[] a, int start) {
for(int i=start; i<a.Length; i++)
yield return a[i];
for(int i=start-1; i>=0; i--)
yield return a[i];
}
編集: linqでさらに良い:
IEnumerable<int> ForwardBackward(int[] a, int start) {
return a.Skip(start).Concat(a.Take(start).Reverse());
}
他のヒント
メンテナンスが簡単(?):
int[] a= {1,2,3,4,5,6,7,8,9,10};
int StartIndex=5;
for (int iCount = StartIndex; iCount < a.Count() + StartIndex; iCount++)
{
Debug.WriteLine(a[(iCount + a.Count()) % a.Count()]);
}
出力:
6 7 8 9 10 1 2 3 4 5
編集:シーケンスを見つけただけで、上限に達すると反転します。それが指定された質問であれば、それは厄介です。
これは古いスレッドですが、同じアルゴリズムが必要であり、素晴らしい解決策になりました。解決策
- 配列の任意の要素から開始できます
- 任意の方向への反復を開始できます
- NEXTから動きの方向にすべての要素を渡します
- 境界要素に到達すると、最初/最後に重なります
すべてのマジックは for ループ演算子を使用して1行で、他のコードはプレビューの利便性のためです。
// Example program
#include <iostream>
#include <string>
int a[] = {0,1,2,3,4,5};
int Count = sizeof(a)/sizeof(int);
void LoopFromMidWithDirection ( int curIdx , int motion )
{
std::cout << "\nNextFrom=" << curIdx << " motion =" << motion << "\n";
curIdx +=motion;
for (int i = curIdx; (i - curIdx) * motion < Count ; i += motion)
std::cout << a[(i + Count) % Count] << " ";
std::cout << "\n";
}
int main()
{
LoopFromMidWithDirection(4, +1);
LoopFromMidWithDirection(6, +1);
LoopFromMidWithDirection(0, -1);
}
出力
NextFrom=4 motion =1
5 0 1 2 3 4
NextFrom=6 motion =1
1 2 3 4 5 0
NextFrom=0 motion =-1
5 4 3 2 1 0
ソリューションは@Neil Kimberからインスピレーションを受けています
はい、 IEnumerator を実装する必要がありますカスタムクラスのインターフェイス。 MoveNextメソッドにロジックを記述して、配列の終わりを検出し、途中の開始点を記憶して、配列の先頭から開始します。
フォローこれらのコードサンプルテンプレート。
(DEFINE (traverse length start call)
(DEFINE (flow index motion)
(cond ((> index length)
(flow (- start 1) -1))
((> index -1)
((call index) (flow (+ index motion) motion)))))
(flow start +1))
(traverse 9 5 job)
質問の9対5の側面が好きです。彼らは何かをほのめかしていたのだろうか? job
が配列インデックスを出力すると仮定すると、678954321が生成されます。
Cでは、forループ(編集前にwhileループではなかった)を使用したくなるでしょう;
int a[]= { 1,2,3,4,5,6,7,8,9,10};
int length = 10;
int start = 5;
int motion = 1; //increment
for( int index = start; index >= 0; index += motion ) {
if(index > (length-1)) {
motion = -1; //decrement
index = start -1;
else {
printf("%d", a[index]);
}
}
プロセスは、ゼロインデックスを印刷した後にのみ終了します。配列を横断していないのは、それを超えたときだけです。その場合、開始インデックス(-1)に戻り、モーションを逆にします。