在2d数组java中计算次数

时间:2013-10-09 08:56:11

标签: java arrays

我有这个2d数组

**Client| Status** 

    FAI | deferred
    SDE | Bounced
    FAI | Bounced
    SDE | Bounced
    SDE | deferred
    FAI | deferred

我想做的是创建一个函数,它可以产生某种统计输出: EX:

FAI --> Deferred 66 % , Bounced 34 %
SDE --> Deferred 34 % , Bounced 66%

N.B。 对于第一列,有很多可能的客户端,但对于第二列,我只有这两种状态。

我想要创建的函数是一个计算第一列元素出现次数的函数,然后为每个客户端查看每次出现的状态(如果它是Bounced或者被引用),d为客户端生成统计信息。 / p>

这里我真的不知道如何开始我的功能,所以任何想法,任何建议都是受欢迎的,并会帮助我。 谢谢!

2 个答案:

答案 0 :(得分:0)

您必须列出所有客户。然后,您可以计算每个客户拥有的被拒绝和退回的数量。 这是我的解决方案。它不是最好的方法,但它的工作原理!输出是:

FAI - >减少67%,反弹33%

SDE - >减少33%,反弹67%

  public static void main(String[] args) throws InterruptedException {

      String[][] client_status = new String[6][2];
      client_status[0][0] = "FAI";
      client_status[0][1] = "deffered";
      client_status[1][0] = "SDE";
      client_status[1][1] = "Bounced";
      client_status[2][0] = "FAI";
      client_status[2][1] = "Bounced";
      client_status[3][0] = "SDE";
      client_status[3][1] = "Bounced";
      client_status[4][0] = "SDE";
      client_status[4][1] = "deffered";
      client_status[5][0] = "FAI";
      client_status[5][1] = "deffered";


      List<String> clients = new ArrayList<String>();

      int allDeffered = 0;
      int allBounced = 0;

      for(int i = 0; i < client_status.length; i++) {
          if(!clients.contains(client_status[i][0])) {
              clients.add(client_status[i][0]);
          }  
      }

      Integer[] clientDeffered = new Integer[clients.size()];
      Integer[] clientBounced = new Integer[clients.size()];

      int k = 0;
      for(String client : clients) {
          for(int j = 0; j<client_status.length; j++) {
              if(client_status[j][0].equals(client)&&client_status[j][1].equals("deffered")) {
                  if(clientDeffered[k]==null) {
                      clientDeffered[k]=1;
                  }
                  else {
                      clientDeffered[k]++;
                  }
                  allDeffered ++;
              }
              if(client_status[j][0].equals(client)&&client_status[j][1].equals("Bounced")) {
                  if(clientBounced[k]==null) {
                      clientBounced[k]=1;
                  }
                  else {
                      clientBounced[k]++;
                  }
                  allBounced ++;

              }
          }
          k++;
      }
      for(int l = 0; l<clients.size(); l++) {
          double a = clientDeffered[l];
          double b = allDeffered;
          double c = clientBounced[l];
          double d = allBounced; 
          System.out.println(clients.get(l) +" --> Deffered " +Math.round((a/b)*100) + " % , Bounced " +Math.round((c/d)*100) + "%");
      }   
  }

答案 1 :(得分:0)

使用HashMap(或Map接口的任何其他实现)来有效地解决您的问题(@kai解决方案没问题,但它是O(N ^ 2))。此示例不是通用的,只有在网格的第二列(数据矩阵)中,您才有两个可能的值(deffered和bounced)。解决方案以这种方式工作:我们迭代数据矩阵中的行并检查当前实体(按名称表示 - 网格的第一列)是否已经在hashmap中。如果是,只需增加该实体百分比(inc实体类的方法),否则我们必须首先创建实体的新实例,将其添加到hashmap而不是增加百分比。打印类似(因为我们需要按照它们在矩阵中出现的相同顺序打印名称):我们再次遍历数据和打印实体对象(这就是覆盖toString方法的原因)。使用了Entity类中的isVisitedMember attr,因为我们只想打印每个实体一次。

import java.util.HashMap;

public class HelloWorld{
 static class Entity {
    private String name;
    private int countFirst;
    private int countSecond;
    private boolean isVisitedMember; // because we want to print in same order as in original matrix

    public Entity(String name) {
        this.name = name;
        countFirst = 0;
        countSecond = 0;
        isVisitedMember = false;
    }

    public void inc(String status) {
        if (status.toLowerCase().equals("deferred")) {
            ++countFirst;
        }
        else {
            ++countSecond;   
        }
    }

    public boolean isVisited() {
        return isVisitedMember;
    }

    public void setIsVisited(boolean value) {
        isVisitedMember = value;
    }

    public float getFirstPercent() {
        return (float)countFirst / (countFirst + countSecond) * 100;
    }

    public float getSecondPercent() {
        return (float)countSecond / (countFirst + countSecond) * 100;
    }

    @Override
    public String toString() {
        if (countFirst <= countSecond) {
            int first = (int)Math.ceil(getFirstPercent());
            return String.format("%s --> Deferred %d %% , Bounced %d %%", name, first, 100 - first);
        }

        int second = (int)Math.ceil(getSecondPercent());
        return String.format("%s --> Deferred %d %% , Bounced %d %%", name, 100 - second, second);
    }
 }


 public static void main(String []args){
    String[][] data = {
        { "FAI", "deferred" },
        { "SDE", "Bounced" },
        { "FAI", "Bounced" },
        { "SDE", "Bounced" },
        { "SDE", "deferred" },
        { "FAI", "deferred" },
    };

    HashMap<String, Entity> map = new HashMap<String, Entity>();
    for (int i = 0; i < data.length; ++i) {
        String name = data[i][0];
        String value = data[i][1];
        Entity entity = map.get(name);
        if (entity == null) {
            entity = new HelloWorld.Entity(name);
            map.put(name, entity);
        }

        entity.inc(value);
    }

    // print in same order as in original matrix
    for (int i = 0; i < data.length; ++i) {
        String name = data[i][0];
        Entity entity = map.get(name);
        if (entity.isVisited()) {
            continue;
        }

        entity.setIsVisited(true);
        System.out.println(entity);
    }        
 }

}