# vector & strings



## Sandro (29. Nov 2010)

Hallo ich weiß nicht so recht wie ich von einem String in einen Vektor schreiben kann. Das ist der bisherige Code:


```
public Vector<N> getShortestPath(N location1, N location2) {

			Vector<String> vecPath;
			int Loc1;
			int Loc2;
			
			String[] strLocations = (String[])vecLocations.toArray(new String[vecLocations.size()]); 
			
			if ((location1 != null) && (location2 != null)){
				
				Loc1 = getLocationIndex(location1);
				Loc2 = getLocationIndex(location2);
				
				if ((Loc1 != -1) && (Loc2 != -1) && (Loc1 != Loc2)) {
					
					vecPath = new Vector<String>();
					
					do {
						vecPath.add(0, strLocations[Loc2]);
						Loc2 = intMatrixT[Loc1][Loc2];
					} while (Loc2 != Loc1);
					
					vecPath.add(0, strLocations[Loc1]);
					
									
					
					return vecPath;
						
					}
				}		
		return null;
	}
```


Ich habe ja anfangs einen Vektor mit Strings (vecPath). Die Methode an sich ist aber vom Typ <N> also schmeißt er mir einen Fehler beim return am Ende mit dem vecPath, da dieser vom Typ String ist, aber er möchte ihn in N wieder haben.

 Weiß einer vllt eine Idee was ich da machen kann?

Ich bitte um euren Rat. Vielen Dank im vorraus!


----------



## Gast2 (29. Nov 2010)

```
public Vector<N> getShortestPath(N location1, N location2) {
 
            Vector<N> vecPath;
            int Loc1;
            int Loc2;
            
            String[] strLocations = (String[])vecLocations.toArray(new String[vecLocations.size()]); 
            
            if ((location1 != null) && (location2 != null)){
                
                Loc1 = getLocationIndex(location1);
                Loc2 = getLocationIndex(location2);
                
                if ((Loc1 != -1) && (Loc2 != -1) && (Loc1 != Loc2)) {
                    
                    vecPath = new Vector<N>();
                    
                    do {
                        vecPath.add(0, (N) strLocations[Loc2]);
                        Loc2 = intMatrixT[Loc1][Loc2];
                    } while (Loc2 != Loc1);
                    
                    vecPath.add(0, (N) strLocations[Loc1]);
                    
                                    
                    
                    return vecPath;
                        
                    }
                }       
        return null;
    }
```

Aber so schön ist das nicht... Man verwendet ja grade Generics um nicht casten zu müssen. Was soll N denn sein? Also wie ist es in der Klasse definiert?

Du kannst natürlich auch den array strLocations in N[] ändern. Dann sparst du dir das casten.


----------



## nrg (29. Nov 2010)

versteh ich jetzt nicht. wo geht in dem Code hervor, dass man String zu N casten kann?


----------



## Sandro (29. Nov 2010)

hallo,

vielen dank für deine antwort 

nun dann beschreib ich kurz mal mehr:

wir haben einen graphen mit mehreren "orten". manche sind direkt verbunden, manche nur durch umwege. wir müssen jetzt die kürzesten möglichen wege bestimmen von a nach b.

ich habe hier eine musterlösung die vor einigen jahren aktuell war, allerdings ist dies nur mit strings und arrays und damals nicht mit vectoren etc. wir müssen eben das ganze mit vektoren nun machen, aber leider fällt mir das ganze doch sehr schwer. habe eben versucht mit dieser lösung zu arbeiten und es zu modifizieren, aber ja... 

Das ist die alte Musterlösung:

