以下显然是非常不切实际的,但我的讲师坚持教我们对编程的基本理解。他给我们的练习是这样的:
仅使用System.in.read,int,char和循环,创建一个读取的方法 用户从命令行输入并返回一个与金额完全一样大的char [] 输入的字符数。不要使用System.arraycopy()或其他库方法。
我很无能为力。由于似乎无法缓冲System.in.read输入,因此在解析任何字符之前,数组必须具有完美的大小。这个世界应该如何运作?
答案 0 :(得分:1)
创建一个从命令行读取用户输入并返回char []
的方法
再想一想,我假设您应该通过自己种植char[]
数组来进行自己的输入缓冲。这应该是提到System.arraycopy()
的原因。
增长数组就像
一样如果你将它与一个读取输入流中所有字符的循环结合起来,你可以得到以下内容,并且应该完成你的任务。
甚至可以在没有循环和增长数组的情况下完成它。只需创建一次正确大小的新数组。
private static char[] readToCharArray(int length) throws IOException {
int read = System.in.read();
char[] result;
if (read == -1 || read == '\r' || read == '\n' ) {
result = new char[length];
} else {
result = readToCharArray(length + 1);
result[length] = (char) read;
}
return result;
}
char[] myArray = readToCharArray(0);
答案 1 :(得分:0)
手动阵列复制怎么样,文中没有说什么呢?如果允许你可以做这样的事情:
private static char[] readInput() throws IOException {
System.out.println("type something terminated with '|'");
char[] input = new char[0];
int count = 0;
int read;
for (; ; ) {
read = System.in.read();
if (read == '|') {
break;
} else {
char[] tmp = new char[input.length + 1];
for (int i = 0; i < input.length; i++) {
tmp[i] = input[i];
}
input = tmp;
}
input[count] = (char) read;
count++;
}
return input;
}
您还可以检查read == -1
而不是read == '|'
,但输入结束字符因系统而异。您可以在每次迭代中复制char [],而不是在每次迭代时复制char [],然后在最后创建一个正确大小的数组。你也可以使用while循环...
但是如果建议zapl
返回一个正确大小的空数组肯定会更有趣:)
答案 2 :(得分:0)
我将假设你的讲师意味着:
System.in.read
”仅指InputStream#read()
而不是read
上的其他重载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)。