Java 程序布局-通过System.in.read创建大小合适的阵列
下面的内容显然非常不切实际,但我的讲师坚持要教我们对编程的基本理解。他给我们的练习是这样的:Java 程序布局-通过System.in.read创建大小合适的阵列,java,arrays,loops,Java,Arrays,Loops,下面的内容显然非常不切实际,但我的讲师坚持要教我们对编程的基本理解。他给我们的练习是这样的: private static char[] readInput() throws IOException { System.out.println("type something terminated with '|'"); char[] input = new char[0]; int count = 0; int read; for
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;
}
仅使用System.in.read、int、char和循环,创建一个读取
用户从命令行输入并返回一个char[],该char[]正好与数量一样大
输入的字符数。不要使用System.arraycopy()或其他库方法
我不懂。由于似乎没有办法缓冲System.in.read输入,因此在解析任何字符之前,必须完全调整数组的大小。这到底是怎么回事
创建一个从命令行读取用户输入并返回char[]的方法
再想一想,我假设您应该通过自己生长一个char[]
数组来完成自己的输入缓冲。这应该是提到System.arraycopy()
的原因
增长阵列的工作原理如下
- 创建比现有阵列长1项的新阵列
- 对于旧数组中的每个字符
- 将字符从旧数组复制到新数组,保持位置不变
- 将旧阵列替换为新阵列
- 从长度为0的数组开始
- 而字符可从inputstream获得
- 将阵列放大一倍
- 将inputstream中的字符放入数组的最后一个插槽
- 返回数组
甚至可以在没有循环和不断增长的阵列的情况下实现。只需创建一次大小正确的新数组
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);
那么手动阵列复制呢,文本中没有提到这一点?如果允许,您可以这样做:
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;
}
private static char[]readInput()引发IOException{
System.out.println(“键入以“|”结尾的内容”);
字符[]输入=新字符[0];
整数计数=0;
int-read;
对于(;;){
read=System.in.read();
如果(读=='|'){
打破
}否则{
char[]tmp=新字符[input.length+1];
for(int i=0;i
您也可以检查
read==-1
而不是read=='|'
,但输入字符的结尾因系统而异。除了在每次迭代中复制char[],您还可以每x次迭代复制一次,然后在最后创建一个大小正确的数组。你也可以使用while循环
但是,按照
zapl
的建议,返回一个正确大小的空数组肯定会更有趣:)我假设您的讲师的意思是:
- 字符[]应包含从System.in读取的字符(不仅仅是正确的大小)
- “
”仅指System.in.read
,而不指InputStream#read()
上其他重载的InputStream
方法,因此您只能一次读取一个字符read
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);
}
/**
*将指定的元素追加到此列表的末尾。
*
*要附加到此列表的@param e元素
*@return true(由{@link Collection#add}指定)
*/
公共布尔加法(E){
确保RecapacityInternal(大小+1);//递增modCount!!
elementData[size++]=e;
返回true;
}
私有网络容量内部(int minCapacity){
modCount++;
//有溢出意识的代码
如果(最小容量-elementData.length>0)
增长(生产能力);
}
/**
*增加容量,以确保它至少可以容纳
*最小容量参数指定的元素数。
*
*@param minCapacity所需的最小容量
*/
私人空间增长(单位容量){
//有溢出意识的代码
int oldCapacity=elementData.length;
int newCapacity=oldCapacity+(oldCapacity>>1);
if(新容量-最小容量<0)
新容量=最小容量;
if(新容量-最大阵列大小>0)
新容量=大容量(最小容量);
//minCapacity通常接近大小,因此这是一个胜利:
elementData=Arrays.copyOf(elementData,newCapacity);
}
由于无法使用System.arraycopy()
,因此需要编写自己的方法来完成此操作。这只是一个for
循环
事实上,这并不是那么低效。正如javadoc所描述的,ArrayList#add(E)
在摊销固定时间内运行
如果您严格遵循
ArrayList
策略,那么生成的数组将比需要的数组大,因此在最后,您需要在最后再进行一次数组调整,以将其截断为输入大小。或者,您可以在每次读取字符时将数组增加1,但在输入长度中,运行时间将是二次的(n^2),而不是线性的(n)。了解输入的字符数。创建了一个大小相同的字符数组。不知道问题是什么。(坚持对编程有一个非常基本的理解有什么错?)我想他打算让你自己做自定义缓冲。您不限于制作一个字符数组和一个字符数组。如果您只有一个字符数组,则无法缓冲内容