```
public class Solution08 extends APSP {


    private Solution07 solGraph1;
    private String[] strLocations;


   /**
    public Solution08() {
        super();

        // create object for basic graph operations and init order of locations.

        solGraph1    = new Solution07();
        strLocations = null;
    }


     /**
    * Compute all-pairs shortest path of the given scenario with the given
    * order of locations.<p>
    *
    * @param   scenario   a scenario
    * @param   locations  array of location names (String) that defines the
    *          order of locations.
    * @return  <ul>
    *  <li> <code>true</code> if and only if the computation was successful.<br>
    *  <li> <code>false</code> if and only if the computation was NOT successful
    *   <ul>
    *   <li> at least one paramter is invalid (<code>null</code>)
    *   <li> at least one location name in the given array is not found in the scenario
    *   <li> at least one location name in the scenario is not found in the given array.
    *   </ul>.
    * </ul>
    * @since   1.0
    */
	public boolean computeAPSP(IScenario scenario, String[] locations) {
        int intLocations, intI, intJ, intK;
        int intDik, intDkj, intNew;

        if ((solGraph1 != null) && (testLocations(scenario, locations))) {
            // save order of location
            strLocations = locations;
            intLocations = strLocations.length;

            // create initial matrices.
            initMatrices(scenario);

            // run all iterations
            for (intK = 0; intK < intLocations; ++intK)
                for (intI = 0; intI < intLocations; ++intI)
                    for (intJ = 0; intJ < intLocations; ++intJ) {
                        intDik = intMatrixD[intI][intK];
                        intDkj = intMatrixD[intK][intJ];

                        // check for connection between these locations
                        if ((intDik < Integer.MAX_VALUE) &&
                            (intDkj < Integer.MAX_VALUE)) {
                            // compute duration using location k
                            intNew = intDik + intDkj;
                            if (intMatrixD[intI][intJ] > intNew) {
                                intMatrixD[intI][intJ] = intNew;
                                intMatrixT[intI][intJ] = intMatrixT[intK][intJ];
                            }
                        }
            }

            // computation was successful
            return true;
        }

        // something was wrong
        return false;
    }


   /**
    * Returns the shortest path between the given locations as a result of the
    * latest computation. The path is represented as a Vector of location names
    * (<code>String</code> objects) in the right order from location1 to
    * location2.<p>
    *
    * @param   location1  the first location as String
    * @param   location2  the second location as String.
    * @return  <ul>
    *  <li> <code>null</code>, if and only if at least one parameter is not
    *       valid (<code>null</code> or unknown location) or there is no path
    *       between the given locations
    *  <li> Otherwise a Vector containing all location names to travel from
    *       location1 to location2 (including location1 and location2)
    * </ul>
    * @see     java.util.Vector
    * @see     #computeAPSP
    * @since   1.0
    */
    public Vector<String> getShortestPath(String location1, String location2) {
        Vector<String> vecPath;
        int intLoc1, intLoc2;

        // first, check parameters
        if ((location1 != null) && (location2 != null)) {

            // get indices of both locations.
            intLoc1 = getLocationIndex(location1);
            intLoc2 = getLocationIndex(location2);

            // locations must be known and different
            if ((intLoc1 != -1) && (intLoc2 != -1) &&
                (intLoc1 != intLoc2)) {
                // create vector that contains the shortest path
                vecPath = new Vector<String>();

                // add location names in reverse order
                do {
                    // put current location name at the top of the vector.
                    vecPath.add(0, strLocations[intLoc2]);

                    // get next location index from matrix T.
                    intLoc2 = intMatrixT[intLoc1][intLoc2];
                } while (intLoc2 != intLoc1);

                // put first location at the top and return vector
                vecPath.add(0, strLocations[intLoc1]);
                return vecPath;
            }
        }

        // something was wrong
        return null;
    }


   /**
    * Returns the duration to travel along a shortest path between the given locations
    * as a result of the latest computation.<p>
    *
    * @param   location1  the first location as String
    * @param   location2  the second location as String.
    * @return  <ul>
    *  <li> <code>-1</code>, if and only if at least one parameter is not valid
    *       (<code>null</code> or unknown location) or there is no path between the
    *        given locations.
    *  <li> Otherwise duration to travel along a shortest path from
    *       location1 to location2.
    * </ul>
    * @see     #computeAPSP
    * @since   1.0
    */
    public int getShortestPathDuration(String location1, String location2) {
        int intLoc1, intLoc2;

        // first, check parameters
        if ((location1 != null) && (location2 != null)) {

            // get indices of both locations.
            intLoc1 = getLocationIndex(location1);
            intLoc2 = getLocationIndex(location2);
            if ((intLoc1 != -1) && (intLoc2 != -1))
                return intMatrixD[intLoc1][intLoc2];
        }

        // something was wrong
        return -1;
    }


   /**
    * Initialize matrices D and T according to the given parameters.<p>
    *
    * @param   scenario   a scenario
    * @since   1.0
    */
	private void initMatrices(IScenario scenario) {
        int intLocations, intI, intJ, intValue;

        // get number of locations.
        intLocations = strLocations.length;

        // create and initialize both matrices
        intMatrixD = solGraph1.getAdjacencyMatrix(scenario, strLocations);
        intMatrixT = solGraph1.getAdjacencyMatrix(scenario, strLocations);

        // set all invalid values to -1 and valid values to the predecessor
        for (intI = 0; intI < intLocations; ++intI)
            for (intJ = 0; intJ < intLocations; ++intJ) {
                intValue = intMatrixT[intI][intJ];
                if ((intValue < 1) || (intValue == Integer.MAX_VALUE))
                    intMatrixT[intI][intJ] = -1;
                else
                    intMatrixT[intI][intJ] = intI;
        }
    }


   /**
    * Returns the index of the given location.<p>
    *
    * @param   location   a location as String
    * @return  <ul>
    *  <li> <code>-1</code>, if and only if the location is unknown
    *  <li> otherwise the index in the array of locations
    * </ul>
    * @since   1.0
    */
	private int getLocationIndex(String location) {
        int intI;

        // check parameter
        if (location != null) {
            intI = strLocations.length;
            while (intI > 0) {
                if (location.equalsIgnoreCase(strLocations[--intI]))
                    return intI;
            }
        }

        // location name not found
        return -1;
    }

}
```

der neue klassenkopf muss nun allerdings so lauten:


```
public class Solution09<N extends INode, E extends IEdge<N>, G extends IGraph< N, E >> extends APSP<N, G> {
```


----------



## Gast2 (29. Nov 2010)

nrg hat gesagt.:


> versteh ich jetzt nicht. wo geht in dem Code hervor, dass man String zu N casten kann?



Nirgends... Wenn es nicht geht wird er es merken. Deswegen sagte ich ja auch das nicht der Hit ist.


			
				Sandro hat gesagt.:
			
		

> der neue klassenkopf muss nun allerdings so lauten:
> 
> ```
> public class Solution09<N extends INode, E extends IEdge<N>, G extends IGraph< N, E >> extends APSP<N, G> {
> ```



Dann musst du mit INodes statt Strings arbeiten.


----------



## Sandro (29. Nov 2010)

danke erneut für die antwort. da fühlt man sich nicht irgendwie allein gelassen 

ok ich werde die methode komplett neu bearbeiten. kannst du mir aber vllt einen rat geben wie ich das ganze mit dem vecPath anwenden kann?

strLocations könnte ich ja dann zb als private Vector<N> vecLocations; deklarieren. 
so wie ganz am anfang der klasse. wie füg ich dann mit der methode add die intLoc1 ein? in der musterlösung ist es ja mit einem string-array. also:

vecPath.add(0, strLocations[intLoc1]);
return vecPath;


wenn ich jetzt mit inode arbeite, wie müsste da dann der befehl sein?

Tut mir leid für wenn es schwer ist mich gerade zu verstehen. Leider bin ich der deutschen Sprache nicht so mächtig. Vielen lieben Dank nochmal für die Hilfe!


