private void train(List <Example> examples) {
    classes = uniqueOutputValues(examples);
    classProbabilityTable = new HashMap <String, Double> ();
    categoricalCPT =
        new HashMap <String, List <Map <String, Double> > > ();
    continuousCPT =
        new HashMap <String, List <Pair <Double, Double> > > ();

    int n = examples.size();
    if(n == 0) return;
    nContinuousInputs = examples.get(0).getContinuousInputs().size();
    nCategoricalInputs = examples.get(0).getCategoricalInputs().size();

    List <List <String> > uniqueValues = new ArrayList <List <String> > ();
    for(int i = 0; i < nCategoricalInputs; i++) {
      uniqueValues.add(uniqueCategoricalInputValues(examples, i));
    }

    for(String output : uniqueOutputValues(examples)) {
      List <Example> filteredExamples = filterExamplesByOutput(
          examples, output);
      classProbabilityTable.put(
          output,
          (double) filteredExamples.size() / n);
      categoricalCPT.put(output, new ArrayList <Map <String, Double> > ());
      continuousCPT.put(output, new ArrayList <Pair <Double, Double> > ());
      for(int i = 0; i < nCategoricalInputs; i++) {
        categoricalCPT.get(output).add(
            categoryFrequencyMap(
                filteredExamples, i, uniqueValues.get(i)));
      }
      for(int i = 0; i < nContinuousInputs; i++) {
        continuousCPT.get(output).add(
            normalDistributionOfInput(filteredExamples, i));
      }
    }
  }