我假设您的讲师的意思是:
- char[] 应该包含从 System.in 读取的字符(不仅仅是正确的大小)
- "
System.in.read
" 仅指InputStream#read()
而不是指其他重载read
方法 on InputStream
,因此您只能一次读取一个字符。
你应该看看ArrayList
是如何实现的。它由一个数组支持,但列表可以任意调整大小。当列表的大小超过数组大小时,ArrayList
创建一个更大的新数组,然后将旧数组的内容复制到其中。以下是一些相关的摘录ArrayList
:
/**
* Appends the specified element to the end of this list.
*
* @param e element to be appended to this list
* @return <tt>true</tt> (as specified by {@link Collection#add})
*/
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
/**
* Increases the capacity to ensure that it can hold at least the
* number of elements specified by the minimum capacity argument.
*
* @param minCapacity the desired minimum capacity
*/
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
由于您不能使用System.arraycopy()
,因此您需要编写自己的方法来执行此操作。那只是一个for
循环。
这实际上并不是那么低效。正如 javadoc 所描述的,ArrayList#add(E)
以摊销的常数时间运行。
如果您ArrayList
完全遵循该策略,那么您的结果数组将比它需要的更大,所以最后,您需要在最后再进行一次数组调整大小以将其截断为精确的输入大小。或者,您可以在每次读取字符时将数组增加 1,但运行时间将是输入长度的二次 (n^2) 而不是线性 (n)。