----------



## Gast2 (29. Nov 2010)

Dann muss der String[] ein INode[] array sein.


----------



## Sandro (29. Nov 2010)

also dann so?


```
public Vector<N> getShortestPath(N location1, N location2) {

			Vector<N> vecPath;
			int Loc1;
			int Loc2;
			
			
			
			if ((location1 != null) && (location2 != null)){
				
				Loc1 = getLocationIndex(location1);
				Loc2 = getLocationIndex(location2);
				
				if ((Loc1 != -1) && (Loc2 != -1) && (Loc1 != Loc2)) {
					
					vecPath = new Vector<N>();
					
					do {
						vecPath.add(0, (N) nLocations[Loc2]);
						Loc2 = intMatrixT[Loc1][Loc2];
					} while (Loc2 != Loc1);
					
					vecPath.add(0, (N) nLocations[Loc1]);
					
					
					
					
					return vecPath;
						
					}
				}		
		return null;
	}
```

Anfangs noch  private String[] strLocations;
in INode[] nLocations; umbenannt.


----------



## Sandro (29. Nov 2010)

scheint bisher zu klappen 

aber eine frage habe ich dann noch.

wir hatten eine klasse zuvor eine matrix erstellt die eben die werte der verbindungen aufzeigte. wenns keine direkte verbindung gab dann hatten wir ein unendlich zeiten, direkte verbindung der wert und wenn ort A nach A hatten wir den wert 0.

die aufgabe habe ich auch hingekriegt:


```
public class Solution08<N extends INode, E extends IEdge<N>, G extends IGraph<N,E>> extends Graph<N,G>{

	

		
	
	public int getDirectDuration(G scenario, N loc1, N loc2) {
		if (scenario != null && loc1 != null && loc2 != null){
			if (loc1.equals(loc2)){
				return 0;
			}
			else {
				
				
				Enumeration<IConnection<ILocation>> enu = ((ILocation) loc1).getConnections().elements();
				while(enu.hasMoreElements()){
					IConnection<ILocation> element = enu.nextElement();
					if (element.isConnectedLocation((ILocation) loc1) && element.isConnectedLocation((ILocation) loc2)){
						return element.getWeight();
					}
				}
				return Integer.MAX_VALUE;
			}
		}
		return -1;
	}
	
	
	
	
	
	
	
	public int[][] getAdjacencyMatrix(G scenario, Vector<N> locations) {
        
		ILocation locLoc1; 
		ILocation locLoc2;
        
        int LocAnz; 
        int i; 
        int j;

       
        if ((scenario != null) && (locations != null)) {

            
        	LocAnz = ((IScenario) scenario).getLocations().size();

                int [][] matrix = new int[LocAnz][LocAnz];

            	ILocation[] locs = new ILocation[locations.size()];
        		locations.toArray(locs);
                
                
                try {
                   
                    for (i = 0; i < LocAnz; i++) {
                        locLoc1 = ((IScenario) scenario).getLocation(locs[i].getId());
        
                        for (j = 0; j < LocAnz; j++) {
                            locLoc2 = ((IScenario) scenario).getLocation(locs[j].getId());
                            
                            matrix [i][j] = getDirectDuration((scenario), (N) locLoc1, (N) locLoc2);
                        }
                    }
               } catch (Exception e) { 
            	   
               }

              
               return matrix;
            }
       
        return null;
    }

}
```


die aufgabe die ich jetzt habe ist momentan so:


```
package solutions;

import de.tu_darmstadt.es.sopra.exercises.APSP;
import de.tu_darmstadt.es.sopra.model.external.interfaces.graph.IEdge;
import de.tu_darmstadt.es.sopra.model.external.interfaces.graph.IGraph;
import de.tu_darmstadt.es.sopra.model.external.interfaces.graph.INode;
import de.tu_darmstadt.es.sopra.model.external.interfaces.scenario.ILocation;
import de.tu_darmstadt.es.sopra.model.external.interfaces.scenario.IScenario;
import java.util.Vector;


public class Solution09<N extends INode, E extends IEdge<N>, G extends IGraph< N, E >> extends APSP<N, G> {


	private final String[] strAuthors = { "Arian Cake", "Daniel Schmidt"};

	public String[] getAuthors() {
		return strAuthors;
	}

	public String getTeam() {
		return "G13T2";
	}

	public String getVersion() {
		return "1.1";
	}
	
	
	private Solution08 solutionGraph;
	
	INode[] nLocations;
	

	

	
	
	public Solution09(){
		super();
		
		solutionGraph = new Solution08();
		nLocations = null;
	}

	@Override
	public boolean computeAPSP(G scenario, Vector<N> locations) {


		
        int intDik, intDkj, intNew;

        
        if ((solutionGraph != null) && (testLocations(scenario, locations))) {
            // save order of location
            Vector<N> strLocations = locations;
            int LocAnz = strLocations.size();

            initMatrices(scenario);

            // run all iterations
            for (int k = 0; k < LocAnz; k++)
                for (int i = 0; i < LocAnz; i++)
                    for (int j = 0; j < LocAnz; j++) {
                        intDik = intMatrixD[i][k];
                        intDkj = intMatrixD[k][j];

         // check for connection between these locations
if ((intDik < Integer.MAX_VALUE)&&(intDkj < Integer.MAX_VALUE)) {
         
 // compute duration using location k

intNew = intDik + intDkj;

if (intMatrixD[i][j] > intNew) {

intMatrixD[i][j] = intNew;
intMatrixT[i][j] = intMatrixT[k][j];
                            }
                        }
            }

            // computation was successful
            return true;
        }

        // something was wrong
        return false;		
	}

		

	public Vector<N> getShortestPath(N location1, N location2) {

			Vector<N> vecPath;
			int Loc1;
			int Loc2;
			
			
			
			if ((location1 != null) && (location2 != null)){
				
				Loc1 = getLocationIndex(location1);
				Loc2 = getLocationIndex(location2);
				
				if ((Loc1 != -1) && (Loc2 != -1) && (Loc1 != Loc2)) {
					
					vecPath = new Vector<N>();
					
					do {
						vecPath.add(0, (N) nLocations[Loc2]);
						Loc2 = intMatrixT[Loc1][Loc2];
					} while (Loc2 != Loc1);
					
					vecPath.add(0, (N) nLocations[Loc1]);
					
					
					
					
					return vecPath;
						
					}
				}		
		return null;
	}

	@Override
	public int getShortestPathDuration(N location1, N location2) {
		
		int intLoc1, intLoc2;

        // first, check parameters
        if ((location1 != null) && (location2 != null)) {

            // get indices of both locations.
            intLoc1 = getLocationIndex(location1);
            intLoc2 = getLocationIndex(location2);
            if ((intLoc1 != -1) && (intLoc2 != -1))
                return intMatrixD[intLoc1][intLoc2];
        }

        // something was wrong
        return -1;
    
	

		
	}
	
	private int getLocationIndex(N location) {
        
		ILocation[] locs = new ILocation[((Vector<N>) location).size()];
		((Vector<N>) location).toArray(locs);
		
        int LocAnz = nLocations.length;
		
		
        if (location != null) {
            int i = LocAnz;
            while (i > 0) {
                return i;
            }
        }

       return -1;
    }	

	
private void initMatrices(G scenario) {
		
		int LocAnz;
		int i;
		int j;
		
		LocAnz =  nLocations.length;
		
		intMatrixD = solutionGraph.getAdjacencyMatrix(scenario, nLocations);
		intMatrixT = solutionGraph.getAdjacencyMatrix(scenario, nLocations);
		
		for (i=0; i<LocAnz; i++)
			for (j=0; j<LocAnz; j++){
				int value = intMatrixT[i][j];
				if ((value<1) || (value == Integer.MAX_VALUE))
					intMatrixT[i][j]=-1;
				else
					intMatrixT[i][j]= i;
			
		}
	
	}
	
	
}
```

