1

我正在尝试查看带有金额的名称列表。

一个数组包含此人的姓名,另一个数组包含此人给的金额,即 john, 55 sally 40 john 33 sarah 55。

我的目标是汇总相似的姓名并打印出此人的姓名和给出的总金额。

约翰给了两次,所以他的总数应该是 88。但我得到了正确的结果,但我的程序打印了两次名称。所以 john 88 打印了两次......我知道这很可能是因为我把它放在第一个 for 循环中,它迭代了数组的整个长度。

但我不确定如何解决这个问题?

import java.util.*;

public class chapterfive {
    public static void main (String[]args) {
       Scanner in = new Scanner (System.in);
       String[]names = new String[4];
       int[] scores = new int[4];
       for (int i = 0; i<names.length; i++) {
           names[i] = in.next();
           scores[i] = in.nextInt();
       }
       int amount = 0;
       String firstname = "";

       for (int i = 0; i < names.length; i++) {
           for (int j=0; j < names.length; j++) {

               if (names[j].equals(names[i]))
                   amount += scores[j];
           }

       System.out.println(names[i] + "  " + amount);
       amount = 0;
       }
    }
}
4

4 回答 4

1

您可以看到它们具有 Name -> Score 之类的关系,因此,如果您认为更抽象,这是一个具有 Key (Name) 和 Value (Score) 的字典,因此您可以使用其他数据结构,例如 aMap或者您可以使用 an数组并创建一个类 Person ,拥有 arrayOrderer 并在添加新人时检查该人是否存在于数组中。

例子 :

Map <String , Integer> people = new HashMap<>();
     for (int i=0; i<lengthYouWant; i++)
           {
               String name=in.next();
               int score=in.nextInt();

               if(people.contains(name)){
                 score= people.get(name)+score;
               }
                people.put(name,score);
           }
于 2013-06-27T02:42:02.647 回答
0

如果你创建一个 Person 类的数组或列表,你可以实现 Comparable 并添加一个方法来帮助排序。

于 2013-06-27T02:50:17.090 回答
0

Java 是一种面向对象的语言,这意味着除其他外,您可以创建自己的数据结构。使用并行数组很容易出错,并且它会将您想要保存在一起的数据分开。那么,你需要什么来组织这个?

首先是一种存储名称和金额的方式。调用它Donation

class Donation {
    private final String name;
    private final int    amount;
    public Donation(String name, String amount) {
        this.name = name;
        this.amount = amount;
        // EXERCISE: Add error checking.
    }
    public String getName()   { return name;   }
    public int    getAmount() { return amount; }
    public String toString() {
        return "Name: " + name +", amount: " + amount;
    }
}

注意这个类的变量是最终的;它们一旦设置就无法更改。它们在构造函数中设置,并且有 get 方法和 toString 方法来替换您在System.out.println语句中的内容。

接下来,您需要一种存储数据的方法。不要使用数组。 Lists 更灵活。

private static List<Donation> donations = new ArrayList<Donation>();

// and in main:

while (true) {
    String name = null;
    int amount = 0;
    if (in.hasNext()) {
        name = in.next();
    } else {
        break;
    }
    if (in.hasNextInt()) {
        amount = in.nextInt();
    } else {
        break;
    }
    donations.add(new Donation(name, amount));
}   See -- no 4s.

接下来,您需要合并重复的捐赠。我的意思是,有些人每个星期天都会给他们的教堂捐款。我们将使用适当的结构, a Map

// Also in main:
Map<String, Integer> totals = new HashMap<>();
for(Donation d: donations) {
    String name = d.getName();
    int amount = d.getAmount();
    if (!totals.containsKey(name)) {
        totals.put(name, 0);
    }
    int currentDonation = totals.get(name);
    totals.put(name, currentDonation + amount);
}

最后,您遍历地图并打印每个条目。

for ( Map.Entry<String, Integer> entry: totals.entrySet()) {
    System.out.println(entry.getKey() + ": " + entry.getValue());
}

现在,另一个练习和策略:停止在main. 给你的ChapterFive类实例变量和方法。然后,为这些编写测试。尝试对我的建议进行改进。然后,看看是否有图书馆可以帮助你。

于 2013-06-27T03:06:02.157 回答
0

应该使用 Map 来简化事情,而不是跟踪两个数组。但这是一个可能有效的修复程序(尚未测试)

   String firstname = "";

   for (int i = 0; i < names.length; i++) {
       int amount = 0;
       boolean skip = false;

       for (int j=0; j < names.length; j++) {
          //need to skip because we have already processed it
          if(names[j].equals(names[i]) && i > j) {
              skip = true;
              break;
          } 
          else if (names[j].equals(names[i])) {
               amount += scores[j];
          }
       }
       if(!skip) {
         System.out.println(names[i] + "  " + amount);
       }
   }
于 2013-06-27T04:04:07.233 回答