我希望每次都将数组中的一个元素向右移,同时在C#中将原始元素按特定顺序保留。
好的,所以我被要求重新编写我能理解的代码,为什么这样我们去:
我的号码可能是48390
//the ar elements have been commented out to show that we never know what ar contains but only the that I will always want to shift; ar[4]
int[] ar = new int[5];
//ar[0] = 4
//ar[1] = 8
//ar[2] = 3
//ar[3] = 9
//ar[4] = 0
while(ar != 04839)
{
Shift code
}
如果您注意到相同的数字但是一个数字输出,我可能会输入5个数字48390。我想要一个while循环旋转4 ar [1]移动直到数字形成04839
我希望这是有道理的。我发布这个问题是因为大多数页面基于将所有元素向右移动而发布有关移位的信息,而我只想转移一个特定元素。
感谢您的光临。
编辑:我应该更具体一点。如果你不知道每个数组元素是什么怎么办?所以我不能依赖“0”作为锚点。因为另一组数字可能包括另一个数字,例如“00238”。
答案 0 :(得分:2)
此方法将为您提供一系列数组,这些数组是通过将单个元素插入到给定数组中的每个位置(之间)而生成的:
public static IEnumerable<T[]> InsertElementBetweenAllPositions<T>(
T[] array, T element)
{
int newLength = array.Length + 1;
for (int i = 0; i < newLength; i++)
{
T[] rtn = new T[newLength];
rtn[i] = element;
Array.Copy(array, 0, rtn, 0, i);
Array.Copy(array, i, rtn, i + 1, array.Length - i);
yield return rtn;
}
}
对于您的示例,您可以将其称为
foreach (int[] arr in InsertElementBetweenAllPositions(new[] { 6, 7, 8, 9 }, 0))
{
foreach (int i in arr)
Console.Write(i + " ");
Console.WriteLine();
}
答案 1 :(得分:1)
您的示例中的内容是交换,可以实现如下:
private void Swap(ref int[] array, int index1, int index2)
{
int temp = array[index1];
array[index1] = array[index2];
array[index2] = temp;
}
调用Swap(ref source, 0, 1)
会交换第一个和第二个元素。你想要的是:
for (int i = 0; i < a.Length-1; i++)
{
Swap(ref a, i, i+1);
}
这会“冒泡”第一个元素,直到每次迭代的最后一个位置。
答案 2 :(得分:1)
这个怎么样:
List<int> l = new List<int>(){0,6,7,8,9};
for (int i=1;i<5;i++)
{
l.Remove(0);
l.Insert(i, 0);
}
答案 3 :(得分:1)
从示例中你需要移动元素,这个例子有点令人困惑,你是否需要再次将它们循环到开头。我已经提供了下面的示例,它将循环到开头 - 如果您不需要这样做,您可以重新编写if语句。
private int[] Shift(int[] a)
{
int zeroPos = Array.IndexOf(a, 0);
int[] rtn = new int[a.Length];
a.CopyTo(rtn, 0);
if (zeroPos + 1 == a.Length)
{
rtn[0] = 0;
for (int i = 0; i < a.Length - 1; i++)
{
rtn[i + 1] = a[i];
}
}
else
{
rtn[zeroPos] = rtn[zeroPos + 1];
rtn[zeroPos + 1] = 0;
}
return rtn;
}
答案 4 :(得分:0)
您是否考虑过使用LinkedList?链表数据结构可能比数组更适合您尝试的操作。 AddFirst,AddLast,AddAfter和AddBefore方法允许您以比每次重新组织数组更有效的方式将元素插入列表。
链表的缺点是您需要按顺序读取元素。因此,插入/删除元素非常有效,但随机访问元素效率低下。
对LinkedLists here有一个很好的概述。
答案 5 :(得分:0)
r=ar[0];
for (int i = 0; ar.lenght;i++)
{
ar[i]=ar[i + 1];
}
ar[ar.lenght] = r;
答案 6 :(得分:0)
也许
int oldLast = ar[ar.Length - 1];
for (int i = ar.Length - 1; i >= 0; i--)
ar[i] = i == 0 ? oldLast : ar[i - 1];
答案 7 :(得分:0)
它只是一个项目的排列,下面是排列算法的完整源代码。
static List<string> Put(char s1, string list)
{
List<string> str =new List<string>();
for (int i = 0; i < list.Length+1; i++)
{
string s = list.Substring(0, i) + s1.ToString() + list.Substring(i);
str.Add(s);
}
return str;
}
static List<string> Permute(string list,int x)
{
List<string> Result = new List<string>();
if (list.Length == 1)
{
Result.Add(list[0].ToString());
return Result;
}
else
{
char first = list[0];
list = list.Substring(x+1);
List<string> part = Permute(list,0);
foreach (string str in part)
{
List<string> hasBeenPlaced = Put(first, str);
foreach (string str2 in hasBeenPlaced)
{
Result.Add(str2);
}
}
}
return Result;
}
static void Main(string[] args)
{
List<string> per = Permute("abc",0);
for (int i = 0; i < per.Count; i++)
{
Console.WriteLine(per[i]);
}
Console.ReadKey();
}
现在,如果我在foreach之后添加一个休息时间,那么问题就解决了。 (它会为你想要的一个项目写出所有的遗留物,而不是全部......) 所以改为:
foreach (string str in part)
{
List<string> hasBeenPlaced = Put(first, str);
foreach (string str2 in hasBeenPlaced)
{
Result.Add(str2);
}
break;
}
希望能帮到你
答案 8 :(得分:0)
如果你是linq,那很简单:-)但是你需要一个比数组更大的尺寸。
ShiftLeft(ar, 1);
private static int[] ShiftLeft(int[] value, int countOfShift = 1)
{
var length = value.Length;
if (countOfShift > length)
{
throw new InvalidOperationException("countOfShift must less then value's length.");
}
var tempList = new List<int>(value);
tempList.RemoveRange(length - countOfShift, countOfShift);
tempList.InsertRange(0, value.Skip(length - countOfShift));
return tempList.ToArray();
}