在最近的采访中,我被要求为下面的String操作程序找到解决方案。 给定一个字符串s,表示最常用的字符为1,第二个最常用的字符为01,第三个为001等。
如果String是" marrymyyyr",那么输出应为:
每个字符的字符数为m:2,a:1,r:3,y:4最高计数 number为4,因此具有该计数的字符应打印1 在该char的位置,具有计数3的char应打印为01 取而代之的是等等。
输出:001(m)0001(a)01(r)01(r)1(y)001(m)1(y)1(y)1(y)01(r)
我使用HashMap跟踪每个角色的计数。然后我无法解决问题。我知道我必须实现一些机制,将哈希/映射应用于hashmap,这是基于最常见的char映射,其对应结果字符串与" 1" " 0"并使用映射的结果字符串而不是该字符串打印char。
答案 0 :(得分:0)
你说你用HashMap
。如果您将地图创建为Map<Character, AtomicInteger>
,则可以直接更新该值,而不会影响地图。
这样可以提高过程计数步骤的性能,但也可以让您更换&#34; count&#34;值,其值表示要为字符打印的0的数量,即a&#34; rank&#34;。
示例:如果计数为m:2, a:1, r:3, y:4
(来自问题),则会对列表降序排序(y:4, r:3, m:2, a:1
),然后使用递增排名替换计数:y:0, r:1, m:2, a:3
。
如果您使用LinkedHashMap
,那么具有相同计数的多个字符将按首次出现的顺序排列。
使用这些排名,您现在可以转换输入。 (以下是适用于任何Java版本。在Java 8上,lambdas会大量减少代码。我将把它作为练习留给你。)
private static String test(String input) {
char[] chars = input.toCharArray();
// Collect chars with count of occurrences
Map<Character, AtomicInteger> charMap = new LinkedHashMap<>();
for (Character c : chars) {
AtomicInteger count = charMap.get(c);
if (count == null)
charMap.put(c, new AtomicInteger(1));
else
count.incrementAndGet();
}
// Sort char/count pairs by count (descending)
@SuppressWarnings("unchecked")
Entry<Character, AtomicInteger>[] charArr = charMap.entrySet().toArray(new Map.Entry[charMap.size()]);
Arrays.sort(charArr, new Comparator<Entry<Character, AtomicInteger>>() {
@Override
public int compare(Entry<Character, AtomicInteger> e1, Entry<Character, AtomicInteger> e2) {
return Integer.compare(e2.getValue().intValue(), e1.getValue().intValue()); // descending
}
});
// Replace "count" with "rank" (this updates values in charMap)
for (int i = 0; i < charArr.length; i++)
charArr[i].getValue().set(i);
// Generate result
StringBuilder buf = new StringBuilder();
for (Character c : chars) {
int rank = charMap.get(c).intValue();
while (rank-- > 0)
buf.append('0');
buf.append('1');
buf.append('(').append(c).append(')'); // Remove?
}
return buf.toString();
}
<强>测试强>
System.out.println(test("marrymyyyr"));
<强>输出强>
001(m)0001(a)01(r)01(r)1(y)001(m)1(y)1(y)1(y)01(r)
问题的措辞使得听起来像字母应该被替换(&#34;取代&#34;)。如果是,请注释掉或删除标有// Remove?
<强>输出强>
00100010101100111101