例如,我有一个包含一些Lecture实例的列表,每个讲座都有一定数量的学生参加本讲座,另一个列表包含一些课堂实例,每个教室都有最大容量。
现在我打算将课堂列表中的每个讲座分配到课堂列表中的教室,讲座课上的所有讲座都应该有一个教室,然后创建一个地图来存储这种可能性。 我希望以集合的形式返回所有这些可能的匹配。 例如:
Classroom List: [Classroom1(50),Classroom2(70),Classroom3(80)]
Lecture list: [Lecture1(50), Lecture2(70), Lecture3(50)]
然后我们有3个可能的地图,它们是:
{lecture1:classroom1, lecture2:classroom2, lecture3:classroom3} and
{lecture1:classroom1, lecture2:classroom3, lecture3:classroom2} and
{lecture1:classroom2, lecture2:classroom3, lecture3:classroom1}
之后,所有可能的地图都应该存储在一个集合中。
我是编程的新手,还没有学过算法,也许这就是我为什么如此挣扎的原因,如果有人能帮我解决这个问题,我将不胜感激。
答案 0 :(得分:4)
你看起来像是笛卡尔产品。
请参阅https://en.wikipedia.org/wiki/Cartesian_product
您可以使用Java 8流
执行此操作所有排列
// Just substitute the types and values for Lecture and Classroom instances
// I'm not going to do this for you
final List<String> first = Arrays.asList("foo","bar","baz");
final List<String> second = Arrays.asList("spam","ham","eggs");
final Set<Map.Entry<String,String>> objects =
first
.stream()
.flatMap(f ->
second
.stream()
.map(s -> new AbstractMap.SimpleEntry<>(f, s)))
.collect(Collectors.toSet());
您的“对象”设置将包含保存组合的抽象输入地图。
Set[
Map{foo : spam}
Map{foo : ham}
Map{foo : eggs}
Map{bar : spam}
Map{bar : ham}
Map{bar : eggs}
Map{baz : spam}
Map{baz : ham}
Map{baz : eggs}
]
组合组
如果您确实需要集合中的3个项目,则可以在第二个流上执行中间收集以收集到您选择的数据结构中。下面显示了列表,因为我已经展示了Collectors.toSet()
final Set<List<AbstractMap.SimpleEntry<String,String>>> objects =
first
.stream()
.map(f ->
second
.stream()
.map(s -> new AbstractMap.SimpleEntry<>(f, s))
.collect(Collectors.toList()))
.collect(Collectors.toSet());
您的“对象”设置将包含一个包含组合的抽象输入地图列表。
Set[
List(
Map{foo : spam}, Map{foo : ham}, Map{foo : eggs}
),
List(
Map{bar : spam}, Map{bar : ham}, Map{bar : eggs}
),
List(
Map{baz : spam}, Map{baz : ham}, Map{baz : eggs}
)
]
这说明了在单个功能语句中使用Java 8的简单笛卡尔积算法。如果您希望添加任何子句或排除项,可以使用filter
或任何其他更高阶的函数来操作流。
答案 1 :(得分:1)
所以我厌倦了这个并编写了一个有效的解决方案
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
class ClassMatcher {
//The set of all possible matchings.
static ArrayList<ArrayList<Pair>> set = new ArrayList<ArrayList<Pair>>();
// The current matching being built
static ArrayList<Pair> cur = new ArrayList<Pair>();
public static void main(String[] args) {
Lecture[] l = { new Lecture(50, 1), new Lecture(70, 2), new Lecture(50, 3)};
ArrayList<Classroom> c = new ArrayList<>(Arrays.asList(
new Classroom(50, 1), new Classroom(70, 2),
new Classroom(100, 3)));
for (int i = 0; i < l.length; i++) {
//Fill with dummy values
cur.add(new Pair(new Classroom(-1, -1), new Lecture(-1, -1)));
}
// Sort the arrays to save work in rec()
Arrays.sort(l);
//Sort classrooms in descending order
Collections.sort(c, new Comparator<Classroom>() {
@Override
public int compare(Classroom o1, Classroom o2) {
return o1.compareTo(o2) * -1;
}
});
recursive(l, c, 0);
// Print all the sets
for (int i = 0; i < set.size(); i++) {
System.out.print("{");
for (int j = 0; j < set.get(i).size(); j++) {
System.out.print("Lecture " + set.get(i).get(j).l + ": "
+ "Classroom " + set.get(i).get(j).c);
if (j < set.get(i).size() - 1) {
System.out.print(", ");
} else {
System.out.print("}");
}
}
System.out.println();
}
}
public static void recursive(Lecture[] lectureList,
ArrayList<Classroom> classroomList, int curLecture) {
for (int i = 0; i < classroomList.size(); i++) {
// if the classroom is smaller than the lecture we cna stop as the
// lists are sorted so all other lectures will be to big for the
// current classroom
if (lectureList[curLecture].size > classroomList.get(i).size) {
return;
}
//Match the current classroom to the current lecture and add to the working matching
cur.set(curLecture, new Pair(classroomList.get(i), lectureList[curLecture]));
//If there are more lectures to do then remove the used classroom and recursively call.
if (curLecture < lectureList.length - 1) {
Classroom tmp = classroomList.remove(i);
recursive(lectureList, classroomList, curLecture + 1);
classroomList.add(i, tmp);
}
// If no Lectures left then add this matching to the set of all matchings.
else {
ArrayList<Pair> copy = (ArrayList<Pair>) cur.clone();
set.add(copy);
}
}
}
}
class Classroom implements Comparable<Classroom> {
int size;
int number;
public Classroom(int s, int n) {
size = s;
number = n;
}
@Override
public int compareTo(Classroom o) {
return Integer.compare(this.size, o.size);
}
public String toString() {
return number + " (" + size + ")";
}
}
class Lecture implements Comparable<Lecture> {
int size;
int number;
public Lecture(int s, int n) {
size = s;
number = n;
}
@Override
public int compareTo(Lecture o) {
return Integer.compare(this.size, o.size);
}
public String toString() {
return number + " (" + size + ")";
}
}
class Pair {
Classroom c;
Lecture l;
public Pair(Classroom c, Lecture l) {
this.c = c;
this.l = l;
}
}
这给出了输出
{Lecture 1 (50): Classroom 3 (100), Lecture 3 (50): Classroom 1 (50), Lecture 2 (70): Classroom 2 (70)}
{Lecture 1 (50): Classroom 2 (70), Lecture 3 (50): Classroom 1 (50), Lecture 2 (70): Classroom 3 (100)}
{Lecture 1 (50): Classroom 1 (50), Lecture 3 (50): Classroom 3 (100), Lecture 2 (70): Classroom 2 (70)}
{Lecture 1 (50): Classroom 1 (50), Lecture 3 (50): Classroom 2 (70), Lecture 2 (70): Classroom 3 (100)}
答案 2 :(得分:0)
下面的代码将为您提供所有匹配,您可以像使用任何内容一样使用它们
HasMap<Integer, Integer> match = new HashMap<Integer, Integer>();
for(int i = 0; i < 3; i++) {
for(int j = 0; j < 3; j++) {
if(classroom[i] >= lecture[j]) {
match.add(lecture[j], classroom[i]);
}
}
}
如果你想要每个教室或讲座的单独地图,你可以试试这个(教室的例子)
HashMap<Integer, Integer> classroom1 = new HashMap<Integer, Integer>();
HashMap<Integer, Integer> classroom2 = new HashMap<Integer, Integer>();
HashMap<Integer, Integer> classroom3 = new HashMap<Integer, Integer>();
for(int i = 0; i < 3; i++) {
for(int j = 0; j < 3; j++) {
if(i == 0) {
if(classroom[i] >= lecture[j]) {
classroom1.add(lecture[j], classroom[i]);
}
}
if(i == 1) {
if(classroom[i] >= lecture[j]) {
classroom2.add(lecture[j], classroom[i]);
}
}
if(i == 2) {
if(classroom[i] >= lecture[j]) {
classroom3.add(lecture[j], classroom[i]);
}
}
}
}
在此之后,您可以创建地图地图。不介意纠正我或添加一些东西。祝你有个美好的一天!
答案 3 :(得分:0)
对于每个循环,算法本身可能看起来像这样:
mathWith
答案 4 :(得分:0)
以下是使用地图而非数组的答案:
public Set<Map<Lecture, ClassRoom>> allocateRooms(List<Lecture> lectures, List<ClassRoom> classRooms){
Set<Map<Lecture, ClassRoom>> returnSet = new LinkedHashSet<>();
for(Lecture l: lectures){
for (ClassRoom c: classRooms){
Map<Lecture, ClassRoom> n = new HashMap<>();
n.put(l,c);
}
}
return returnSet;
}
答案 5 :(得分:0)
以下是有序数据集合的示例:
public Set<Map<Lecture, ClassRoom>> allocateRooms(List<Lecture> lectures, List<ClassRoom> classRooms){
List<ClassRoom> sortedClassRooms = classRooms
.stream().sorted(Comparator.comparingInt(a -> a.getId())).collect(Collectors.toList());
List<Lecture> sortedLectures = lectures
.stream().sorted(Comparator.comparingInt(a -> a.getId())).collect(Collectors.toList());
Set<Map<Lecture, ClassRoom>> returnSet = new LinkedHashSet<>();
for(Lecture l: sortedLectures){
for (ClassRoom c: sortedClassRooms){
Map<Lecture, ClassRoom> n = new HashMap<>();
n.put(l,c);
}
}
return returnSet;
}