Gegen Ende bei:

		intMatrixD = solutionGraph.getAdjacencyMatrix(scenario, nLocations);
		intMatrixT = solutionGraph.getAdjacencyMatrix(scenario, nLocations);

sagt er mir aber einen Fehler an, da die Klasse vorher mit Vector<N> gearbeitet hat.
Wann kann ich nun tun?


Danke nochmal für deine Hilfe, du hast mir sehr geholfen!


----------



## Gast2 (29. Nov 2010)

Entweder einen Vector übergeben oder die Signatur ändern damit die Methode einen N[] annimmt. Kommt so ziemlich auf das gleiche raus.

Kannst ja aus dem N[] einen Vector<N> machen.

```
N[] nArray = getNarray();
Vector<N> vectorN = new Vector<N>();
for (N n : nArray){
  vector.add(n);
}
```


----------



## Sandro (30. Nov 2010)

danke fassy für all deine mühe und die zeit, die du für mich genommen hast.

deinen letzten post verstehe ich aber nicht ganz so gut.

Meinst du, dass ich mein INode[] nun in einen Vektor machen sollte?

Wenn ja, dann versteh ich leider in deinem Code getNarray() und die dritte Zeile nicht mit "for (N n : nArray){"

Ich hoffe du hast Einsicht mit mir und könntest mir nochmals behilflich sein.


----------



## Gast2 (30. Nov 2010)

Naja, du hast eine Methode in der Klasse IGraph (schätze ich mal) 

```
public int[][] getAdjencyMatrix(G scenario, INode[] nodes){
...
}
```

Momentan übergibst du der Methode deinen Graphen G "scenario" und einen Vector<N> "nLocations".

Da passt halt nicht zusammen.

Du hast jetzt zwei Möglichkeiten.

1) Ändern der Methode getAdjencyMatrix. Das ist evtl nicht möglich wenn das Interface IGraph nicht geändert werden darf. Wenn doch dann:

```
public int[][] getAdjencyMatrix(G scenario, Vector<N> nodes){
...
}
```
oder 
2) vor dem Aufruf deinen Vector in ein Array schreiben. Dazu kannst du zum konvertieren zwischen Vector und Array zwei Methoden definieren:

```
import java.lang.reflect.Array;
...

public N[] vectorToArray(Vector<N> vector, Class<?> clazz){
	      @SuppressWarnings("unchecked")
		N[] array = (N[])Array.newInstance(clazz,vector.size());
	      for(int i = 0; i < vector.size(); i++){
	          array[i] = vector.get(i);
	      }
	      return array;
	}

public Vector<N> arrayToVector(N[] array){
	  Vector<N> vector = new Vector<N>();
	  for(int i = 0; i < array.length; i++){ // ok, dann die index schleife... for(N n : array) wäre die foreach Schleife, macht das gleiche
		  vector.add(array[i]);
	  }
	  return vector;
}
```

Dann in deinem Code:

```
N[] locationArray = vectorToArray(nLocations, nLocations.get(0).getClass());
intMatrixD = solutionGraph.getAdjencyMatrix(scenatio, locationArray);
```

Alles klar?


----------



## Gast2 (30. Nov 2010)

Hier nochmal als ganze Testklasse:

