【问题标题】:How to shift one array element wrap around?如何移动一个数组元素环绕?
【发布时间】:2011-04-17 19:00:52
【问题描述】:

我正在尝试编写一个遍历数组的函数,当它找到某种类型的值时,它会将其向右移动指定数量的位置。

我知道如何通过临时存储一个值来移动元素,将右侧元素向左移动,然后将临时值写入正确的位置。

我正在苦苦挣扎的一点是,如果某个字符出现在数组的末尾附近,我需要它环绕并从数组的开头继续,所以是循环的。

所以一个数组,例如,大写字母向右移动 3 位,特殊字符向左移动 1 位:

{ M, y, N, a, m, e, P} becomes...
{ y, M, P, a, N, m, e}

要将 8 的元素向右移动 3 个我在下面的位置,但这仅适用于 8 出现在数组末尾的 3 个元素之前并且不会回绕的情况。

输入数组:

{0, 1, 2, 3, 4, 5, 6, 7, **8**, 9}

想要的输出:

{0, **8**, 1, 2, 3, 4, 5, 6, 7, 9}
int[] array = new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

for (int i = array.Length - 1; i >= 0; i--) 
{
    if (array[i] == 8) 
    {
        int temp = array[i];
        int j = 0;
        for (j = i; j < i + 3; j++) 
        {
            array[j] = array[j + 1];
        }
        array[j] = temp;
    }
}

【问题讨论】:

  • 你到底有什么问题?
  • 它是我需要帮助的数组开头的延续,因此如果需要向右移动的元素显示为倒数第二个元素并且需要向右移动三它将最终成为数组中的第二个元素

标签: c# arrays shift circular-buffer


【解决方案1】:

只需使用模算术,以便在您移动时不要写入索引j 处的元素,而是写入索引j % array.Length 处的元素。因此:

public void FindAndShift<T>(T[] array, T value, int shift) {
    int index = Array.IndexOf(array, value);
    int shiftsRemaining = shift;
    for(int currentPosition = index; shiftsRemaining > 0; shiftsRemaining--) {
        array[currentPosition % array.Length] = array[(currentPosition + 1) % array.Length];
    }
    array[(index + shift) % array.Length] = value;
}

我已排除错误检查。

【讨论】:

  • 这似乎有效,非常感谢。我什至没有想到使用模数。谢谢
【解决方案2】:

您可以使用 if 语句来完成,检查数组末尾是否有足够的空间,如果没有,您还必须计算在数组开头移动多少步。

我还认为,您可以通过在进行移位时计算以数组长度为模的位置来做到这一点,我目前无法尝试,但我脑海中的逻辑表明它应该可以工作。

【讨论】:

  • 如果你头脑中的逻辑和杰森所说的一样,那么它确实有效:) 谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-24
  • 1970-01-01
  • 2021-07-16
  • 2012-08-25
  • 1970-01-01
相关资源
最近更新 更多