質問

最近のインタビューで、ある奇妙な質問が尋ねられました

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

編集:シーケンスを見つけただけで、上限に達すると反転します。それが指定された質問であれば、それは厄介です。

これは古いスレッドですが、同じアルゴリズムが必要であり、素晴らしい解決策になりました。解決策

  1. 配列の任意の要素から開始できます
  2. 任意の方向への反復を開始できます
  3. NEXTから動きの方向にすべての要素を渡します
  4. 境界要素に到達すると、最初/最後に重なります

すべてのマジックは 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)に戻り、モーションを逆にします。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top