```
import java.lang.reflect.Array;
import java.util.Vector;

public class Test<N extends Object> {
	public static void main(String[] args) {
		Test<String> k = new Test<String>();
	}

	@SuppressWarnings("unchecked")
	public Test() {
		Vector<N> vector = new Vector<N>();
		vector.add((N) "1");
		vector.add((N) "2");
		vector.add((N) "3");
		vector.add((N) "4");
		vector.add((N) "5");
		N[] array = vectorToArray(vector, vector.get(0).getClass());
		System.out.println("Inhalt array:");
		for(N n : array){
			System.out.println(n);
		}
		Vector<N> newVector = arrayToVector(array);
		System.out.println("Inhalt newVector:");
		for(N n : newVector){
			System.out.println(n);
		}
	}

	public N[] vectorToArray(Vector<N> vector, Class<?> clazz) {
		@SuppressWarnings("unchecked")
		N[] array = (N[]) Array.newInstance(clazz, vector.size());
		for (int i = 0; i < vector.size(); i++) {
			array[i] = vector.get(i);
		}
		return array;
	}

	public Vector<N> arrayToVector(N[] array) {
		Vector<N> vector = new Vector<N>();
		for (int i = 0; i < array.length; i++) {
			vector.add(array[i]);
		}
		return vector;
	}
}
```

Man könnte sich auch das Reflectiongebastel sparen mit:

```
public N[] vectorToArray(Vector<N> vector) {
		N[] array = (N[]) new Object[vector.size()];
		for (int i = 0; i < vector.size(); i++) {
			array[i] = vector.get(i);
		}
		return array;
	}
```

So macht es die Vector klasse auch. Sonst hat man das Problem das bei einem "leeren" Vektor das nicht tut und einem mit einem IndexOutOfRange abschmiert.


----------



## Sandro (30. Nov 2010)

Hallo fassy,

ich weiß nicht wie ich dir nur danken kann. Für all die Zeit und Mühe, unglaublich! Danke danke!
Um ehrlich zu sein, schäme ich mich gerade auch etwas, da ich das Ganze wohl immernoch nicht hinkriege, selbst bei deiner großartigen Hilfe. Verzeih mir also wenn ich erneut Fragen habe, bzw nicht folgen kann.

Das Interface IGraph kann ich in der Tat nicht ändern, also bleibt mir nur deine zweite Möglichkeit übrig.
Du sagst "vor dem Aufruf deinen Vector in ein Array schreiben."

Welchen Aufruf meinst du? Den von getAdjacencyMatrix(scenario, nLocations)? 
Ich weiß nicht gerade wo du die Methoden einsetzen möchtest, in der Solution09 oder 08?

Ursprünglich erwartet die getAdjacencyMatrix einen Vektor und ich habe bisher mit einem Array in der S09 gearbeitet. Heißt ich muss jetzt diesen Array in einen Vektor umwandeln. Mit hilfe deiner Methode:


```
public Vector<N> arrayToVector(N[] array){
      Vector<N> vector = new Vector<N>();
      for(int i = 0; i < array.length; i++){ // ok, dann die index schleife... for(N n : array) wäre die foreach Schleife, macht das gleiche
          vector.add(array[i]);
      }
      return vector;
}
```

Hab ich das bisher richtig verstanden? Aber was macht die andere Methode  public N[] vectorToArray(Vector<N> vector) ?

Soll sie den Vektor aus S08 in ein Array speichern, damit ich in der S09 damit arbeiten kann? Muss dieser dann in der S08 implementiert werden? Oder kann das auch in der S09 gemacht werden?

Bitte entschuldige meine Unkenntnis. Leider ist es so, dass ich am Anfang des Programmierens stehe und alles wie ein riesen Jungle für mich aussieht, aber dennoch möchte ich alles verstehen und trotz Panik wenn ich hier Sachen sehe die ich nicht verstehe, möchte ich nicht aufgeben. Daher hoffe ich, dass du Verständnis für mich hast und mir dennoch weiter helfen kannst. Ich wäre dir sehr dankbar!


----------



## Gast2 (30. Nov 2010)

Sandro hat gesagt.:


> Hallo fassy,
> 
> ich weiß nicht wie ich dir nur danken kann. Für all die Zeit und Mühe, unglaublich! Danke danke!
> Um ehrlich zu sein, schäme ich mich gerade auch etwas, da ich das Ganze wohl immernoch nicht hinkriege, selbst bei deiner großartigen Hilfe. Verzeih mir also wenn ich erneut Fragen habe, bzw nicht folgen kann.



Kein Problem, wir haben alle mal angefangen 



Sandro hat gesagt.:


> Das Interface IGraph kann ich in der Tat nicht ändern, also bleibt mir nur deine zweite Möglichkeit übrig.
> Du sagst "vor dem Aufruf deinen Vector in ein Array schreiben."
> 
> Welchen Aufruf meinst du? Den von getAdjacencyMatrix(scenario, nLocations)?
> Ich weiß nicht gerade wo du die Methoden einsetzen möchtest, in der Solution09 oder 08?




```
N[] locationArray = vectorToArray(nLocations, nLocations.get(0).getClass());
intMatrixD = solutionGraph.getAdjencyMatrix(scenatio, locationArray);
```

Halt da wo du den Fehler hattest den du in dem letzen Posting als Screenshot angezeigt hast. Und zwar an genau der Stelle. Ich hab ja nur eine Zeile über den von dir schon programmierten Code eingefügt. Ob das jetzt die 09 oder 08 war kann ich so grade nicht sagen - aber du wirst ja wissen aus welcher Klasse du den code kopiert und einen Fehler hast? 



Sandro hat gesagt.:


