因此,对于编程类,我们需要递归地找到向量的最大值和最小值的值。我知道如何使用迭代执行此操作,但无法弄清楚我需要做什么才能使用此递归所需的递归。如果我能得到索引,我将能够使用元素得到最大值和最小值,但到目前为止我尝试的所有内容只会让我犯下大量错误。这是我到目前为止的所有代码。
import java.util.*;
import java.io.*;
public class Lab4<E> {
Vector <Double> data;
public void readData() throws FileNotFoundException
{
{
Scanner console = new Scanner (System.in);
System.out.println("Enter the data file name: ");
String inFile = console.next();
File fileRef = new File(inFile);
Scanner tokens = new Scanner(fileRef);
data = new Vector<Double>();
while(tokens.hasNext())
{
Double value = tokens.nextDouble();
data.add(value);
}
System.out.print("The values in the file are: "+data.toString()+"\n");
System.out.print("The number of values in the file is: "+(data.size())+"\n");
tokens.close();
console.close();
}
}
public static void main(String[] args)
throws IOException
{
Lab4 fileTest = new Lab4();
fileTest.readData();
System.out.println(obj);
}
class MinMaxObject
{
private double max, min;
private int maxPos, minPos;
public MinMaxObject()
{
this.max =Double.MIN_VALUE;
this.maxPos = 0;
this.min=Double.MAX_VALUE;
this.minPos = 0;
}
public MinMaxObject(double ma, int maP, double mi, int miP)
{
this.max = ma;
this.maxPos = maP;
this.min = mi;
this.minPos = miP;
}
public void setMax(double newMax)
{
max = newMax;
}
public double getMax() {
return max;
}
public void setMin(double newMin)
{
min = newMin;
}
public double getMin() {
return min;
}
public void setMaxPos(int newMaxPos)
{
maxPos = newMaxPos;
}
public int getMaxPos() {
return maxPos;
}
public void setMinPos(int newMinPos)
{
minPos = newMinPos;
}
public int getMinPos() {
return minPos;
}
}
}
答案 0 :(得分:3)
除非特定要求使用Vector
,不要,如果是,请告诉教师将作业更新为比1998年更新的内容。Vector
在1998年的Java 1.2中被ArrayList
取代,javadoc说:
与新的集合实现不同,Vector是同步的。如果不需要线程安全实现,建议使用
ArrayList
代替Vector
。
如果需要同步,我建议ArrayList
使用Vector
而不是使用Vector
,这意味着永远不要使用StackOverflowException
,除非一个需要它的旧API。
Java不支持尾递归,但无论如何我都要解释一下,因为那将是支持它的其他语言的首选方式。
使用递归时,函数调用将进入调用堆栈。最终,通过非常深的递归,您可能会耗尽堆栈空间,这将导致List
并终止您的程序。
在纯函数式编程中,所有变量都是不可变的,在不占用堆栈空间的情况下执行循环的方法是使递归调用成为方法中的最后一个。这样,函数编译器可以简单地跳转回到方法的开头,而无需添加到调用堆栈,这是唯一可能的,因为在当前调用中没有其他任何操作。
为了使必须返回列表最大值的方法有效,递归调用将传递public static Integer max(List<Integer> list) {
if (list.isEmpty())
return null;
return max(list, 1, list.get(0));
}
private static final Integer max(List<Integer> list, int index, Integer maxSoFar) {
if (index == list.size())
return maxSoFar;
Integer value = list.get(index);
Integer maxValue = (value.compareTo(maxSoFar) > 0 ? value : maxSoFar);
return max(list, index + 1, maxValue); // tail-recursive call
}
,下一个要处理的索引以及到目前为止找到的最大值。在列表的末尾,它返回传入的值。
为了便于使用,通常会有一个导入方法,因此调用者不必设置额外的参数。
List
上述代码仅适用于ArrayList
个按索引直接访问的对象,例如LinkedList
,但会在List
等列表上执行不佳。
对于所有Collection
个对象和任何其他Iterator
对象,您可以使用Optional
代替。
在这里,我还将展示如何使用public static Optional<Integer> max(Iterable<Integer> coll) {
Iterator<Integer> iter = coll.iterator();
if (! iter.hasNext())
return Optional.empty();
return Optional.of(max(iter, iter.next()));
}
private static final Integer max(Iterator<Integer> iter, Integer maxSoFar) {
if (! iter.hasNext())
return maxSoFar;
Integer value = iter.next();
return max(iter, (value.compareTo(maxSoFar) > 0 ? value : maxSoFar));
}
。
Comparable
要同时获得最小值和最大值,您需要一个类来返回这两个值。
还可以更新代码以处理public static final class MinMax<T> {
private final T min;
private final T max;
MinMax(T min, T max) {
this.min = min;
this.max = max;
}
public T getMin() {
return this.min;
}
public T getMax() {
return this.max;
}
}
public static <T extends Comparable<T>> Optional<MinMax<T>> minMax(Iterable<T> coll) {
Iterator<T> iter = coll.iterator();
if (! iter.hasNext())
return Optional.empty();
T value = iter.next();
return Optional.of(minMax(iter, value, value));
}
private static final <T extends Comparable<T>> MinMax<T> minMax(Iterator<T> iter, T minSoFar, T maxSoFar) {
if (! iter.hasNext())
return new MinMax<>(minSoFar, maxSoFar);
T value = iter.next();
return minMax(iter, (value.compareTo(minSoFar) < 0 ? value : minSoFar),
(value.compareTo(maxSoFar) > 0 ? value : maxSoFar));
}
。
fileInput.files.length
答案 1 :(得分:0)
您可以使用以下代码递归获取向量的最小值:
static double min(Vector<Double> v, int index) {
if (index == v.size() - 1) {
return v.get(index);
}
double val = min(v, index + 1);
if (v.get(index) < val) {
return v.get(index);
} else {
return val;
}
}
您可以以相同的方式递归地找到最大值,只需切换&lt;用&gt;在最后的if语句中
答案 2 :(得分:0)
使用带有索引参数和最大/最小对象的辅助方法。代码应该是自我解释的:
public MinMaxObject getMinMax(Vector<Double> vector) {
MinMaxObject minMax = new MinMaxObject();
getMinMaxAux(vector, minMax, 0);
return minMax;
}
public void getMinMaxAux(Vector<Double> vector, MinMaxObject minMax, int index) {
if(index < vector.size())
{
double value = vector.get(index);
if(value > minMax.getMax())
{
minMax.setMax(value);
minMax.setMaxPos(index);
}
if(value < minMax.getMin())
{
minMax.setMin(value);
minMax.setMinPos(index);
}
getMinMaxAux(vector, minMax, index + 1);
}
}
您也可以选择不在参数中传递MinMaxObject
并从递归调用中获取它。到达向量的末尾时,将创建MinMaxObject
。但它会产生可能有些令人困惑的代码。
如果你想尝试一下,这是一个很好的练习。
答案 3 :(得分:0)
但是在矢量中有直接的方法来找到最大值
public class Main {
public static void main(String [] args){
Vector<Double> v = new Vector<Double>();
v.add(new Double("3.0"));
v.add(new Double("4.0"));
Object obj = Collections.max(v);
System.out.println(obj);
} }