[英]Recursively Finding a Max Value in a Vector in Java
因此,對於編程類,我們需要遞歸地找到向量的最大值和最小值的值。 我知道如何使用迭代來執行此操作,但是無法弄清楚我需要做些什么才能使此工作與此分配所需的遞歸一起工作。 如果可以獲取索引,我將能夠僅使用element來獲取最大值和最小值,但是到目前為止,我嘗試過的所有操作都給我帶來了很多錯誤。 這是我到目前為止的所有代碼。
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;
}
}
}
除非是使用特定的需求Vector
, 不這樣做 ,如果是,告訴老師來更新分配到新的東西比1998年Vector
被替換ArrayList
早在1998年中的Java 1.2和javadoc說:
與新的集合實現不同,Vector是同步的。 如果不需要線程安全的實現,建議使用
ArrayList
代替Vector
。
如果需要同步,我建議您在Vector
周圍使用ArrayList
周圍的Collections.synchronizedList()
,而不要使用Vector
,這意味着從不應該使用Vector
,除非使用要求它的舊API。
Java不支持尾遞歸,但是無論如何,我還是要解釋一下,因為這將是支持它的其他語言的首選方式。
使用遞歸時,函數調用將進入調用堆棧。 最終,通過非常深的遞歸,您可能會耗盡堆棧空間,這將導致StackOverflowException
並殺死您的程序。
在所有變量都不可變的純函數式編程中,不使用堆棧空間即可執行循環的方法是使遞歸調用成為方法中的最后一件事。 這樣,功能編譯器可以簡單地跳回到方法的開頭,而無需添加到調用堆棧中,這僅是可能的,因為當前調用中無事可做。
為了使該方法對於必須返回列表最大值的方法起作用,遞歸調用將傳遞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));
}
您可以使用以下代碼遞歸獲取向量的最小值:
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;
}
}
您可以通過相同的方式遞歸查找最大值,只需在最后一個if語句中用<>切換<
使用輔助方法,該方法需要一個index參數和您的max / min對象。 該代碼應易於說明:
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
。 但是它將產生可能有些混亂的代碼。 如果您想嘗試一下,這是一個很好的練習。
但是向量中有直接方法來找到最大值
公共班級主要{
公共靜態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);
}}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.