> Ursprünglich erwartet die getAdjacencyMatrix einen Vektor und ich habe bisher mit einem Array in der S09 gearbeitet. Heißt ich muss jetzt diesen Array in einen Vektor umwandeln. Mit hilfe deiner Methode:
> 
> 
> ```
> ...



Naja - die Namen sprechen ja für sich [c]vectorToArray[/c] macht aus einem Vector einen Array und [c]arrayToVector[/c] aus einem Array einen Vector? 

Ich hab nur der Vollständigkeit beide Methoden eingefügt, du brauchst ja nur die erste um aus einem Vector einen Array zu machen.



Sandro hat gesagt.:


> Soll sie den Vektor aus S08 in ein Array speichern, damit ich in der S09 damit arbeiten kann? Muss dieser dann in der S08 implementiert werden? Oder kann das auch in der S09 gemacht werden?



Das muss in die Klasse in der du auch den Code aufrufst: 

```
N[] locationArray = vectorToArray(nLocations, nLocations.get(0).getClass());
intMatrixD = solutionGraph.getAdjencyMatrix(scenatio, locationArray);
```

Einfach irgendwo am Ende der Klasse einfügen.



Sandro hat gesagt.:


> Bitte entschuldige meine Unkenntnis. Leider ist es so, dass ich am Anfang des Programmierens stehe und alles wie ein riesen Jungle für mich aussieht, aber dennoch möchte ich alles verstehen und trotz Panik wenn ich hier Sachen sehe die ich nicht verstehe, möchte ich nicht aufgeben. Daher hoffe ich, dass du Verständnis für mich hast und mir dennoch weiter helfen kannst. Ich wäre dir sehr dankbar!



Passt schon. Da werfen sie euch aber recht früh Generics (Vector<N>,N[], G usw) um die Ohren. Sehr erstaunlich.


----------



## Sandro (30. Nov 2010)

die getAdjacencyMatrix methode ist doch im interface so definiert, sodass sie einen vektor geliefert bekommen möchte. ich arbeite ständig mit arrays, also muss ich die arrayToVector von dir methode verwenden, richtig?

ist dann dein code hier wirklich richtig?


```
N[] locationArray = vectorToArray(nLocations, nLocations.get(0).getClass());
intMatrixD = solutionGraph.getAdjacencyMatrix(scenario, locationArray);
```

ich habe die nLocations als INode[] also als array anfangs deklariert. Aber mir wird ständig gesagt, dass ich die getAdjacencyMatrix methode mit einem vektor füllen soll und nicht mit dem array wie bei dir verwendet dem locationArray.

Ich hoffe du verstehst was ich meine. Ich kann da leider die Methode nicht abändern was es übergeben bekommt. definiert ist sie als getAdjacencyMatrix(G scenario, *Vector<N> locations*)


----------



## Gast2 (30. Nov 2010)

Ok, wenn die Methode definiert ist dass sie einen Vector annimmt und du nur einen Array zu Hand hast - dann musst du die Methode [c]vectorToArray[/c] nehmen, also:


```
Vector<N> locationVector = arrayToVector(nLocations);
intMatrixD = solutionGraph.getAdjacencyMatrix(scenario, locationVector);
```

So hast du jetzt wenigestens beide Wege gesehn: Vector -> Array und Array -> Vector


----------



## Sandro (30. Nov 2010)

großartig, immerhin jetzt keine direkten fehlermeldungen im programm  ich danke dir soooooooo sehr!
Du hast mir wirklich in vielen Themen die Türen geöffnet, ich kann dir nicht genug danken! Das war sehr sehr nett und ich weiß deine Hilfe sehr zu schätzen!

Aaaaber 

Wenn ich das Programm starte, bekomme ich leider immernoch eine NullPointerException :noe:

Das ist die Klasse jetzt überarbeitet wurde und die kürzesten Wege in die Matrix aufzeigt:


```
public class Solution09<N extends INode, E extends IEdge<N>, G extends IGraph< N, E >> extends APSP<N, G> {


	
	
	private Solution08 solutionGraph;
	
	INode[] nLocations;
	

	
	public Solution09(){
		super();
		
		solutionGraph = new Solution08();
		nLocations = null;
	}


	public boolean computeAPSP(G scenario, Vector<N> locations) {

        int intDik, intDkj, intNew;

        
        if ((solutionGraph != null) && (testLocations(scenario, locations))) {
            // save order of location
            Vector<N> strLocations = locations;
            int LocAnz = strLocations.size();

            initMatrices(scenario);

            // run all iterations
            for (int k = 0; k < LocAnz; k++)
                for (int i = 0; i < LocAnz; i++)
                    for (int j = 0; j < LocAnz; j++) {
                        intDik = intMatrixD[i][k];
                        intDkj = intMatrixD[k][j];

         // check for connection between these locations
if ((intDik < Integer.MAX_VALUE)&&(intDkj < Integer.MAX_VALUE)) {
         
 // compute duration using location k

intNew = intDik + intDkj;

if (intMatrixD[i][j] > intNew) {

intMatrixD[i][j] = intNew;
intMatrixT[i][j] = intMatrixT[k][j];
                            }
                        }
            }

            // computation was successful
            return true;
        }

        // something was wrong
        return false;		
	}

		

	public Vector<N> getShortestPath(N location1, N location2) {

			Vector<N> vecPath;
			int Loc1;
			int Loc2;
			
			
			
			if ((location1 != null) && (location2 != null)){
				
				Loc1 = getLocationIndex(location1);
				Loc2 = getLocationIndex(location2);
				
				if ((Loc1 != -1) && (Loc2 != -1) && (Loc1 != Loc2)) {
					
					vecPath = new Vector<N>();
					
					do {
						vecPath.add(0, (N) nLocations[Loc2]);
						Loc2 = intMatrixT[Loc1][Loc2];
					} while (Loc2 != Loc1);
					
					vecPath.add(0, (N) nLocations[Loc1]);
					
					
					
					
					return vecPath;
						
					}
				}		
		return null;
	}

