简体   繁体   中英

Error in sorting two corresponding arrays

I am trying to make a probabilistic outcome simulator, where information is taken from a .csv file. Two ArrayLists are created and the information and outcomes are then put into these ArrayLists. The Double ArrayList contains the Confidence Ratings for each corresponding two teams in the String ArrayList.

Example: 
Double ArrayList:  25, 22, 50
String ArrayList: Atlanta, Michigan, NY, Detroit

Atlanta and Michigan would correspond to 25, NY and Detroit would correspond to 22.

I have made the program, the confidence rating double ArrayList gets sorted, but the teams String ArrayList does not. These are the two ArrayLists before they get sorted:

[1.0, 7.0, 8.0, 1.0, 10.0, 2.0, 4.0, 3.0, 1.0, 1.0, 9.0, 1.0, 3.0, 6.0, 0.0, 16.0]
[Green Bay, [Detroit, NY Jets, [NY Giants, [St. Louis, Arizona, [Tampa Bay, Atlanta, [Minnesota, Seattle, Houston, [Buffalo, [Miami, Baltimore, Cincinnati, [Cleveland, Jacksonville, [Tennessee, SF, [Chicago, Denver, [San Diego, KC, [Oakland, Carolina, [New Orleans, [New England, Philly, [Pittsburgh, Indy, [Washington, Dallas]

After the two lists get sorted out, this is how it looks like:

[16.0, 10.0, 9.0, 8.0, 7.0, 6.0, 4.0, 3.0, 3.0, 2.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0]
[[NY Giants, [Cleveland, Jacksonville, Seattle, [Cleveland, [St. Louis, Houston, Arizona, [Buffalo, [NY Giants, [Cleveland, [Cleveland, Baltimore, [Miami, Atlanta, [NY Giants, Atlanta, [Tennessee, SF, [Chicago, Denver, [San Diego, KC, [Oakland, Carolina, [New Orleans, [New England, Philly, [Pittsburgh, Indy, [Washington, Dallas]

The Confidence Ratings successfully get sorted accordingly from descending order, but the teams don't correspond to their respective ratings. In fact, the same team is copied multiple times. How do I fix this problem and get all my teams to correspond to their appropriate rating? (The sortArrays() method is where the sorting action takes place).

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.layout.*;
import javafx.scene.control.*;
import javafx.stage.FileChooser;
import javafx.geometry.*;
import java.util.*;
import java.io.*;

public class POS extends Application
{
   private ArrayList<Double> confidenceList = new ArrayList<>();
   private ArrayList<String> cityList = new ArrayList<>();
   private BorderPane pane = new BorderPane();
   private Button runBtn = new Button("Run");
   @Override
   public void start(Stage stage)
   {


      VBox vBox = new VBox(20);
      vBox.setPadding(new Insets(15));
      Button selectBtn = new Button("Select File");
      selectBtn.setStyle("-fx-font: 22 arial; -fx-base: #b6e7c9;");
      vBox.getChildren().add(selectBtn);

      selectBtn.setOnAction(e->
      {
         FileChooser fileChooser = new FileChooser();
         fileChooser.setTitle("Open Resource File");
         FileChooser.ExtensionFilter extFilter = 
                        new FileChooser.ExtensionFilter("TEXT files (*.csv)", "*.CSV", ".xlsv", ".XLSV");
                fileChooser.getExtensionFilters().add(extFilter);
         File file = fileChooser.showOpenDialog(stage);

            run(file);


      });

      RadioButton weekBtn = new RadioButton("Current Week");  
      RadioButton seasonBtn = new RadioButton("Entire Season");

      runBtn.setStyle("-fx-font: 22 arial; -fx-base: #b6e7c9;");


      weekBtn.setSelected(true);
      seasonBtn.setDisable(true);
      vBox.getChildren().add(weekBtn);
      vBox.getChildren().add(seasonBtn);
      vBox.getChildren().add(runBtn);

      pane.setLeft(vBox);
      Scene scene = new Scene(pane, 500, 200);
      stage.setScene(scene);
      stage.setTitle("POS");
      stage.show();
   }
   public void run(File file)
   {
      runBtn.setOnAction(e->
      {
         try
         {
            Scanner input = new Scanner(file);
            input.nextLine(); 
            sortFile(file, input);

            input.close();
         }

         catch (InputMismatchException ex)
         {
            System.out.println("Error you seem to have typed the wrong type of file");
         }
         catch(IOException ex)
         {
            System.out.println("Error, file could not be found");
         }


      });
   }
   public void sortFile(File file, Scanner input)
   {
      if (!input.hasNext())
      {
         sortArrays(confidenceList, cityList);
      }
      else
      {
      String strList = Arrays.toString(input.nextLine().split("\t"));
      String[] arrList = strList.split(",");

      int homeRank = Integer.parseInt(arrList[1]);

      int roadRank = Integer.parseInt(arrList[6]);
      Random r = new Random();

      int lowestTeamRank = Math.abs(homeRank - roadRank);

      double numForHomeTeam = 0;
      double numForRoadTeam = 0;
      if (homeRank < roadRank)
      {
         numForHomeTeam = ((r.nextInt(lowestTeamRank) - r.nextInt(2)) + (getLastGameOutcome(arrList[4])* r.nextInt(3))) - getWinPct(arrList[2], arrList[3]);

         numForRoadTeam = ((r.nextInt(roadRank) + r.nextInt(2)) + (getLastGameOutcome(arrList[9])* r.nextInt(3))) - getWinPct(arrList[7], arrList[8]);
      }

      else if (homeRank > roadRank)
      {
         numForHomeTeam = ((r.nextInt(homeRank) - r.nextInt(2)) + (getLastGameOutcome(arrList[4])* r.nextInt(3))) - getWinPct(arrList[2], arrList[3]);

         numForRoadTeam = r.nextInt(lowestTeamRank) - r.nextInt(2) + getLastGameOutcome(arrList[9])* r.nextInt(3) - getWinPct(arrList[7], arrList[8]);
      }



      double confidenceRate = Math.round(Math.abs(numForHomeTeam - numForRoadTeam));
      confidenceList.add(confidenceRate);
      if (numForHomeTeam < numForRoadTeam)
      {
          cityList.add(arrList[0]);
          cityList.add(arrList[5]);
      }
      else if (numForHomeTeam > numForRoadTeam)
      {
         cityList.add(arrList[5]);
         cityList.add(arrList[0]);
      }
      else
      {
         cityList.add(arrList[0]);
         cityList.add(arrList[5]);
      }

      sortFile(file, input);
      }
   }

   public int getLastGameOutcome(String lastGame)
   {
      if (lastGame.charAt(0) == 'W')
      {
         return (int)(Math.random() * 3);
      }

      else
      {
         return (int)(Math.random() * -3);
      }  
   }

   public double getWinPct(String wins, String losses)
   {
       double newWins = Double.parseDouble(wins);
       double newLosses = Double.parseDouble(losses);
       return newWins / (newWins + newLosses);
   } 

   public void sortArrays(ArrayList<Double> doubleArray, ArrayList<String> stringArray)
   {
      System.out.println(doubleArray);
      System.out.println(stringArray);
      for (int i = 0; i < doubleArray.size(); i++)
      {
         for (int j = 0; j < doubleArray.size(); j++)
         {
            if (doubleArray.get(j).compareTo(doubleArray.get(i)) < 1)
            {
               double tempDouble = doubleArray.get(j);
               doubleArray.set(j, doubleArray.get(i));
               doubleArray.set(i, tempDouble);

               String tempString = stringArray.get(j);
               String tempString2 = stringArray.get(j + 1);
               stringArray.set(j, stringArray.get(i));
               stringArray.set(j + 1, stringArray.get(i + 1));
               stringArray.set(i, tempString);
               stringArray.set(i + 1, tempString2);
            }
         }
      }

      System.out.println(doubleArray);
      System.out.println(stringArray);
   } 

}

Instead of having two independent data structures, I would combine these into a single List of a simple Java object that represents the underlying meaning of the data.

For example, to hold the confidence rating and the team:

public class TeamConfidence implements Comparable<TeamConfidence> {
  private String team;
  private double confidence;

  public TeamConfidence(String team, double confidence) {
    this.team = team;
    this.confidence = confidence;
  }

  @Override
  public int compareTo(TeamConfidence other) {
      if(other == this) { 
        return true;
      } else if (other == null ) {
        return false;
      } else {
        return Double.compare(confidence, other.confidence);
      }
  }

  // include getters and setters, maybe a constructor
}

Since it implements the Comparable interface, you can use a Collections.sort call to sort by confidence:

List<TeamConfidence> teams = new ArrayList<>();
// populate list
Collections.sort(teams);
// list is now ordered by confidence, and still retains the relation between 
// the team name and the confidence level

Here's a simplified example for how we'd go about implementing this.

Let's say we have a minimal data set, using your original example, with Denver and Baltimore thrown in as some lower outliers:

| Team      | Confidence |
| Atlanta   | 25         |
| Michigan  | 25         |
| Detroit   | 22         |
| NY        | 22         |
| Denver    | 13         |
| Baltimore | 1          |

Note I added a constructor to the TeamConfidence class above for demonstration purposes.

We'd first create ourselves a set of TeamConfidence objects. We'll create them manually here as an example, but this is the sort of thing that you could adjust for reading from file, database, or other data source.

We'll also add the objects to the List while we're at it.

// declare a list to hold the TeamConfidence objects
List<TeamConfidence> teams = new ArrayList<>();

// populate the list
teams.add(new TeamConfidence("Detroit", 22.0));
teams.add(new TeamConfidence("Atlanta", 25.0));
teams.add(new TeamConfidence("Baltimore", 1.0));
teams.add(new TeamConfidence("Michigan", 25.0));
teams.add(new TeamConfidence("NY", 22.0));
teams.add(new TeamConfidence("Denver", 13.0));

At this point, we have a List of teams. Now we call sort :

Collections.sort(teams);

Now our list has our teams in order. Depending on how you implement the compareTo method in TeamConfidence , this either will result in smaller first, or larger first. (To swap the order, multiple by -1; eg. -1*Double.compare(confidence, other.confidence); )

Assuming that this compare-to is implemented as smaller-first, which I think it is (but I can't recall off the top of my head), our List will be ordered as follows:

[(Baltimore, 1.0), (Denver, 13.0), (NY, 22.0), (Detroit, 22.0), (Atlanta, 25.0), (Michigan, 25.0)]

Note that since our compareTo method only takes into account the confidence, there is no ordering within a confidence level; so NY and Detroit will be adjacent, but there is no guarantee that NY will come before Detroit consistently.


Per the comments below, it may be best to have the model be as follows:

public class TeamConfidence implements Comparable<TeamConfidence> {
  private String winner;
  private String loser;
  private double confidence;

  public TeamConfidence(String winner, String loser, double confidence) {
    this.winner = winner;
    this.loser = loser;
    this.confidence = confidence;
  }

  @Override
  public String toString() {
    return "(" + confidence + ", " + winner + ", " + loser ")";
  }

  @Override
  public int compareTo(TeamConfidence other) {
      if(other == this) { 
        return true;
      } else if (other == null ) {
        return false;
      } else {
        return Double.compare(confidence, other.confidence);
      }
  }
}

Now, when you sort by confidence, each element in the list will indicate both the winner and the loser.

Data:

| Winner  | Loser     | Confidence |
| Atlanta | Michigan  | 25         |
| NY      | Detroit   | 22         |
| Denver  | Baltimore | 13         |

Code:

List<TeamConfidence> teams = new ArrayList<>();

// populate the list
teams.add(new TeamConfidence("Atlanta", "Michigan", 25.0));
teams.add(new TeamConfidence("NY", "Detroit", 22.0));
teams.add(new TeamConfidence("Denver", "Baltimore", 13.0));

Collections.sort(teams);

Result:

// (confidence, winner, loser)
[(13.0, Denver, Baltimore), (22.0, NY, Detroit), (25.0, Atlanta, Michigan)]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM