我正在与ArrayLists斗争,我的方法public static <T> Pair<T, Integer> mode(T items[])
必须返回最常见的字符(或String,或Integer,或Double)以及在数组中遇到的次数。假设new String[]{"a","b","a"}
,方法应该返回"a", 2
。或者,另一个示例,new Integer[]{30,10,10,20}
应该返回10, 2
(数组10中的数字10会被满足)。请有人指导我到正确的轨道?考虑到我不允许使用地图,收藏......只有ArrayLists!
import java.util.ArrayList;
public class Mode {
public static <T> Pair<T, Integer> mode(T items[])
{
ArrayList<T> trackItems = new ArrayList<>();
for(T values: items)
{
trackItems.add(values);
}
for(int i = 0; i < trackItems.size(); i++)
{
int count = (Integer)trackItems.get(i);
}
}
}
public class Pair<X,Y>{
private X first;
private Y second;
public Pair(X x, Y y){
this.first = x;
this.second = y;
}
public X getFirst(){
return this.first;
}
public Y getSecond(){
return this.second;
}
public boolean equals(Object o){
if(!(o instanceof Pair)){
return false;
}
Pair p = (Pair) o;
return
this.first.equals(p.first) &&
this.second.equals(p.second);
}
public String toString(){
return String.format("(%s,%s)",first,second);
}
}
答案 0 :(得分:0)
为什么不使用您Pair
类的数组列表来模拟地图。
使类型X
与您要匹配的类型相同,并键入Y
一个int。 first
代表字符,Y
代表字符发生的次数。
ArrayList
Pair
first
等于您当前元素的元素。second
元素中添加1。second
元素初始化为1。答案 1 :(得分:0)
假设您使用此答案来理解如何处理此类问题,并且如果是这种情况,则不要公开复制答案以完成作业。
由于Pair
类的第二个参数仅为Integer
,因此为了简单起见,我将其定义如下:
public class Pair<T>
{
private T value;
private int count;
public Pair (T value, int count)
{
this.value = value;
this.count = count;
}
@Override
public String toString ()
{
return String.format ("Pair: [%s, %s]", value, count);
}
}
现在,Mode
类:
import java.util.ArrayList;
import java.util.Comparator;
public class Mode
{
public static <T extends Comparable> Pair<T> mode (ArrayList<T> items) throws Exception
{
if (items == null)
{
throw new NullPointerException ("Items Can't be Null");
}
else if (items.size () == 0)
{
throw new Exception ("Items needs to be more than 0");
}
items.sort (Comparator.<T>naturalOrder ());
int maxCount = 1;
int itemCount = 0;
T maxItem = items.get (0);
T currentItem = items.get (0);
for (T item : items)
{
if (item.equals (currentItem))
{
itemCount++;
}
else if (itemCount > maxCount)
{
maxCount = itemCount;
itemCount = 0;
maxItem = currentItem;
currentItem = item;
}
}
return new Pair<T> (maxItem, maxCount);
}
}
在此,我使用T
行确保Comparable
为T extends Comparable
。这样做是为了可以使用排序方法对ArrayList<T>
进行排序。
接下来,在mode
函数中,我首先检查ArrayList<T> items
是null
还是0
项。如果是这种情况,我会抛出适当的例外。
接下来我对items
进行排序。因此,如果ArrayList
属于Integer
且项目为10, 20, 10
,那么在排序后它将为10, 10, 20
。
然后我假设具有最大计数的元素是第一个元素。
在此之后,我遍历项目以查看下一个项目是否等于上一个项目。如果是,我增加itemCount
。如果不是,我会检查maxCount
是否小于itemCount
。如果是这种情况,请更新我的maxItem
,currentItem
和maxCount
,然后重置itemCount
并重复此过程。
循环结束后,我会在maxItem
中拥有频率最高的值,maxCount
将保持该频率。
以下是一个示例测试来演示它:
import java.util.ArrayList;
import java.util.Arrays;
public class Main
{
public static void main (String[] args) throws Exception
{
ArrayList<Integer> integers = new ArrayList<> (Arrays.asList (10, 20, 10));
System.out.println (Mode.mode (integers));
ArrayList<String> strings = new ArrayList<> (Arrays.asList ("a", "b", "a", "a"));
System.out.println (Mode.mode (strings));
}
}
输出结果为:
Pair: [10, 2]
Pair: [a, 3]
除非我把你的问题读错了,否则这是预期的。
答案 2 :(得分:0)
这里是一个(1,虽然很长,线)解决方案,它不使用任何对象,只是方法:
public static <T> Pair<T, Integer> mode(T[] items) {
return Arrays.stream(items)
.collect(Collectors.groupingBy(o -> o, Collectors.counting()))
.entrySet().stream()
.sorted((a, b) -> b.getValue() - a.getValue())
.findFirst().get()
.map(e -> new Pair(e.getKey(), e.getValue());
}