【问题标题】:Generic types: how to get the most common character from an Generic type array泛型类型:如何从泛型类型数组中获取最常见的字符
【发布时间】:2015-06-08 22:46:08
【问题描述】:

我在 ArrayLists 中苦苦挣扎,我的方法 public static <T> Pair<T, Integer> mode(T items[]) 必须返回最常见的字符(或字符串、整数或双精度)以及在数组中遇到的次数。假设new String[]{"a","b","a"},那么该方法应该返回"a", 2。或者,另一个例子,new Integer[]{30,10,10,20} 应该返回10, 2(数字 10 在数组中出现两次)。请有人引导我到正确的轨道?考虑到我不允许使用 Maps、Collections... 只能使用 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);
      }

    }

【问题讨论】:

  • 嗯,你遇到了什么问题?
  • 我应该如何使用泛型找出最常见的字母或整数? @塔里克
  • 如果您使用的是 Java 8,ArrayList 有一个 sort 方法,可以方便您对项目进行分组和计数。

标签: java arrays generics


【解决方案1】:

你为什么不使用你的 Pair 类的数组列表来模拟地图。

使类型 X 与您匹配的类型相同,然后键入 Y 一个 int。 first 代表字符,Y 代表它出现的次数。

  • 制作ArrayListPair
  • 遍历您的源列表,并在每次迭代时,在您的新 ArrayList 中搜索first 等于您当前元素的元素。
  • 如果找到,请将 1 添加到 second 元素。
  • 如果没有找到,添加一个,将 second 元素初始化为 1。

【讨论】:

  • 感谢@SamIam的回复...为了制作Pair的ArrayList,是不是ArrayList > = new ArrayList() ???
  • @Inferno 你应该可以自己检查一下是否有效
  • @Inferno 你试试会发生什么
【解决方案2】:

假设您会使用此答案来了解如何解决此类问题,而不是公然复制答案以完成您的作业。

由于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 extends Comparable 行确保TComparable。这样做是为了可以使用排序方法对ArrayList&lt;T&gt; 进行排序。

接下来,在mode 函数中,我首先检查ArrayList&lt;T&gt; itemsnull 还是其中有0 项。如果是这种情况,我会抛出适当的异常。

接下来我对items 进行排序。因此,如果ArrayList 属于Integers 并且项目是10, 20, 10,那么在排序之后它将是10, 10, 20

那么我假设计数最大的元素是第一个元素。

在此之后,我循环遍历项目以查看下一个项目是否等于前一个项目。如果是,我增加itemCount。如果不是,我检查maxCount 是否小于itemCount。如果是这种情况,那么我更新我的maxItemcurrentItemmaxCount,并重置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]

正如预期的那样,除非我读错了你的问题。

【讨论】:

  • @Tarik:好吧,至少我对这个答案有一个有趣的评论。哈哈。当我回答它时,我并没有真正期待任何声誉点。事实上,我更高兴我没有得到任何反对票。哈哈。新来者往往会提出此类问题,而这里的旧帽子通过对此类问题投反对票来制造进入壁垒。诚然,有些人只是为了他们的任务而来到这里,并不真正关心这些概念,但事实是他们都不知道如何解决这个问题,否则他们一开始就不会问这个问题。因此,我试图用我的回答来解释这种方法。
  • 你说的是真的。所以通常是无情的。在帮助和彻底做作业之间取得平衡并不明显。也许我们应该通过逐步引导人或通过指向相关资源来处理这种情况。
【解决方案3】:

这是一个不使用任何对象,只使用方法的(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());
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-17
    • 1970-01-01
    • 2020-12-05
    • 2011-01-24
    • 1970-01-01
    • 2019-01-20
    相关资源
    最近更新 更多