C# 从中间开始的数组迭代
在最近的一次采访中,有人问了一个奇怪的问题C# 从中间开始的数组迭代,c#,arrays,iterator,C#,Arrays,Iterator,在最近的一次采访中,有人问了一个奇怪的问题 a[]= { 1,2,3,4,5,6,7,8,9,10} 当一个数组具有指定的起始索引时,我必须迭代它,直到遍历为止 所有元素 我的意思是,假设起始索引为“5”,我必须从6,7,8,9,10,5,4,3,2,1开始, 电流,等等,等等 但是面试官按照他的要求执行了这个序列,他没有显示代码 我们真的可以为这种奇怪的需求开发逻辑吗?是的,您必须在自定义类上实现接口。将逻辑写入MoveNext方法,该方法检测数组的结尾,然后从数组的开头开始,记住中间的起始
a[]= { 1,2,3,4,5,6,7,8,9,10}
当一个数组具有指定的起始索引时,我必须迭代它,直到遍历为止
所有元素
我的意思是,假设起始索引为“5”,我必须从6,7,8,9,10,5,4,3,2,1
开始,
电流,等等,等等
但是面试官按照他的要求执行了这个序列,他没有显示代码
我们真的可以为这种奇怪的需求开发逻辑吗?是的,您必须在自定义类上实现接口。将逻辑写入MoveNext方法,该方法检测数组的结尾,然后从数组的开头开始,记住中间的起始点 以Microsoft为模板。只需使用两个循环即可
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];
}
IEnumerable ForwardsBackwards(int[]a,int start){
对于(int i=start;i=0;i--)
收益率a[i];
}
编辑:
使用linq更好:
IEnumerable<int> ForwardBackward(int[] a, int start) {
return a.Skip(start).Concat(a.Take(start).Reverse());
}
IEnumerable ForwardBackward(int[]a,int start){
返回a.Skip(start).Concat(a.Take(start).Reverse());
}
更易于维护(?):
int[]a={1,2,3,4,5,6,7,8,9,10};
int StartIndex=5;
对于(int-iCount=StartIndex;iCount
输出为:
六,
7.
8.
9
10
1.
2.
3.
4.
五,
编辑:刚刚发现了你的序列,当你达到上限时它会反转。如果这是一个明确的问题,那就太糟糕了
(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循环)
此过程仅在打印零索引后完成。唯一一次不遍历数组的时间是超出数组的时间。当这种情况发生时,您将返回开始索引(-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);
}
解决方案的灵感来自@Neil Kimber哦!抱歉,我认为这是一个无效的问题。我们可以实际实现它。我以为面试官问了一个令人讨厌的问题。我认为“更好”的LINQ版本实际上并没有那么好,因为它在数组上迭代了两次(IIRC,既不是
Skip
也不是Take
实现检查IList
以优化)。如果这是一个令人讨厌的问题,我需要去做一些采访。请不要提及输出错误的事实(您已经注意到),索引中的+a.Count()是redunant,因为您随后执行了%a.Count()。这正是我需要的,谢谢!我把它做得更进一步,使它在两个方向上工作,添加了“motion”变量。下面是解决方案。
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]);
}
}
// 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