سؤال

في مقابلة أجراها مؤخرا واحد غريب سؤال تم طلب

a[]= { 1,2,3,4,5,6,7,8,9,10}

عند مجموعة معينة مع تحديد مؤشر البداية يجب تكرار ذلك حتى تجتاز جميع العناصر.

أعني لنفترض انطلاق مؤشر "5" يجب أن نبدأ من 6,7,8,9,10,5,4,3,2,1.يرجى النظر بعناية في تسلسل ، كيف يمكن للمرء أن إنشاء إعادة تعيين(), الحالي,إلخ,إلخ?.

ولكن المقابلة تنفيذ تسلسل ما سأل.وقال انه لم تظهر المدونة.

هل نحن حقا في تطوير منطق غريب مثل هذا الشرط ؟

هل كانت مفيدة؟

المحلول

ومجرد استخدام اثنين من الحلقات.

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. سوف تمر جميع العناصر بدءا من القادم في اتجاه الحركة
  4. سوف تتداخل الأول/الماضي عند الحدود عنصر وصلت

كل السحر في خط واحد مع بالنسبة حلقة المشغل, رمز آخر هو معاينة من الراحة.

// 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 

الحل هو وحي من @نيل كيمبر

نعم، يجب تنفيذ 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 سأكون يميل إلى استخدام لحلقة (ليس حلقة في حين كما كان عليه قبل تحرير)؛

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