IndexOutOfBoundsException在Java中的String ArrayList上实现Merge排序

时间:2016-05-21 02:16:28

标签: java

我正在尝试在字符串数组列表上使用合并排序,但我收到错误:

  

java.lang.IndexOutOfBoundsException:Index:0,Size:0

它正在杀了我。有人可以帮帮我,告诉我我做错了什么:

ArrayList<String> input = new ArrayList();
public void mergeSort(ArrayList<String> a, int first, int last)
{
      if(first == last)
      {
         return;
      }
      int mid = (first+last)/2;
      mergeSort(a, first, mid);
      mergeSort(a, mid+1, last);
      merge(a, first, mid, last);   
}
   public void merge(ArrayList<String> a, int firstLeft, int lastLeft, int lastRight)
{
      //Create a temporary ArrayList to do the merging
      ArrayList<String> temp = new ArrayList();

      //Merge elements and put them in the temporary arraylist
      int firstRight = lastLeft + 1; //first index of right array
      int indexLeft = firstLeft; //index for left array
      int indexRight = firstRight; //index for right array
      int indexTemp = indexLeft; //index for merged array

      while(indexLeft <= lastLeft && indexRight <= lastRight)
      {
         if((a.get(indexLeft).compareTo(a.get(indexRight)))<0)
         {
            temp.set(indexTemp++,(a.get(indexLeft++)));
         }
         else
         {
            temp.set(indexTemp++,(a.get(indexRight++)));
         }
      }
      while(indexLeft <= lastLeft)
      {
          temp.set(indexTemp++,(a.get(indexLeft++)));
      }
      while(indexRight <= lastRight)
      {
          temp.set(indexTemp++,(a.get(indexRight++)));
      }
      //copy the sorted array back to the original array
      a = temp;
}

功能调用:

ArrayList<String> input = new ArrayList();
mergeSort(input, 0, (input.size()-1));

ArrayList输入具有未排序的值;
当我输出输入arraylist的大小时,它给了我7373。

2 个答案:

答案 0 :(得分:1)

之所以发生这种情况,是因为您试图在列表中设置一个尚不存在的索引 - temp.set(indexTemp++,(a.get(indexRight++))); 列表api不允许这样做。相反,你必须使用方法add。

但是,你的代码在设计上有问题 - 在递归中覆盖with temp是错误的(你只是将方法指针覆盖到a)

您必须返回合并列表:

public List<String> mergeSort(List<String> a)
{
    if(a.size() <= 1)
    {
        return a;
    }

    int mid = a.size() / 2;
    List<String> left = a.subList(0, mid);
    List<String> right = a.subList(mid, a.size());

    return merge(mergeSort(left), mergeSort(right));
}

public List<String> merge(List<String> left, List<String> right)
{
    ArrayList<String> temp = new ArrayList<>(left.size() + right.size());

    int indexLeft = 0; //index for left array
    int indexRight = 0; //index for right array

    while(indexLeft < left.size() && indexRight < right.size())
    {
        if((left.get(indexLeft).compareTo(right.get(indexRight))) < 0)
        {
            temp.add(left.get(indexLeft++));
        }
        else
        {
            temp.add(right.get(indexRight++));
        }
    }
    while(indexLeft < left.size())
    {
        temp.add(left.get(indexLeft++));
    }
    while(indexRight < right.size())
    {
        temp.add(right.get(indexRight++));
    }

   return temp;
}

答案 1 :(得分:0)

我对您的代码进行了一些更改,我认为它有效:

  • 方法未传递任何列表,这些列表正在使用input实例列表
  • 临时列表以输入内容开始,以避免IndexOutOfBoundsException
public void merge() {
    mergeSort( 0, input.size() - 1);
}


public void mergeSort(int first, int last)
{
      if(first == last)
      {
         return;
      }
      int mid = (first+last)/2;
      mergeSort(first, mid);
      mergeSort(mid+1, last);
      merge(first, mid, last);   
}
public void merge(int firstLeft, int lastLeft, int lastRight)
{
      //Create a temporary ArrayList to do the merging
      ArrayList<String> temp = new ArrayList(input);

      //Merge elements and put them in the temporary arraylist
      int firstRight = lastLeft + 1; //first index of right array
      int indexLeft = firstLeft; //index for left array
      int indexRight = firstRight; //index for right array
      int indexTemp = indexLeft; //index for merged array

      while(indexLeft <= lastLeft && indexRight <= lastRight)
      {
         if((input.get(indexLeft).compareTo(input.get(indexRight)))<0)
         {
            temp.set(indexTemp++,(input.get(indexLeft++)));
         }
         else
         {
            temp.set(indexTemp++,(input.get(indexRight++)));
         }
      }
      while(indexLeft <= lastLeft)
      {
          temp.set(indexTemp++,(input.get(indexLeft++)));
      }
      while(indexRight <= lastRight)
      {
          temp.set(indexTemp++,(input.get(indexRight++)));
      }
      //copy the sorted array back to the original array
      input = temp;
}

现在,我们可以使用这样的排序:

MergeSortImp mSort = new MergeSortImp();
mSort... //(some method created to fill input list)
mSort.mergeSort( 0, input.size() - 1);