问题:在给定字符串的情况下,我希望使用length = k
获取Hash Map
的所有子字符串。
所以我声明了public static function getHistogram
返回Map<String,Integer>
并且我正在尝试使用HashMap获取该给定字符串的所有子字符串(作为键),以及每个子字符串已经出现在字符串中,我想增加其键中的值(将是计数器)。
这是我到目前为止所做的: Currenet输出:输出不如预期。
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Iterator;
import java.util.Set;
public class Main2{
public static void main(String[] args) throws InvalidValueException{
// Get a set of the entries
Set set = Main2.getHistogram("ababaca", 5).entrySet();
// Get an iterator
Iterator i = set.iterator();
// Display elements
while(i.hasNext()) {
Map.Entry me = (Map.Entry)i.next();
System.out.print(me.getKey() + ": ");
System.out.println(me.getValue());
}
System.out.println();
}
public static Map<String,Integer> getHistogram(String str, int k)
throws InvalidValueException
{
int i,j;
String tempStr;
Map<String, Integer> hmap = new HashMap<String, Integer>();
for(i = 0; i < str.length(); i++)
{
for(j=i; j < str.length(); j++){
tempStr = str.substring(i, j);
int count = hmap.containsKey(tempStr) ? hmap.get(tempStr) : 0;
hmap.put(tempStr, count + 1);
}
}
return hmap;
}
}
编辑:必须使用count + 1而不是count ++,但仍然没有完全修复。
输出:
: 7
a: 3
ab: 2
aba: 2
b: 2
bab: 1
ac: 1
c: 1
bac: 1
abac: 1
abab: 1
baba: 1
babac: 1
ababa: 1
ababac: 1
ba: 2
答案 0 :(得分:2)
public class Substr {
public static void main(String[] args) {
System.out.println(getHistogram("ababaca", 5));
System.out.println(getHistogram("ababaca", 4));
System.out.println(getHistogram("ababaca", 3));
System.out.println(getHistogram("ababaca", 2));
System.out.println(getHistogram("ababaca", 1));
}
public static Map<String, Integer> getHistogram(String str, int k) {
Map<String, Integer> hmap = new HashMap<>();
for (int start = 0; start < str.length() - k + 1; start++) {
String substring = str.substring(start, start + k);
int count = hmap.containsKey(substring) ? hmap.get(substring) : 0;
hmap.put(substring, count + 1);
}
return hmap;
}
}
这似乎产生了正确的结果。
如果k
已修复,则您不需要两个循环,只需一个循环。它只是贯穿可能的子串的开始索引。然后我们采用子字符串并按照您最初的建议计算子字符串的数量。
答案 1 :(得分:1)
使用Java 8,您可以直接的方式执行此操作:
public static Map<String, Long> getHistogram(String string, int k) {
return
k > string.length() ? Collections.emptyMap() :
k == string.length() ? Collections.singletonMap(string, 1L) :
IntStream.range(0, string.length() - k + 1)
.mapToObj(i -> string.substring(i, i + k))
.collect(Collectors.groupingBy(
Function.identity(),
Collectors.counting()));
}
首先检查k
是否大于给定string
的长度。如果k
更大,则返回空地图(您也可以抛出IllegalArgumentException
)。
然后,它会检查k
是否等于给定string
的长度,在这种情况下,会返回包含string
和1L
的单例地图。< / p>
最后,如果k < string.length()
,我们会创建一系列整数,从0
(包括)到string.length() - k + 1
(不包括)。然后,这些整数中的每一个都转换为一个子串,该子串从i
的{{1}}位置开始,始终取string
个字符。 (这与您的实现不同,在第一次迭代中,您采用k
个字符,第二次采用0
等。如果我正确理解了您的问题,则您必须始终使用1
个字符,直至到达k
的结尾。
然后,所有这些子串通过string
收集器收集到Map
,该收集器需要一个函数将流的每个元素(这些是你的情况下的子串)映射到键的地图。因为我们希望实际的子串是地图的键,所以我使用了身份功能。 Collectors.groupingBy
只是将每个子字符串的计数作为值。
如果您希望子字符串以Collectors.counting
的相同顺序显示,则可以使用接受地图供应商的string
版本,并告诉它使用Collectors.grouping
1}},保留插入顺序:
LinkedHashMap