从数组中删除点并返回一个新数组 - Java

时间:2013-01-18 21:43:41

标签: java arrays point

  

编写名为removeSomePoints的方法。这个方法需要一个数组   点,并返回一个与数组相同的新数组   原始数组,除了它删除所有具有x-和。的点   相差小于20的y坐标。换句话说,   返回的数组可能比原始数组小   阵列。此方法应保持原始数组不变。至   澄清:如果原始数组中有以下任何一点,   它们不会在返回的数组中。

     

100 90(x和y相差10)

     

90 100(x和y相差10)

     

3 22(x和y相差19)

     

另一方面,以下任何一点都在数组中   返回:

     

100 80(x和y相差20)

     

80 100(x和y相差20)

     

2 25(x和y相差23)

我的代码:

   public static Point[] removeSomePoints(Point[] arr) 
   {

    int count = 0;      
    for (int i = 0; i < arr.length; i++) {
         if (Math.abs(arr[i].getX() - arr[i].getY()) > 19) {
            count++;
          }
         }

        Point[] finalArr = new Point[count];

        for (int i = 0; i < finalArr.length; i++) {
          if (Math.abs(arr[i].getX() - arr[i].getY()) > 19) {
               finalArr[i] = arr[i];
          }

     }

       return finalArr;
    }

似乎无法弄清楚出了什么问题。它返回一个数组,但它不会改变任何东西。

4 个答案:

答案 0 :(得分:1)

好的,所以你的程序目前无法正常工作,因为你在长度为N的输入数组中确定了匹配项的数量(比如M)。现在假设N保证小于M,请注意您正在迭代输入数组的 子集 (长度) N)并将该子集中的任何匹配项复制到输出数组中。这完全是错误的。

我认为这是一个学习项目 - 本课程的关键点在于为您的代码选择合适的数据结构。处理固定大小的集合时,数组很棒,但对于可变大小的集合则不太合适。对于可变数据,列表绝对是可行的方法。

让我们来看看一些伪代码:

public static Point[] removeSomePoints(Point[] arr) {
    // If 'arr' is null, return null
    // If 'arr' is empty, return empty

    // Initialize a variable list structure, of at least arr.length in size
    // For each element in arr
    //     if element matches condition, add to variable list
    // End for
    // 
    // Convert variable list into array and return
}

简而言之,这就是你的算法。将其转换为实际代码:

public static Point[] removeSomePoints(Point[] arr) {
    if(arr == null) return null;
    if(arr.length == 0) return new Point[0];

    List<Point> outputList = new ArrayList<Point>(arr.length);
    for(Point p : arr) {
        if (Math.abs(p.getX() - p.getY()) > 19) outputList.add(p);
    }

    return outputList.toArray(new Point[outputList.size());
 }

不要忘记查看ListArrayList的文档,以便更好地了解它们的工作原理。

答案 1 :(得分:0)

逻辑中的关键缺陷是原始数组中使用了较短的数组索引。

这意味着数组[[90,100],[75,100],[85,100],[80,100]]将首先计算2个有效条目,创建一个大小为2的新数组,然后从原始数据中复制前两个条目数组创建[[90,100],[75,100]]而不是所需的[[75,100],[80,100]]。

一种方法是添加“resizeArray()”函数(例如:http://www.source-code.biz/snippets/java/3.htm),在初始循环期间使用单独的索引(例如“count”)填充新数组,该索引仅在添加时递增到新数组,然后将新数组调整到目标大小。

像这样:

public static Point[] removeSomePoints(Point[] arr)
{
    int count = 0;

    Point[] finalArr = new Point[arr.length];

    for (int i = 0; i < arr.length; i++)
    {
        if (Math.abs(arr[i].getX() - arr[i].getY()) > 19)
        {
            finalArr[count] = arr[i];
            count++;
        }
    }

    return (Point[])resizeArray(finalArr, count);
}

答案 2 :(得分:0)

你的第二个循环应该是:

int j = 0;
for (int i = 0; i < arr.length; ++i) {
   if ((Math.abs(arr[i].getX() - arr[i].getY()) > 19) {
            finalArr[j++] = arr[i];
   }
}

答案 3 :(得分:0)

正如其他人所提到的,问题是由于第二个循环中的逻辑缺陷。您应该迭代原始数组而不是要返回的数组。

使用ArrayListresizeArray的答案都很好。在@ Perception的答案中,ArrayList用作中间数据结构,而在@DreadPirateShawn的答案中,Array用作中间数据结构。最后,它们都将调整为要返回的结果数组。由于不需要随机访问中间数据结构,我宁愿使用LinkedList。使用链接列表不需要任何大小调整,因此可能节省一些时间和空间。

public static Point[] removeSomePoints(Point[] arr) {
    if(arr == null) return null;
    if(arr.length == 0) return new Point[0];

    List<Point> outputList = new LinkedList<Point>();
    for(Point p : arr) {
        if (Math.abs(p.getX() - p.getY()) > 19) outputList.add(p);
    }

    return outputList.toArray(new Point[outputList.size()]);
}