有一个对象,Cars,定义为,
class Cars{
String make;
String model;
String year;
....
}
对象的一些限制:
品牌,型号和年份可以带来任何价值。
不能有两个具有相同属性集的对象。例如,不能car1 = { make : "Audi", model : "A6", year : "2008" }
和car2 = { make : "Audi", model : "A6", year : "2008"}
让我们说我和一个服务人员谈话,该服务给我一份所有汽车对象的清单。我有一个输入(品牌,型号,年份)。我的工作是从列表中选择汽车对象(由服务返回)。我应该这样做,以便我选择匹配尽可能多的属性的对象。
让我举个例子。让我们假设我从服务中获得了5辆车的清单,
car1 = { make : "", model : "A6", year : "2008" }
car2 = { make : "Audi", model : "", year : "2008" }
car3 = { make : "Audi", model : "A6", year : "" }
car4 = { make : "", model : "", year : "" }
car5 = { make : "BMW", model : "M3", year : "2009" }
如果我的输入是
{make : "Audi", model : "A6", year : "2008"}
我应该可以从列表中选择一辆车。如果相同数量的参数匹配,我应该在订单make>中给出优先权。 &model;年。在上面的例子中,我应该选择car3。
此外,如果我的输入是
{ make : "Mercedes", model : "C300", year : "2008" }
我应该选择car4 = { make : "", model : "", year : "" }
(通用的)
有关解决此问题和/或伪代码的任何建议吗?
答案 0 :(得分:1)
我会考虑使用数据库表来存储这些条目:
SELECT * FROM cars
WHERE make IN('Audi', '')
AND model IN('A6', '')
AND year IN('2008', '')
SORT BY make DESC, model DESC, year DESC
LIMIT 1
然后,您可以使用SQL语句选择最佳条目:
DESC
''
是因为否则LIMIT 1
将首先出现。
{make : "Audi", model : "A6", year : "2008"}
是根据您的排序顺序从行中选择最佳候选者。
案例1: | make | model | year |
+--------+---------+------+
| Audi | A6 | '' | <--- LIMIT 1 selects this one
| Audi | '' | 2008 |
| '' | A6 | 2008 |
| '' | '' | '' |
{ make : "Mercedes", model : "C300", year : "2008" }
案例2: | make | model | year |
+--------+---------+------+
| '' | '' | '' | <---- LIMIT 1 selects this one
e.preventDefault();
答案 1 :(得分:1)
步骤1)找到符合任何条件的所有项目。
步骤2)按照将您的标准按重要性排列的分数对结果进行排序。
这是JavaScript中的一些伪代码(您可以将其迁移到Java)。
var list = [
{a: "a1", b: "b1", c: "c1"},
{a: "a1", b: "b1", c: "c2"},
{a: "a1", b: "b2", c: "c1"},
{a: "a1", b: "b2", c: "c2"},
{a: "a2", b: "b1", c: "c1"},
{a: "a2", b: "b1", c: "c2"},
{a: "a2", b: "b2", c: "c1"},
{a: "a2", b: "b2", c: "c2"}
];
function findAny(a, b, c) {
// get a list of all of the items that match any case
var found = list.filter(function(record) {
return record.a == a || record.b == b || record.c == c;
});
// sort the items be the calculated score high to low
function score(record) {
var score = 0;
if(record.a == a) { score += Math.pow(2, 2); }
if(record.b == b) { score += Math.pow(2, 1); }
if(record.c == c) { score += Math.pow(2, 0); }
// setting the score on the record for education
record.score = score;
return score;
}
return found.sort(function(a, b) { return score(b) - score(a); });
}
var result = findAny("a2", "b2", "c2");
console.log(JSON.stringify(result, null, "\t"));
上述结果将是
[
{
"a": "a2",
"b": "b2",
"c": "c2",
"score": 7
},
{
"a": "a2",
"b": "b2",
"c": "c1",
"score": 6
},
{
"a": "a2",
"b": "b1",
"c": "c2",
"score": 5
},
{
"a": "a2",
"b": "b1",
"c": "c1",
"score": 4
},
{
"a": "a1",
"b": "b2",
"c": "c2",
"score": 3
},
{
"a": "a1",
"b": "b2",
"c": "c1",
"score": 2
},
{
"a": "a1",
"b": "b1",
"c": "c2",
"score": 1
}
]
编辑如果您只想获得得分最高的结果。
function findAnyBest(a, b, c) {
function score(record) {
var score = 0;
if(record.a == a) { score += Math.pow(2, 2); }
if(record.b == b) { score += Math.pow(2, 1); }
if(record.c == c) { score += Math.pow(2, 0); }
return score;
}
var highScore = 0;
var found = [];
list.forEach(function(record) {
var currentScore = score(record);
if(currentScore > highScore) {
// new high score throw out the old ones
found = [record];
highScore = currentScore;
} else if(currentScore === highScore) {
found.push(record);
}
});
return found;
}
答案 2 :(得分:1)
请注意,我们不需要在此处进行任何排序,只需找到最高分数即可。排序会使您的解决方案O(NlogN)
,而找到最大值为O(N)
。
public Car getBestSelection(List<Car> cars, String make, String model, String year){
Map<Car, Integer> scoreMap = new HashMap<>(cars.size());
// Find scores for all valid cars
for(Car car : cars)
if(isValidCar(car, make, model, year))
scoreMap.push(car, calcScore(car, make, model, year));
// find max score
Car maxCar;
int maxScore;
for(Map.Entry<Car, Integer> e : scoreMap.entrySet()){
if(e.getValue() > maxScore){
maxScore = e.getValue();
maxCar = e.getKey();
}
}
return maxCar;
}
public int calcScore(Car car, String make, String model, String year){
int makeScore = car.make.equals(make) ? Math.pow(2,2) : 0;
int modelScore = car.model.equals(model) ? Math.pow(2,1) : 0;
int yearScore = car.year.equals(year) ? Math.pow(2,0) : 0;
return makeScore + modelScore + yearScore;
}
public boolean isValidCar(Car car, String make, String model, String year){
return (car.make.equals("") && car.model.equals("") && car.year.equals("")) ||
(car.make.equals(make) || car.model.equals(model) || car.year.equals(year));
}
答案 3 :(得分:0)
上述答案大多是正确的,但实际上并没有解决问题。当使用指数模型来确定汽车匹配的程度时,最高匹配将始终获胜。这意味着单独制作匹配(4分)的得分高于模型和年份的匹配(2 + 1 = 3分)。这与初步问题的评论相反应该发生。
最好使用线性模型(例如,make = 4 points,model = 3 points,year = 2 points)。这样,匹配任何两个标准都将胜过匹配单个标准。