【问题标题】:Find numbers with different absolute value in an array using java使用java在数组中查找具有不同绝对值的数字
【发布时间】:2016-07-12 04:11:24
【问题描述】:

我正在尝试编写一个打印出具有唯一绝对值的数字的程序。 这是我的尝试:

import java.util.*;
public class MyClass {

     static ArrayList<Integer> aCopy;

    public static void main(String[] args)

    {
        int myArray[]= {-5, 4,-6,8,-4,6,13};

        System.out.println(Arrays.toString(myArray));

        aCopy = new ArrayList<>();
        for(int i=0; i<myArray.length; i++)
        { aCopy.add(myArray[i]); }

       System.out.println("Numbers with unique abs. value are:");
       findDifferentAbsoluteValues(myArray);
       System.out.println(aCopy);   
    }

     public static boolean findDifferentAbsoluteValues (int[] anArray)  
     {      
      for (int i=0; i<anArray.length;i++)
      {
        for(int j=i+1;j<anArray.length; j++)
        {
            if ( Math.abs(anArray[i]) == Math.abs(anArray[j]) ) 
            {
            aCopy.remove(anArray[i]);
            return false;
            }           
        }
      }
      return true;
     } 
}

但它给出了不正确的输出。我(还)不是很流利地使用java,所以这不是我主要关心的问题,而是解决方案很优雅,只需要它工作))任何人都可以解释一下有什么问题吗?

【问题讨论】:

  • 请在您的问题中包含实际输出和所需输出

标签: java arrays loops absolute


【解决方案1】:

在 Java 8+ 中,您可以使用 IntStream.map(IntUnaryOperator) 获取绝对值,然后使用 IntStream.distinct() 获取唯一值,最后使用 IntStream.forEach(IntConsumer) 来打印它。比如,

int[] myArray = { -5, 4, -6, 8, -4, 6, 13 };
IntStream.of(myArray).map(Math::abs).distinct().forEach(System.out::println);

【讨论】:

  • 解决问题的好答案(+1),但 OP 显然在基础知识方面苦苦挣扎,所以我认为这对他没有多大帮助......
  • 此方法创建一个IntPipeline,其distinct 方法注释:“虽然功能强大且实施快速,但此方法效率不高。高效的版本需要特定于int 的map/set 实现。 "
  • @AustinD 非常感谢您的评论!但是,这是关于当前实现的说明,在 IntStreams 上使用 distinct 应该不会特别低效。
【解决方案2】:

我理解你想取一系列不同的绝对值的问题。 第一个错误

aCopy.remove(anArray[i]);

它不能删除这些,它们具有相同的值。您会找到相同的值,但 anArray[i] 不值得删除。例如:i=1 anArray[1]= 4. 你将删除这个

aCopy.remove(4);/* because anArray[1] = 4*/

第二个错误不返回false。因为循环没有完成。

我通过以下方式理解问题和答案;

 public static void main(String[] args)
    {
        int myArray[]= {-5, 4,-6,8,-4,6,13};

    System.out.println(Arrays.toString(myArray));

    aCopy = new ArrayList<>();

   System.out.println("Numbers with unique abs. value are:");
   findDifferentAbsoluteValues(myArray);
   System.out.println(aCopy);     
}

public static void findDifferentAbsoluteValues (int[] anArray)  
{      
     for (int i=0; i<anArray.length;i++)
     {
         Boolean dif =true;
       for(int j=i+1;j<anArray.length; j++)
       {
           if ( Math.abs(anArray[i]) == Math.abs(anArray[j]) ) 
           {
               dif = false;
           }           
       }
       if(dif == true)
       aCopy.add(anArray[i]); //if you want absolute value aCopy.add(Math.abs(anArray[i])) 
     }
    }

【讨论】:

  • 不错,但你真的不应该将无用的boolean 作为返回值和static 数组。只需让函数返回 void 并将副本作为参数。
【解决方案3】:

您的(主要)问题是您的函数findDifferentAbsoluteValues 在删除第一个“重复项”后停止,并且您正在迭代列表中删除不小心的元素。以下是一些可以帮助您改进代码的建议:

  • 您需要保留原始数组吗?如果不这样做,请直接使用ArrayList 代替myArray,不要复制它
  • 无论您是否需要保留该原始数组,您的函数都应直接将您的 ArrayList 作为参数,而不是对全局 (static) 变量进行操作
  • 你不需要你的函数的结果,所以findDifferentAbsoluteValues应该返回void

对于你的函数findDifferentAbsoluteValues中的算法:

  • 它不应该在第一次找到两个绝对值相同的整数时停止
  • 尝试逐步查看(或者更好,在调试器的帮助下)您的函数在示例中做了什么来发现问题

编辑:以下是解决方案的示例:

import java.util.ArrayList;
import java.util.Arrays;

public class MyClass {
    // You don't need a global variable here
    public static void main(String[] args)
    {
      Integer[] myArray = {-5, 4, -6, 8,-4, 6, 13, 4, 4};
      // Copy the array using the constructor of ArrayList on a collection
      ArrayList<Integer> aCopy = new ArrayList<Integer>(Arrays.asList(myArray));

      System.out.println("Original array: " + Arrays.toString(myArray));
      findDifferentAbsoluteValues(aCopy);
      System.out.println("Numbers with unique abs. value are: " + aCopy);
    }

    // Takes an array as argument and works on it directly.
    // Returns void since no return value is necessary.
    public static void findDifferentAbsoluteValues (ArrayList<Integer> anArray)  
    {
      for (int i = 0; i < anArray.size(); i++)
          for (int j = i + 1; j < anArray.size(); j++)
              if (Math.abs(anArray.get(i)) == Math.abs(anArray.get(j)))
                  // Removes the second one and decrement to avoid forgetting any element
                  anArray.remove(j--);
    }
}

【讨论】:

    【解决方案4】:

    在方法findDifferentAbsoluteValues这里aCopy.remove(anArray[i]);首先你必须找到要删除的元素的索引,然后删除它,否则它可以给ArrayIndexOutOfBoundsException

    if ( Math.abs(anArray[i]) == Math.abs(anArray[j]) ) 
    {
         aCopy.remove(anArray[i]);
         return false;
    }  
    

    您在找到不正确的匹配后从函数返回,因为您还必须继续检查其他数字。 所以用break语句替换return。同时去掉boolean返回类型,因为它没用,把它改成void,因为你没有在任何地方使用返回值。

    public static void findDifferentAbsoluteValues (int[] anArray)

    您的代码应如下所示:

    public static void findDifferentAbsoluteValues (int[] anArray)  
     {      
          for (int i=0; i<anArray.length;i++)
          {
            for(int j=i+1;j<anArray.length; j++)
            {
                if ( Math.abs(anArray[i]) == Math.abs(anArray[j]) ) 
                {
                aCopy.remove(aCopy.indexOf(anArray[i]));
                break;
                }           
            }
          }
     }
    

    它对我有用。

    【讨论】:

    • 是否有“删除负分和 cmets 的答案并重新回答而不是编辑”的徽章? ;-) 顺便说一句,您的回答仍然存在与@JuniorDevelepor 相同的问题。
    【解决方案5】:

    你们都是对的。我搞砸了内部循环,因为我想到了我前段时间写的一个函数,它检查一个数字是否为素数,因此使用 return 语句是有意义的。 非常感谢所有回复我帖子的人。复活节快乐!

    【讨论】:

      猜你喜欢
      • 2020-02-11
      • 2018-12-25
      • 1970-01-01
      • 2012-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多