2011-10-20 3 views
-1

하위 집합에 대한 알고리즘 작성 시도 중 ... 주어진 벡터의 가능한 모든 하위 집합을 찾아서 어떤 벡터가 목표 값에 더하는 지 찾아야합니다. 그러나, 나는 nullpointerexceptions, 그리고 몇 가지 다른 오류가 계속. 누군가 나를 도울 수 있습니까? 나는 단단한 지점에 있고, 뇌 기능은 거의 없다. 매우 감사. 감사합니다. .업데이트 : subsetSum

java.lang.NullPointerException 
at Sumation.subsetSum(Sumation.java:78) 
at Sumation.main(Sumation.java:110) 

라인 78은 subsetSum 메소드에서 루프의 첫 번째 라인입니다.

/* Ruben Martinez 
* CS 210 Data Structures 
* Program requires no paramters at main method call; 
* instead, a JOptionPane asks for the ints the user 
* wishes to search. These must be seperated by commas, 
* e.g. 50,40,30 or 35,45,55. Program then asks for a 
* target int to find. Program searches for target 
* and returns combinations that add up to the target. 
*/ 

import java.util.Vector; 
import javax.swing.*; 

public class Sumation 
{ 
    static int[] array; 
    static int target; 
    static Vector<Integer> subsets; 
    static Vector<Integer> set; 
    static Vector<Vector<Integer>> outer; 

    public Sumation() { 
     //insert integers into array 
     String defineArray = (String)JOptionPane.showInputDialog(null, 
       "Enter integers to search. Seperate by commas.", null); 
     //splits string into array delimeted by commas 
     String[] arrayString = defineArray.split(","); 
     //creates int array of size of string array 
     array = new int[arrayString.length]; 
     //adds ints from args[] to int array 
     for (int i = 0; i < arrayString.length; i++) { 
      array[i] = Integer.parseInt(arrayString[i]); 
     } 
     //enter integer to search for 
     String targetString = (String)JOptionPane.showInputDialog(null, 
       "What is your target integer?", null); 
     //turns string to int 
     target = Integer.parseInt(targetString); 


     set = new Vector<Integer>(); 
     for (int n = 0; n < array.length; n++) { 
      set.add(array[n]); 
     } 
    } 

    private static Vector<Vector<Integer>> getSubsets(Vector<Integer> set) { 
     Vector<Vector<Integer>> subsetCollection = new Vector<Vector<Integer>>(); 

     if (set.size() == 0) { 
      subsetCollection.add(new Vector<Integer>()); 
     } else { 
      Vector<Integer> reducedSet = new Vector<Integer>(); 
      reducedSet.addAll(set); 

      int first = reducedSet.remove(0); 
      Vector<Vector<Integer>> subsets = getSubsets(reducedSet); 
      subsetCollection.addAll(subsets); 

      subsets = getSubsets(reducedSet); 

      for (Vector<Integer> subset : subsets) { 
       subset.add(0, first); 
      } 

      subsetCollection.addAll(subsets); 
     } 

     return subsetCollection; 
    } 

    public static Vector<Vector<Integer>> subsetSum(Vector<Integer> subsets, int target) { 
     //creates outer vector 
     outer = new Vector<Vector<Integer>>(); 

     for (int k = 0; k < subsets.size(); k++) { 
      //if k is the target, display 
      if (array[k] == target) { 
       //creates new inner vector for values that equal target 
       Vector<Integer> inner = new Vector<Integer>(); 
       outer.add(inner); 
       //add k to vector 
       inner.add(array[k]); 
      } 
      for (int l =0; l < subsets.size(); l++) { 
       int sum = subsets.elementAt(k); 
       if (sum == target) { 
        //creates new inner vector for values that sum up to target 
        Vector<Integer> inner = new Vector<Integer>(); 
        outer.add(inner); 
        //add l,k to vector 
        inner.add(array[l]); 
        inner.add(array[k]); 
       } 
       else { 
        System.out.print(""); 
       } 
      } 
     } 
     //return combinations that add up to target in vector form 
     return outer; 
    } 

    public static void main(String[] args) { 
     //calls sumation constructor 
     Sumation s = new Sumation(); 
     s.getSubsets(set); 
     s.subsetSum(subsets, target); 
     JOptionPane.showMessageDialog(null, "The combinations that equal to "+target+" are \n"+outer, "Vector", JOptionPane.INFORMATION_MESSAGE); 
    } 
} 
+1

최소한 NPE가 발생하는 스택 추적 및/또는 회선 번호를 제공해야합니다. * 어떤 * 참조도 null 일 가능성이 있으므로 NPE가 발생했다는 사실은이 추가 정보 없이는 거의 수행 할 수 없습니다. –

+0

미안해! 나는 그것을 여기에 둔다 고 생각했다. 내 코드에 붙여 넣었을 때 실수로 삭제 된 것 같습니다. @ AndrzejDoyle, 여기 있습니다 : –

답변

0

어떻게 분석 했습니까?

디버거 (예 : IDE)가 준비되어있는 경우 이와 같은 문제를 쉽게 분석 할 수 있습니다. 환경 설정에 따라 처음부터 프로그램을 통해

  • 단계는
  • 예외의이
  • NullPointerExceptions

과에 대한 중단 점을 설정 던져 줄에 중단 점을 설정 완료 할 수 모든 경우 변수/필드의 상태가 모든 점을 쉽게 볼 수 있습니다. 예기치 않은 상황에 빠지면 프로그램을 되감거나 다시 실행하여 이전 계산 결과를보고 쉽게 기대치를 벗어나는 위치를 확인하십시오.

디버거가없는 경우에도 println 문을 빈번한 사람의 디버거 인 값을보기 위해 모든 빈번히 (예외 행 직전에) 넣을 수 있습니다.

하지만 진지한 디버거를 만들려면 진지한 디버거를 설치하십시오. 만약 5 분에서 20 분 정도 걸리면 처음으로이 같은 문제를 조사해야 할 때보 다 더 많은 것을 절약 할 수 있습니다.


어쨌든, 문제는 당신이 subsets 필드에 아무것도 지정하지 않았다는 사실에 의해 발생합니다, 그래서 당신은 mainsubsetSum로를 통과 할 때 그것은 null입니다.

getSubsets 메서드 내의 로컬 변수 subset이 그림자를 나타 내기 때문일 수 있습니다.이 메서드가 해당 필드를 수정하기를 원한다면 실수라고 생각할 수 있습니다. 하지만 재귀 적 방법으로 상태를 변경하는 것은 잘못되기 쉽고 올바른 경우에도 언제든지 클래스에 대해 추론하기가 어려울지라도 (IMHO) 어쨌든 나쁜 연습이 될 것입니다. d) 그것이 어떤 상태인지 알 필요가있다. 필드에 결과를 할당하는 것은 일반적인 초보자의 실수입니다 (더 객체 지향적이라고 느끼기 때문일 수도 있습니다). 반환 결과는 보통 로컬 변수에 저장되는 결과를 얻는 것이 더 좋은 옵션 일 때 유용합니다.

그래서 main있어서 로컬 변수로 getSubsets 호출 결과를 할당해야하고 subsetSum 방법으로 통과.

(형식이 완전히 호환되지 않음을 알았습니다. subsetSum의 인수도 Vector<Vector<Integer>>이 아니어야합니다. 지금은 단일 하위 집합 만 전달할 수있는 것처럼 보입니다. 다른 문제.)