计算数组中出现了多少对数字
Count how many pairs of a number appear in an array
假设数组:
array = {1,2,1,2,1,3,2,1};
我希望输出为:
2 pairs of number 1, 1 pair of number 2
为此我创建了一个哈希 table。代码:
class Trail{
static void countFreq(int arr[], int n)
{
Map<Integer, Integer> mp = new HashMap<>();
// Insert elements into HashTable while avoiding overwriting:
for (int i = 0; i < n; i++)
{
// This part is to avoid overwriting:
if (mp.containsKey(arr[i]))
{
mp.put(arr[i], mp.get(arr[i]) + 1);
}
else
{
mp.put(arr[i], 1);
}
}
// Traverse through map and print frequencies
for (Map.Entry<Integer, Integer> entry : mp.entrySet())
{
System.out.println(entry.getKey() + " " + entry.getValue());
}
}
public static void main(String[] args) {
int arr[] = {1,2,1,2,1,3,2,1};
int n = arr.length;
countFreq(arr, n);
}
}
不确定下一步要做什么才能打印出所需的输出。卡在这个简单的部分好久了
最简单的做法是使用 Map<Integer, Long>
并计算频率。
- 流式传输数组
- 将其装箱(转换为 Integer 对象)
- 根据值
a
分组
- 并计算该值的出现次数
- 在地图中,
k
是值,v
是计数
- 还添加了逻辑以更正数字复数。
int[] vals = {1,2,1,2,1,3,2,1};
Arrays.stream(vals).boxed().collect(
Collectors.groupingBy(a -> a, Collectors.counting()))
.forEach((k, v) -> {
if (v > 1) {
System.out.println(v / 2 + " pair"
+ ((v > 3) ? "s" : "") + " of " + k);
}
});
打印
2 pairs of 1
1 pair of 2
请注意,这利用了整数除法并舍弃了分数。所以任何奇数 n
将具有 (n-1)/2
对的值。
频率的计算似乎没问题,只需要解决打印部分。要获得对数,将频率除以 2(或右移 1),如果对数为 0 则跳过(根据预期输出)。
打印应该移到单独的方法中:
static void printFreq(Map<Integer, Integer> mp) {
boolean addComma = false;
for (Map.Entry<Integer, Integer> entry : mp.entrySet()) {
int pairs = entry.getValue() / 2;
if (pairs < 1) {
continue; // skip 0 pairs
}
if (addComma) {
System.out.print(", ");
}
String p = pairs > 1 ? " pairs " : " pair ";
System.out.print(pairs + p + "of number " + entry.getKey());
addComma = true;
}
System.out.println();
}
但是,Stream API 可用于此类任务:
- 使用 vararg
int ... arr
以更方便的方式传递整数值数组(n
因为数组长度是多余的)
- 使用
Collectors.groupingBy
和Collectors.summingInt
(或Collectors.counting
)计算原始频率
- 计算对数
- 将每个键值对映射到字符串
- 使用 Collectors.joining
连接字符串
static void countFreq(int ... arr) {
String message = Arrays.stream(arr)
.boxed()
.collect(Collectors.groupingBy(
x -> x,
Collectors.summingInt(x -> 1)
)) // Map<Integer, Integer>
.entrySet()
.stream()
.peek(e -> e.setValue(e.getValue() / 2))
.filter(e -> e.getValue() > 0)
.map(e -> String.format("%d %s of number %d",
e.getValue(), e.getValue() > 1 ? "pairs" : "pair", e.getKey()
))
.collect(Collectors.joining(", "));
System.out.println(message);
}
输出(在两种情况下):
2 pairs of number 1, 1 pair of number 2
假设数组:
array = {1,2,1,2,1,3,2,1};
我希望输出为:
2 pairs of number 1, 1 pair of number 2
为此我创建了一个哈希 table。代码:
class Trail{
static void countFreq(int arr[], int n)
{
Map<Integer, Integer> mp = new HashMap<>();
// Insert elements into HashTable while avoiding overwriting:
for (int i = 0; i < n; i++)
{
// This part is to avoid overwriting:
if (mp.containsKey(arr[i]))
{
mp.put(arr[i], mp.get(arr[i]) + 1);
}
else
{
mp.put(arr[i], 1);
}
}
// Traverse through map and print frequencies
for (Map.Entry<Integer, Integer> entry : mp.entrySet())
{
System.out.println(entry.getKey() + " " + entry.getValue());
}
}
public static void main(String[] args) {
int arr[] = {1,2,1,2,1,3,2,1};
int n = arr.length;
countFreq(arr, n);
}
}
不确定下一步要做什么才能打印出所需的输出。卡在这个简单的部分好久了
最简单的做法是使用 Map<Integer, Long>
并计算频率。
- 流式传输数组
- 将其装箱(转换为 Integer 对象)
- 根据值
a
分组
- 并计算该值的出现次数
- 在地图中,
k
是值,v
是计数 - 还添加了逻辑以更正数字复数。
int[] vals = {1,2,1,2,1,3,2,1};
Arrays.stream(vals).boxed().collect(
Collectors.groupingBy(a -> a, Collectors.counting()))
.forEach((k, v) -> {
if (v > 1) {
System.out.println(v / 2 + " pair"
+ ((v > 3) ? "s" : "") + " of " + k);
}
});
打印
2 pairs of 1
1 pair of 2
请注意,这利用了整数除法并舍弃了分数。所以任何奇数 n
将具有 (n-1)/2
对的值。
频率的计算似乎没问题,只需要解决打印部分。要获得对数,将频率除以 2(或右移 1),如果对数为 0 则跳过(根据预期输出)。
打印应该移到单独的方法中:
static void printFreq(Map<Integer, Integer> mp) {
boolean addComma = false;
for (Map.Entry<Integer, Integer> entry : mp.entrySet()) {
int pairs = entry.getValue() / 2;
if (pairs < 1) {
continue; // skip 0 pairs
}
if (addComma) {
System.out.print(", ");
}
String p = pairs > 1 ? " pairs " : " pair ";
System.out.print(pairs + p + "of number " + entry.getKey());
addComma = true;
}
System.out.println();
}
但是,Stream API 可用于此类任务:
- 使用 vararg
int ... arr
以更方便的方式传递整数值数组(n
因为数组长度是多余的) - 使用
Collectors.groupingBy
和Collectors.summingInt
(或Collectors.counting
)计算原始频率 - 计算对数
- 将每个键值对映射到字符串
- 使用 Collectors.joining 连接字符串
static void countFreq(int ... arr) {
String message = Arrays.stream(arr)
.boxed()
.collect(Collectors.groupingBy(
x -> x,
Collectors.summingInt(x -> 1)
)) // Map<Integer, Integer>
.entrySet()
.stream()
.peek(e -> e.setValue(e.getValue() / 2))
.filter(e -> e.getValue() > 0)
.map(e -> String.format("%d %s of number %d",
e.getValue(), e.getValue() > 1 ? "pairs" : "pair", e.getKey()
))
.collect(Collectors.joining(", "));
System.out.println(message);
}
输出(在两种情况下):
2 pairs of number 1, 1 pair of number 2