【问题标题】:Shifting vector elements to the right向右移动向量元素
【发布时间】:2016-09-01 02:50:59
【问题描述】:

我正在研究这个方法,它应该返回一个新的 Vector,其中的元素向右移动了给定数量的位置。例如:

[1 2 3 4] 0 => [1 2 3 4]

[1 2 3 4] 1 => [4 1 2 3]

[1 2 3 4] 2 => [3 4 1 2]

[1 2 3 4] 3 => [2 3 4 1]

[1 2 3 4] 4 => [1 2 3 4]

[1 2 3 4] 5 => [4 1 2 3]

我的代码正在处理一些输入,仅适用于 0、2 和 4,而 1 和 3 不起作用。

这是我的代码:

 public Vector shifted(int amount) {

    Vector v = new Vector(length);

    for (int i = 0; i < length; i++) {
        if (i + amount > length-1) {
             v.elements[i] = this.elements[(i+amount) % length];
        }
        else {
             v.elements[i] = this.elements[(i+ amount)];
        }
    }
    return v;
 }

【问题讨论】:

  • 你为什么使用Vector? Javadoc 说:建议使用ArrayList 代替Vector 为什么它是原始的?泛型是很久以前发明的。
  • 在我看来,您实际上是在向左移动而不是向右移动。这些是您在 1 和 3 中看到的结果吗?如果是这种情况,那么 0、2 和 4 将“发生”工作,因为 0 和 4 不进行任何移位,而 2 将移位数组的一半,因此无论您是否向左移位,它看起来都一样或对。我认为你应该用铅笔和纸试一试,看看v.elements 中的哪些索引是你分配给this.elements 中的哪些索引的。如果你这样做,你应该能够看到如何修复它。你很亲密。
  • 还是不行,你能帮帮我吗?请 ??我花了很多时间在上面
  • 您遇到的问题是您正在覆盖以后需要复制的值。

标签: java class arraylist vector


【解决方案1】:

这是一个可以处理amount 的任何值的工作版本。

public static <E> Vector<E> shifted(Vector<E> input, int amount) {
    if (input.isEmpty())
        return new Vector<>();
    int shift = (amount % input.size() + input.size()) % input.size();
    if (shift == 0)
        return new Vector<>(input);
    Vector<E> v = new Vector<>(input.size());
    v.addAll(input.subList(input.size() - shift, input.size()));
    v.addAll(input.subList(0, input.size() - shift));
    return v;
}

测试

Vector<Integer> input = new Vector<>(Arrays.asList(1,2,3,4));
for (int i = -5; i <= 5; i++)
    System.out.printf("%2d: %s%n", i, shifted(input, i));

输出

-5: [2, 3, 4, 1]
-4: [1, 2, 3, 4]
-3: [4, 1, 2, 3]
-2: [3, 4, 1, 2]
-1: [2, 3, 4, 1]
 0: [1, 2, 3, 4]
 1: [4, 1, 2, 3]
 2: [3, 4, 1, 2]
 3: [2, 3, 4, 1]
 4: [1, 2, 3, 4]
 5: [4, 1, 2, 3]

【讨论】:

  • 解释原始实现的问题比逐字提供可行的解决方案更有帮助。教人钓鱼等等。
【解决方案2】:

您应用的换档策略不正确。试着想想当i = 0amount = 1Vectorlength = 4 时会发生什么:您将位置0 的值分配给位置1,这与您想要实现的相反。

以下是您希望以采用Vector 和移位amount 的函数形式实现的示例:

public static Vector rightShiftVector(Vector v, int amount){
    int s = v.size();
    int a = (amount >= 0)?amount % s : amount % s + s; // or int a = (amount % s + s) % s
    Vector result = new Vector(s);
    for(int i = 0; i < s; i++){
        int p;
        if(i + a < s){
            p = i;
        }
        else{
            p = (i + a) % s;
        }
        result.insertElementAt(v.get(i), p);
    }

    return result;
}

【讨论】:

  • 仅供参考:解决方案非常简单。假设s 是4。对于较大的amount 值11,您使用% s 将其降低到3。一切都很好。对于 -9 的较大 值,% s 会将其降低到 -1,这意味着向左移动 1。但是左边的 1 和右边的 3 是一样的,所以+ s 把它变成了 3。太好了。所以添加if (a &lt; 0) a += s或: 始终使用a += s,但这会使正值过高,a %= s 也是如此,因为(a + s) % s == a 的正值是a。所有结合起来,您只需编写a = (amount % s + s) % s,您就可以处理amount 的所有值。
  • 感谢您的评论,安德烈亚斯。我只专注于正确的(积极的)转变。我也更新了处理负(左)移的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-05
  • 2019-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-18
  • 2019-12-26
相关资源
最近更新 更多