	@Override
	public int getShortestPathDuration(N location1, N location2) {
		
		int intLoc1, intLoc2;

        // first, check parameters
        if ((location1 != null) && (location2 != null)) {

            // get indices of both locations.
            intLoc1 = getLocationIndex(location1);
            intLoc2 = getLocationIndex(location2);
            if ((intLoc1 != -1) && (intLoc2 != -1))
                return intMatrixD[intLoc1][intLoc2];
        }

        // something was wrong
        return -1;
    
	

		
	}
	
	private int getLocationIndex(N location) {
        
		ILocation[] locs = new ILocation[((Vector<N>) location).size()];
		((Vector<N>) location).toArray(locs);
		
        int LocAnz = nLocations.length;
		
		
        if (location != null) {
            int i = LocAnz;
            while (i > 0) {
                return i;
            }
        }

       return -1;
    }	

	
private void initMatrices(G scenario) {
		
		int LocAnz;
		int i;
		int j;
		
		LocAnz =  nLocations.length;
		
		
		
		Vector<N> locationVector = arrayToVector(nLocations);
		intMatrixD = solutionGraph.getAdjacencyMatrix(scenario, locationVector);
        intMatrixT = solutionGraph.getAdjacencyMatrix(scenario, locationVector);	

		
		for (i=0; i<LocAnz; i++)
			for (j=0; j<LocAnz; j++){
				int value = intMatrixT[i][j];
				if ((value<1) || (value == Integer.MAX_VALUE))
					intMatrixT[i][j]=-1;
				else
					intMatrixT[i][j]= i;
			
		}
	
	}

public Vector<N> arrayToVector(INode[] nLocations){
    Vector<N> vecLocations = new Vector<N>();
    for(int i = 0; i < nLocations.length; i++){ 
        vecLocations.add((N) nLocations[i]);
    }
    return vecLocations;
}

	
	
}
```


Das ist die Klasse, die die Matrix, also diese Adjacency Matrix aufbaut und die obrige Klasse auf diese hier zugreift:


```
public class Solution08<N extends INode, E extends IEdge<N>, G extends IGraph<N,E>> extends Graph<N,G>{

	

		
	
	public int getDirectDuration(G scenario, N loc1, N loc2) {
		if (scenario != null && loc1 != null && loc2 != null){
			if (loc1.equals(loc2)){
				return 0;
			}
			else {
				
				
				Enumeration<IConnection<ILocation>> enu = ((ILocation) loc1).getConnections().elements();
				while(enu.hasMoreElements()){
					IConnection<ILocation> element = enu.nextElement();
					if (element.isConnectedLocation((ILocation) loc1) && element.isConnectedLocation((ILocation) loc2)){
						return element.getWeight();
					}
				}
				return Integer.MAX_VALUE;
			}
		}
		return -1;
	}
	
	
	

	
	
	
	public int[][] getAdjacencyMatrix(G scenario, Vector<N> locations) {
        
		ILocation locLoc1; 
		ILocation locLoc2;
        
        int LocAnz; 
        int i; 
        int j;

       
        if ((scenario != null) && (locations != null)) {

            
        	LocAnz = ((IScenario) scenario).getLocations().size();

                int [][] matrix = new int[LocAnz][LocAnz];

            	ILocation[] locs = new ILocation[locations.size()];
        		locations.toArray(locs);
                
                
                try {
                   
                    for (i = 0; i < LocAnz; i++) {
                        locLoc1 = ((IScenario) scenario).getLocation(locs[i].getId());
        
                        for (j = 0; j < LocAnz; j++) {
                            locLoc2 = ((IScenario) scenario).getLocation(locs[j].getId());
                            
                            matrix [i][j] = getDirectDuration((scenario), (N) locLoc1, (N) locLoc2);
                        }
                    }
               } catch (Exception e) { 
            	   
               }

              
               return matrix;
            }
       
        return null;
    }
	




}
```

Wo kommt denn hier die NullPointerException? Und was kann ich jetzt noch tun, um diese abzufangen?
Ach mensch, kurz davor und doch noch so fern >.<


----------



## Gast2 (30. Nov 2010)

Erstmal den StackTrace ansehn... Da stehen genau die Zeilen drin die du dir ansehen musst. Poste mal den Stacktrace der dir ausgeworfen wird.


----------



## Andi_CH (30. Nov 2010)

mach in jedes catch mal 

e.printStackTrace();

und da steht dann ganz genau auf welcher Codezeile das auftritt.

Ach ja, ganz oben om Main auch noch try - catch und e.printStackTrace() .......


----------



## Sandro (30. Nov 2010)

also ihr meint mit 


```
try{
...
}catch (Exception e) { 
	e.printStackTrace();
}
```

die methoden zu untersuchen? oder meint ihr ganz was anderes?


----------



## Gast2 (30. Nov 2010)

Japp, genau das.

Eigentlich müsste der StackTrace der NPE auch in der Eclipse Console stehen.


----------



## Andi_CH (30. Nov 2010)

Lies nur weiter, wenn du sonst nicht an den output der Exception kommst

Du musst das jetzt nicht überall einbauen
Im Main um alles ein try - catch block - und in jedem schon vorhanden catch - block
das reicht - leere catch blocks "verschlucken" die Meldung - ok, dazu sind sie ja da ;-)


----------



## Sandro (30. Nov 2010)

Nun in Eclipse steht nichts, aber früher mussten wir eine Debug-Funktion einbinden und diese spuckt dies aus:




```
Wanted location is not found! location: Magdeburg

stack trace:
de.tu_darmstadt.es.sopra.model.internal.implementations.BeerBrewingScenario.getLocation(BeerBrewingScenario.java:216)
solutions.Solution03.directConnection(Solution03.java:59)
de.tu_darmstadt.es.sopra.exercises.commands.ExcerciseCommand_Debug.check(ExcerciseCommand_Debug.java:79)
de.tu_darmstadt.es.sopra.exercises.commands.ExcerciseCommand_Debug.execute(ExcerciseCommand_Debug.java:40)
de.tu_darmstadt.es.sopra.splitInterfaces.AbstractMenuListener.execute(AbstractMenuListener.java:75)
de.tu_darmstadt.es.sopra.gui.SpielGUIController.actionPerformed(SpielGUIController.java:98)
javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
javax.swing.DefaultButtonModel.setPressed(Unknown Source)
javax.swing.AbstractButton.doClick(Unknown Source)
javax.swing.plaf.basic.BasicMenuItemUI.doClick(Unknown Source)
javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(Unknown Source)
java.awt.Component.processMouseEvent(Unknown Source)
javax.swing.JComponent.processMouseEvent(Unknown Source)
java.awt.Component.processEvent(Unknown Source)
java.awt.Container.processEvent(Unknown Source)
java.awt.Component.dispatchEventImpl(Unknown Source)
java.awt.Container.dispatchEventImpl(Unknown Source)
java.awt.Component.dispatchEvent(Unknown Source)
java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
java.awt.Container.dispatchEventImpl(Unknown Source)
java.awt.Window.dispatchEventImpl(Unknown Source)
java.awt.Component.dispatchEvent(Unknown Source)
java.awt.EventQueue.dispatchEvent(Unknown Source)
java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
java.awt.EventDispatchThread.pumpEvents(Unknown Source)
java.awt.EventDispatchThread.pumpEvents(Unknown Source)
java.awt.EventDispatchThread.run(Unknown Source)
```

und das hier auch:


```
de.tu_darmstadt.es.sopra.model.external.exception.LocationNotExistingException: Wanted location is not found! location: Magdeburg
	at solutions.Solution03.directConnection(Solution03.java:59)
de.tu_darmstadt.es.sopra.model.external.exception.LocationNotExistingException: Wanted location is not found! location: Wiesbaden
	at solutions.Solution03.directConnection(Solution03.java:59)
```

Ich dachte, dass ich nun vllt die Exception LocationNotExistingException importiere und implementiere, wie das in Solution08 der Fall ist, denn vor diesem Problem hatte ich das mit der S08 ebenfalls das gleiche Problem. Nur hier in der neuen Klasse, weiß ich leider nicht, wo ich am besten die Exception einbinden soll. 

Zur Info, die Solution03, die er immer verlangt:


```
package solutions;

import de.tu_darmstadt.es.sopra.exercises.Debug;
import de.tu_darmstadt.es.sopra.model.external.interfaces.scenario.ILocation;
import de.tu_darmstadt.es.sopra.model.external.interfaces.scenario.IScenario;
import de.tu_darmstadt.es.sopra.model.external.interfaces.scenario.IConnection;
import de.tu_darmstadt.es.sopra.model.external.exception.LocationNotExistingException;

import java.util.Enumeration;


public class Solution03 extends Debug {

	private final String[] strAuthors = { "xy" };

   
    public String getTeam() {
        return "yx";
    }


   
    public String[] getAuthors() {
         return strAuthors;
    }


   
    public String getVersion() {
        return "1.01";
    }


   /**
    * Returns whether there is a direct connection between the given locations.<p>
    *
    * @param   scenario   a scenario
    * @param   location1  the name of the first location
    * @param   location2  the name of the second location
    * @return  <code>true</code> if and only there is a direct connection between
    *          the given locations in the given scenario.<br>
    *          <code>false</code> if and only there is NO direct connection between
    *          the given locations, or the locations are equal.<br>
    * @since   08.11.2006
    */
    public boolean directConnection(IScenario scenario,
                                    String location1, String location2) {
        ILocation loc1, loc2;
        IConnection conTemp;
        Enumeration<IConnection<ILocation>> enuConnections;

        // check for valid scenario
        // Erweiterung des Codes mit (location2 != null)
        
        if ((scenario != null) && (location2 != null)) {
            try {
                // get location object from location names
                loc1 = scenario.getLocation(location1);
                loc2 = scenario.getLocation(location2);

                // get all connection from location 1
                enuConnections = loc1.getConnections().elements();
                while (enuConnections.hasMoreElements()) {
                    conTemp = enuConnections.nextElement();
                    if (conTemp.isConnectedLocation(loc2)){
                    	
                    /* Überprüfung ob Start und Ziel identisch sind. Falls dies zutrifft
                      wird als Rückgabe "false" ausgegeben. 
                      */
                    	if (loc1 == loc2){
                    		return false;
                    	} else return true;
                    }
                    
                }
            } catch (LocationNotExistingException e) { }
        }
        
        // Something was wrong
        return false;
    }
}
```


----------



## Gast2 (30. Nov 2010)

Naja, bei [c]loc2 = scenario.getLocation(location2);[/c] gibt es die NullPointerException. Dann würd ich mal in [c]scenario.getLocation[/c] gucken. Ich vermute mal von den ganzen Fehlermeldungen das der Ort nicht in dem Scenario verfügbar ist und deshalb beim getLocation die NPE auftritt. 

Zeig doch mal die Implementierung von getLocation


----------



## Sandro (30. Nov 2010)

hey,

ja die Orte sind in der Tat nicht vorhanden und dies ist auch so gewollt. getLocation ist die Methode des Interfaces IScenario (bzw später eben G sceneraio). Implementiert habe ich die Methode also nicht.

In der API haben wir zu getLocation dies als Info gegeben:



> getLocation
> 
> ILocation getLocation(java.lang.String id)
> throws LocationNotExistingException
> ...


----------



## Gast2 (30. Nov 2010)

Aber wenn das eine Methode in einem Interface ist, dann muss die doch von dir in der Klasse die das Interface implementiert auch ausprogammiert werden?


----------

