Java 根据客户历史记录查找强链接和弱链接
如果同一客户同时购买了这两种商品,则这两种商品之间存在着紧密的联系。如果两个项目与第三个项目强链接或弱链接,则它们是弱链接的 输入:Java 根据客户历史记录查找强链接和弱链接,java,Java,如果同一客户同时购买了这两种商品,则这两种商品之间存在着紧密的联系。如果两个项目与第三个项目强链接或弱链接,则它们是弱链接的 输入: {“第一:abc”,“第一:hij”,“第二:hij”,“第二:klm”,“第三:nop”,“第四:qrs”,“第四:abc”,“第一:def”,“第五:klm”,“第五:tuv”} “第一/第二/第三/第四/第五”是客户ID,“ABC,HIJ”等是项目ID。它们之间用“:”分隔 目标:找到给定项目的强链接和弱链接的数量 示例:对于“ABC”和上面的字符串输入数组
{“第一:abc”,“第一:hij”,“第二:hij”,“第二:klm”,“第三:nop”,“第四:qrs”,“第四:abc”,“第一:def”,“第五:klm”,“第五:tuv”}
“第一/第二/第三/第四/第五”是客户ID,“ABC,HIJ”等是项目ID。它们之间用“:”分隔
目标:找到给定项目的强链接和弱链接的数量
示例:对于“ABC”和上面的字符串输入数组,输出应为
[3,2]
强链为QRS、HIJ、DEF,弱链为KLM、TUV
方法:
public int[] getLinkCount(String itemId, String[] orderHist) {
}
我能弄明白的是:
不知道这是否是最有效的。我现在还停留在如何找到薄弱环节的问题上我目前没有IDE,因此我现在无法提供完整的程序,但我尝试概述一下想法。查找强链接通常与您所做的方式相同,但您最好将其与同时查找弱链接合并,以递归方式遍历hashmap,从那些项目列表包含特定元素的客户开始 在这种情况下,客户“第一”和“第四”的项目列表中有项目“ABC”
- 客户“first”的列表中还有项目“HIJ”和“DEF”,这些都是与“ABC”的强链接。因此,应该继续搜索那些其项目列表包含这些元素的客户。在这种情况下,客户“second”也有项目“HIJ”,除此之外,他还有“KLM”,因此“KLM”是“ABC”的薄弱环节。没有任何其他客户的商品列表中有“DEF”,因此我们到此为止。您应该继续搜索那些项目列表中包含“KLM”的客户,您将发现客户“fifth”,其项目列表中除此之外还包含“TUV”,因此这也是“ABC”的薄弱环节。没有任何其他客户的商品列表中有“TUV”,所以我们就到此为止
- 客户“第四个”有“QRS”项,该项与“ABC”有很强的联系。没有任何其他客户在他们的商品列表中有“QRS”,所以我们就到此为止
- 这里有一个工作版本。请参见代码中的注释:
package strong;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class Strong {
/**
* Are item1 and item2 strongly linked ?
* @param item1 the first item for example "abc"
* @param item2 the second item for example "hij"
* @param groups example: [[nop], [tuv, klm], [qrs, abc], [abc, def, hij],
* [hij, klm]]
* @return true if item1 and item2 are strongly linked
*/
public static boolean stronglyLinked(String item1, String item2,
Collection<Set<String>> groups) {
// true if groups contains a set with item1 and item2
return groups.stream().
anyMatch(g-> g.contains(item1) && g.contains(item2));
}
/**
* Are item1 and item2 weakly linked ?
* @param item1 the first item for example "abc"
* @param item2 the second item for example "hij"
* @param groups example: [[nop], [tuv, klm], [qrs, abc], [abc, def, hij],
* [hij, klm]]
* @return true if item1 and item2 are weakly linked
*/
public static boolean weaklyLinked(String item1, String item2,
Collection<Set<String>> groups) {
// call private implementation with bag parameter (to avoid infinite
// recursion).
return weaklyLinked(item1, item2, groups, new HashSet());
}
/**
* Get strongly and weakly link count for the given item
* @param itemId the item
* @param orderHist for example: {"first:abc","first:hij", "second:hij",
* "second:klm", "third:nop","fourth:qrs", "fourth:abc", "first:def",
* "fifth:klm", "fifth:tuv"}
* @return an array with [0] => strongly linked count, [1] => weakly linked
* count.
*/
public static int[] getLinkCount(String itemId, String[] orderHist) {
// get groups of items bought together for example:
// [[nop], [tuv, klm], [qrs, abc], [abc, def, hij], [hij, klm]]
final Collection<Set<String>> groups = Arrays.stream(orderHist).
map(o-> o.split(":")).
// for example map "first:abs" to ["first", "abc"]
collect(Collectors.groupingBy(o-> o[0],
Collectors.mapping(o-> o[1], Collectors.toSet()))).
values();
// group by customerId but keep only values (groups are
// important but customer are not).
// get the set of strongly linked items
final Set<String> stronglyLinkedItems = groups.stream().
flatMap(g-> g.stream()).
// we get someting like: [nop, tuv, klm, qrs, abc, abc, def,
// hij]
filter(item-> !item.equals(itemId)).
// select only item != itemId
distinct().
// optimization. but stronglyLinked is not so costly (so may be
// removed)
filter(item-> stronglyLinked(item, itemId, groups)).
// select only item strongly linked with item
collect(Collectors.toSet());
// make a set from that stream
// weeklyLinked items
final Set<String> weaklyLinkedItems = groups.stream().
flatMap(g-> g.stream()).
// we get someting like: [nop, tuv, klm, qrs, abc, abc, def,
// hij]
filter(item-> !item.equals(itemId)).
// select only item != itemId
filter(item-> !stronglyLinkedItems.contains(item)).
// remove strongly linked items (alreay in stronglyLinkedItems
// set).
distinct().
// remove duplicate. it's only an optimization we don't want
// to compute costly weaklyLinked() on duplicate (not needed).
filter(item-> weaklyLinked(item, itemId, groups)).
// select only item weakly linked with itemId
collect(Collectors.toSet());
// make a set
// return the result array
return IntStream.of(
stronglyLinkedItems.size(),
weaklyLinkedItems.size()).
toArray();
}
/**
* main
*/
public static void main(String[] args) {
final String orderHist[] = {
"first:abc","first:hij", "second:hij", "second:klm", "third:nop",
"fourth:qrs", "fourth:abc", "first:def", "fifth:klm", "fifth:tuv"};
int[] result = getLinkCount("abc", orderHist);
System.out.println(result[0]);
System.out.println(result[1]);
}
private static boolean weaklyLinked(String item1, String item2,
Collection<Set<String>> groups, Set<Set<String>> bag) {
// if (item1, item2) has already been explored then return false
// this is needed to avoid infinite recursion
if (bag.stream().anyMatch(s-> s.contains(item1) && s.contains(item2))) {
return false;
}
// add (item1, item2) to the bag
bag.add(Stream.of(item1, item2).collect(Collectors.toSet()));
return groups.stream().
flatMap(g-> g.stream()).
// we get someting like:
// [nop, tuv, klm, qrs, abc, abc, def, hij]
filter(item-> !item.equals(item1) && !item.equals(item2)).
// filter for removing item1 and item2 from the stream
anyMatch(item-> (stronglyLinked(item1, item, groups) ||
weaklyLinked(item1, item, groups, new HashSet(bag))) &&
(stronglyLinked(item2, item, groups) ||
weaklyLinked(item2, item, groups, new HashSet(bag))));
// any item strongly or weakly linked with item1 and item2 =>
// if yes return true
}
}
包强;
导入java.util.array;
导入java.util.Collection;
导入java.util.HashSet;
导入java.util.Set;
导入java.util.stream.collector;
导入java.util.stream.IntStream;
导入java.util.stream.stream;
公众阶级的强势{
/**
*项目1和项目2是否有强链接?
*@param item1第一项,例如“abc”
*@param item2第二项,例如“hij”
*@param组示例:[[nop],[tuv,klm],[qrs,abc],[abc,def,hij],
*[你好,荷航]]
*@如果item1和item2强链接,则返回true
*/
公共静态布尔强链接(字符串项1、字符串项2、,
(收集组){
//如果组包含具有item1和item2的集合,则为true
返回groups.stream()。
任意匹配(g->g.contains(项目1)和&g.contains(项目2));
}
/**
*项目1和项目2是否弱链接?
*@param item1第一项,例如“abc”
*@param item2第二项,例如“hij”
*@param组示例:[[nop],[tuv,klm],[qrs,abc],[abc,def,hij],
*[你好,荷航]]
*@如果item1和item2弱链接,则返回true
*/
公共静态布尔弱链接(字符串项1、字符串项2、,
(收集组){
//使用bag参数调用私有实现(以避免无限
//递归)。
返回弱链接(item1、item2、groups、newhashset());
}
/**
*获取给定项的强链接计数和弱链接计数
*@param itemId该项目
*@param orderHist例如:{“first:abc”、“first:hij”、“second:hij”,
*“第二:荷航”、“第三:nop”、“第四:qrs”、“第四:abc”、“第一:def”,
*“第五:荷航”,“第五:图瓦”}
*@返回一个具有[0]=>强链接计数、[1]=>弱链接计数的数组
*伯爵。
*/
公共静态int[]getLinkCount(字符串itemId,字符串[]orderHist){
//获取一起购买的项目组,例如:
//[[nop],[tuv,klm],[qrs,abc],[abc,def,hij],[hij,klm]]
最终集合组=Arrays.stream(orderHist)。
映射(o->o.split(“:”)。
//例如,将“first:abs”映射到[“first”,“abc”]
收集(收集器.分组方式(o->o[0],
Collectors.mapping(o->o[1],Collectors.toSet())。
值();
//按customerId分组,但仅保留值(组为
//重要,但客户不重要)。
//获取强链接项集
最终设置stronglyLinkedItems=groups.stream()。
平面图(g->g.stream()。
//我们得到的信息如下:[不,tuv,klm,qrs,abc,abc,def,
//hij]
筛选器(item->!item.equals(itemId))。
//仅选择项目!=项目ID
独特的()。
//优化。但stronglyLinked的成本并不高(也可能如此)
//删除)
筛选(项目->强链接(项目、项目ID、组))。
//仅选择与项目强链接的项目
收集(collector.toSet)