【问题标题】:Display elements without redundancy in an array显示数组中没有冗余的元素
【发布时间】:2013-03-11 20:27:54
【问题描述】:

我编写了这段代码。我认为这是错误的。

public void display() {
    for (int i = 0; i < tabT.length; i++)
        if (tabT[i] != null)
            for (int j = 0; j <= i; j++)
                if (tabT[i] != tabT[j])
                    System.out.println(tabT[i].getCar());
}

如何在数组中显示没有冗余的元素?

【问题讨论】:

    标签: java arrays algorithm redundancy


    【解决方案1】:

    如果你只想使用数组,你可以这样做:

    创建一个临时(辅助)数组,其中将包含到目前为止在tabT 中看到的每个元素。然后,在打印该值之前,检查它是否没有出现在辅助数组 (tmp) 中。

    例如,如果您在 tabT 中有值,并且您不想多次打印每个值:

    int[] tabT = {1,2,3,1,1,2,6,7,2,7,1};
    int[] tmp = new int[tabT.length];
    boolean flag;
    for (int i = 0; i < tabT.length; i++) {
        tmp[i] = tabT[i];
        flag = true;
        for (int j = 0; j < tmp.length; j++)
            if (tabT[i] == tmp[j] && i!=j) {
                flag = false;
            }
        if(flag)
            System.out.println(tabT[i]);
    }
    

    输出:[1,2,3,6,7]

    您可以轻松地将这个想法应用到您的程序中,并且每个元素只打印一次:

    Cars[] tmp = new Cars[tabT.length]; //Assuming tabT is from type Cars[]
    boolean flag = true;
    for (int i = 0; i < tabT.length; i++) { 
        tmp[i] = tabT[i];
        if (tabT[i] != null) {
            for (int j = 0; j < tmp.length; j++)
                if (tabT[i].getCar().equals(tabT[j].getCar()) && i!=j)
                    flag = false;
            if(flag)
                System.out.println(tabT[i].getCar());
        }
    }
    

    这将只打印每辆车(或您要打印的任何东西)一次。

    【讨论】:

    • 谢谢,但这里的“tmp”不是空的吗?那我怎样才能删除数组呢?
    • 这里有问题。 if (tabT[i].getCar().equals(tabT[j].getCar()) && i != j)
    • 你应该知道如何处理它。我给了你一个很好的想法。你的工作是做些小改动以使其发挥作用。我不知道你的类和变量。
    • 我认为是 tmp[j].getCar().equals .. 不是 tabT[i].getCar().equals
    • 我以另一种方式找到了它。还是谢谢你:)
    【解决方案2】:

    通过equals()比较的对象例如

    if (!tabT[i].equals(tabT[j]))
    

    您是在比较参考值而不是对象

    for (int i=0; i< tabT.length; i++) {
      boolean f = false;
      for (int j=i+1; j <tabT.length; j++)
        if (tabT[i].equals(tabT[j])) {
          f=true;
          break;
        }
      if (!f)
        System.out.println(tabT[i].getCar());
    }
    

    这应该为您提供ij 的所有组合不重复,因此我们不会多次比较它们。

    【讨论】:

    • 这仍然会多次打印每个项目(如果出现多次..)
    【解决方案3】:

    ==!= 在对象级别测试相等性(即如果两个实例相同)。你需要的是比较每个对象所代表的值(例如两个字符串是否相等),那么你需要问!tabT[i].equals(tabT[j])是否,并使tabT的元素实现equals)。

    或者将数组转换为一个集合,从而删除重复项。

    T[] tabT = ...
    Set<T> set = new LinkedHashSet<T>(Arrays.asList(tabT))
    for (T t:set) System.out.println(t);
    

    我使用了LinkedHashSet,因为它保留了数组中元素的顺序。注意需要实现equalshashcode

    【讨论】:

      【解决方案4】:

      将 tabT 数组放入一个 Set 中。不会有重复的项目。

      Set tabTList = new HashMap(Listjava.util.Arrays.asList(tabT);
      

      【讨论】:

      • 在练习中,我应该在数组中有重复的项目,但是当我显示它们时,它应该没有冗余。
      • @mpluse:您始终可以转换为集合以删除重复项并保持原始集合不变
      【解决方案5】:

      为什么不尝试这样的事情呢? (我假设您正在使用字符串类型)

      HashSet<String> hashSet = new HashSet<String>();
      
      for (int i = 0; i < tabT.length; i++) {
          hashSet.add(tabT[i]);
      }
      

      您不能将重复项放入一个集合中,因此现在您可以迭代该集合以获取唯一性。

      java.util.Iterator<String> iterator = hashSet.iterator();
      
      while (iterator.hasNext()) {
          System.out.println((String)iterator.next());
      }
      

      【讨论】:

        【解决方案6】:

        如果您确实想跟踪重复计数,可以考虑使用 HashMap。遍历数组一次以将对象放入具有各自计数的 HashMap 中。然后遍历数组再次检查HashMap。这将是 O(n) 时间,而不是潜在的 O(n^2)

        【讨论】: