理想情况下,当处理逻辑上组合在一起的数据时,您应该抽象出一个类来封装它。在您的情况下,您希望跟踪每个可能的 distance 组合。每个Combination 都应该跟踪:
- 值的索引。
- 值本身。
- 距离。
- 哪个低,哪个高。
在这 3. 和 4. 中,可以从 1. 和 2. 计算出来。
class Combination {
int indexA, indexB, valueA, valueB;
public Combination(int[] array, int indexA, int indexB) {
this.indexA = indexA;
this.indexB = indexB;
this.valueA = array[indexA];
this.valueB = array[indexB];
}
public int getDistance() { ... }
public int getHigh() { ... }
public int getLow() { ... }
public int getHighIndex() { ... }
public int getLowIndex() { ... }
}
有了这样的数据结构(类),您可以为每个可能的组合构造对象(当然无需重复 - 注意j 如何在i + 1 开始可变重复可能的组合):
List<Combination> combinations = new ArrayList<>();
for (int i = 0; i < array.length; i++)
for (int j = i + 1; j < array.length; j++)
combinations.add(new Combination(array, i, j));
然后使用Combination 中的List,您可以计算它们之间的最小距离:
int min = combinations.stream()
.mapToInt(Combination::getDistance)
.min().getAsInt();
最后,您可以选择与之前计算的最小距离匹配的那些组合:
combinations.stream()
.filter(c -> c.getDistance() == min)
.forEach(c -> System.out.println(c));
关键是将Combination类抽象到它自己的封装类中,因此它可以单独负责提供必要的API来检查特定组合:索引、值、距离、高值、低值甚至String (toString) 表示。
以下是此方法的完整工作演示,运行它来感受一下:
import java.util.ArrayList;
import java.util.List;
public class MinimumDistance {
public static void main(String[] args) {
printMinimums(5, 50, 3, 42, 18, 16, 8, 30, 44);
}
public static void printMinimums(int... array) {
List<Combination> combinations = new ArrayList<>();
for (int i = 0; i < array.length; i++)
for (int j = i + 1; j < array.length; j++)
combinations.add(new Combination(array, i, j));
int min = combinations.stream()
.mapToInt(Combination::getDistance)
.min().getAsInt();
combinations.stream()
.filter(c -> c.getDistance() == min)
.forEach(c -> System.out.println(c));
}
static class Combination {
int indexA, indexB, valueA, valueB;
public Combination(int[] array, int indexA, int indexB) {
this.indexA = indexA;
this.indexB = indexB;
this.valueA = array[indexA];
this.valueB = array[indexB];
}
public int getDistance() {
return getHigh() - getLow();
}
public boolean isValueAHigh() {
return valueA > valueB;
}
public int getHigh() {
return isValueAHigh() ? valueA : valueB;
}
public int getLow() {
return isValueAHigh() ? valueB : valueA;
}
public int getHighIndex() {
return isValueAHigh() ? indexA : indexB;
}
public int getLowIndex() {
return isValueAHigh() ? indexB : indexA;
}
public String toString() {
return String.format("%d[%d] - %d[%d] = %d",
getHigh(), getHighIndex(),
getLow(), getLowIndex(),
getDistance());
}
}
}
Complete code on GitHub
希望这会有所帮助。