[CareerCup] 14.6 CircularArray 环形数组

14.6 Implement a CircularArray class that supports an array-like data structure which can be efficiently rotated.The class should use a generic type, and should support iteration via the standard for (Obj o : CircularArray) notation.

这道题让我们实现一个环形数组类CircularArray,由于环形数组需要调用rotate(int shiftRight)函数,在这里,我们并不会真的去旋转数组,因为这样十分不高效。我们采用另一种实现方法,用一个变量head来记录环形数组的起始位置,那么调用rotate实际上就是改变head的位置而已。请参见如下代码:

public static class CircularArray<T> implements Iterable<T> {
    private T[] items;
    private int head = 0;

    public CircularArray(int size) {
        items = (T[]) new Object[size];
    }

    private int convert(int idx) {
        if (idx < 0) {
            idx += items.length;
        }
        return (head + idx) % items.length;
    }

    public void rotate(int shiftRight) {
        head = convert(shiftRight);
    }

    public T get(int i) {
        if (i < 0 || i >= items.length) {
            throw new java.lang.IndexOutOfBoundsException("...");
        }
        return items[convert(i)];
    }

    public void set(int i, T item) {
        items[convert(i)] = item;
    }

    public Iterator<T> iterator() {
        return new CircularArrayIterator<T> (this);
    }

    private class CircularArrayIterator<TI> implements Iterator<TI> {
        private int _current = -1;
        private TI[] _items;

        public CircularArrayIterator(CircularArray<TI> array) {
            _items = array.items;
        }

        @Override
        public boolean hasNext() {
            return _current < items.length - 1;
        }

        @Override
        public TI next() {
            ++_current;
            TI item = (TI) _items[convert(_current)];
            return item;
        }

        @Override
        public void remove() {
            throw new UnsupportedOperationException("...");
        }
    }
}

上述代码中主要有两部分:

1. 实现CircularArray类

实现的过程中容易犯一些错误,比如:

- 我们不能新建一个泛类的数组,我们必须cast数组或者定义类型为List<T>.

- 取余操作符%对于负数运算后会得到负数,这和数学家们定义的取余运算不同,所以我们需要给负数序列加上items.length,时期变为正数再做运算。

- 我们必须一致地保证将原序列转为旋转序列。

2. 实现迭代器Iterator接口

为了使用迭代来遍历数组for (Obj o : CircularArray),我们必须实现迭代器Iterator接口:

- 修改CircularArray<T>的定义,添加implements Iteratble<T>。这需要我们添加一个iterator()方法给CircularArray<T>。

- 建立CircularArrayIterator<T>类implements Iterator<T>,这需要我们实现CircularArrayIterator的一些方法,如hasNext(), next(), 和 remove()。

一旦我们实现了上面两项,for (Obj o : CircularArray)循环就会神奇的运行了。

时间: 2024-10-17 10:53:53

[CareerCup] 14.6 CircularArray 环形数组的相关文章

环形数组最大子数组的和及位置

题目: 求环形数组中最大子数组的和及位置. 实验思路: 环形数组中最大子数组的和包括两种情况 1.最大子数组和不包括连接处 设计思想见上篇 2.最大子数组和包括连接处 最大子数组的和=数组的和-最小子数组的和 程序代码: 1 #include <iostream> 2 using namespace std; 3 int main() 4 { 5 int Array[100]; //定义数组 6 int length; //数组长度 7 for(length=0;;) //输入数组 遇到Ent

数组连续最大子和及环形数组最大子和

问题1: /*求连续子数组的最大和: * 设curSum为当前子数组(ai, ai+1, ......, aj)的和 * sum存放到目前为止子数组和的最大值 * 1. cursum+ai>0; cursum=cursum+ai * 2. cursum+ai<=0; cursum=ai; */ 1 int maxsubarr(vector<int> &a) 2 { 3 if(a.size()==0) 4 return 0; 5 int sum=0x80000000; //s

二维环形数组求最大子数组和

一.要求 1.题目: 返回一个二维数组中最大子数组的和. 2.要求: 输入一个二维整形数组,数组里有正数也有负数. 二维数组首尾相接,象个一条首尾相接带子一样. 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和. 求所有子数组的和的最大值.要求时间复杂度为O(n). 3.结对开发要求: 两人结对完成编程任务. 一人主要负责程序分析,代码编程. 一人负责代码复审和代码测试计划. 发表一篇博客文章讲述两人合作中的过程.体会以及如何解决冲突(附结对开发的工作照). 二.设计思路 1.从键

用c++实现环形数组的最大子数组之和

思路: 把一维环形数组从某一段切开,然后转化为之前做过的一维数组最大子数组的和的问题, 然后都其中切开的每一段一维数组做比较,输出最大的值. 1 #include<iostream> 2 #include<stdlib.h> 3 #include<time.h> 4 using namespace std; 5 int main() 6 { 7 int n; 8 cout<<"请输入一维环形数组的长度:"; 9 cin>>n;

环形数组的最大子数组求解

然后再用一维数组求解最大子数组的方法即可.值得注意的是,子数组的长度不可超过n,在我程序中有所体现.最终,因为没有要求时间复杂度的问题,我选择 了遍历的方法求解了此问题. 1 #include<iostream> 2 using namespace std; 3 int main() 4 { 5 int n; 6 cout<<"输入环形数组的长度:"; 7 cin>>n; 8 int *p; 9 p=new int[n]; 10 for(int i=

环形数组逆向遍历

1 #include <stdio.h> 2 #include <string.h> 3 4 #define shell_printf_greep(format,...) printf("\033[42;37m"format"\033[0m", ##__VA_ARGS__) 5 #define shell_printf_red(format,...) printf("\033[41;37m"format"\033

结对开发之环形数组

一.题目与要求 题目:返回一个整数数组中最大子数组的和. 要求: 输入一个整形数组,数组里有正数也有负数. 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和. 如果数组A[0]……A[j-1]首尾相邻,允许A[i-1], …… A[n-1], A[0]……A[j-1]之和最大. 同时返回最大子数组的位置. 求所有子数组的和的最大值.要求时间复杂度为O(n) 二.设计思路 1.在上一次求一维数组最大子数组的问题上,进行拓展,继续使用类似的求和方法 2.应题目要求,这次的一位数组要首尾

环形数组最大子数组之和

题目:返回一个整数数组中最大子数组的和.要求: 输入一个整形数组,数组里有正数也有负数. 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和. 如果数组A[0]……A[j-1]首尾相邻,允许A[i-1],…… A[n-1],A[0]……A[j-1]之和最大. 同时返回最大子数组的位置. 求所有子数组的和的最大值. 合作伙伴:孟西鑫 博客地址:http://home.cnblogs.com/u/wanzitou/feed/blog/ 结对编程要求: 两人结对完成编程任务. 一人主要负责

软件工程——结对开发环形数组

一.题目: 返回一个整数数组中最大子数组的和. 要求: 输入一个整形数组,数组里有正数也有负数. 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和. 如 果数组A[0]……A[j-1]首尾相邻,允许A[i-1], …… A[n-1], A[0]……A[j-1]之和最大. 同时返回最大子数组的位置. 求所有子数组的和的最大值.要求时间复杂度为O(n). 二.设计思路 开始想的是用链表实现数组首尾相连,可是由于链表用着不太熟悉,便想了另一种算法: 当最大值未出现跨域是就按常规方法计算找