Comment dois-je mettre en œuvre les méthodes equals et hashCode de cette HashMap pour représenter un état d'automate?

StackOverflow https://stackoverflow.com/questions/1875810

Question

Je veux mettre des objets de l'État (qui sont HashMaps avec caractère clé et de l'État en tant que valeur dans un ArrayList nommé Allstates. Dois-je remplacer les méthodes equals et hashCode ici? Pourquoi? Comment?

Ce code est pour les classes Automaton et je l'ai État CONSTRUIT jusqu'à présent:

class State extends HashMap<Character, State>{

boolean isFinal;
boolean isInitial;
int stateId;

State () {
    isInitial=false;
    isFinal = false;
    }

public boolean equals (Object o){
    boolean isEqual = false;
    State compare = (State)o;

    if ((compare.stateId)==this.stateId)
    {
        return true;
    }
    return isEqual;
}

public int hashCode() {
    int theHashCode = stateId%7;

    return theHashCode;
}


}

  class Automaton{
     List <State> allStates;
    //private List<State> finalStates;
     int  theInitialStateIntIndex;
     State actualState;
      char [] alphabet;

    Automaton() {
        allStates = new ArrayList<State>();
    }

    public void setAllStates (int numberOfStates)  {
        for (int i =0; i <numberOfStates; i++) {
            State newState = new State();
            newState.stateId = i;
            allStates.add(newState);
         }
    }


    public void setAlphabet (String alphabetLine){
        alphabet = alphabetLine.toCharArray();
    }

    public void markFinalStates (String [] finalStates){
        for (int index =0; index<finalStates.length; index++) {
            int aFinalStateId = Integer.parseInt(finalStates[index]);

            State aFinalState = allStates.get(aFinalStateId);
            aFinalState.isFinal = true;
            allStates.add(aFinalStateId, aFinalState);

            /*DEBUG*/
            aFinalState = allStates.get(aFinalStateId);
            if ((aFinalState.isFinal)==true)
            System.out.println("THE STATE " + aFinalStateId + " IS MARKED AS FINAL");
        }
    }

    public void markInitialState (int initialStateId) {
            State theInitialState = allStates.get(initialStateId);
            theInitialState.isInitial=true;
            allStates.add(initialStateId, theInitialState);

            theInitialStateIntIndex = initialStateId;

            /*DEBUG*/

            System.out.println("THE INITIAL STATE ID IS " + initialStateId);

            theInitialState = allStates.get(initialStateId);
            if ((theInitialState.isInitial)==true)
            System.out.println("THE STATE " + initialStateId + " IS MARKED AS INITIAL");
    }


    public void setTransitions(int stateId, String transitionsLine){
            State theOneToChange = allStates.get(stateId);

            String [] statesToReachStringSplitted = transitionsLine.split(" ");

            for (int symbolIndex=0; symbolIndex<statesToReachStringSplitted.length;symbolIndex++){
                int reachedState= Integer.parseInt(statesToReachStringSplitted[symbolIndex]);
                theOneToChange.put(alphabet[symbolIndex],allStates.get(reachedState));

                System.out.println("THE STATE " + stateId + " REACHES THE STATE " + reachedState + " WITH THE SYMBOL " + alphabet[symbolIndex]);
            }

            allStates.add(stateId, theOneToChange);
    }


    public int findInitialState(){
        int index =0;

       cycle: for (; index<allStates.size(); index++){
            State s = allStates.get(index);

            if (s.isInitial==true) {
                break cycle;
           }
        } return index;
}

    public void processString (String string)
    {
        StringBuilder stepString= new StringBuilder (string);

        int actualStateIntIndex;
        System.out.println("THE FOUND INITIAL ONE IS "+ theInitialStateIntIndex);
        State firstState = allStates.get(theInitialStateIntIndex);
        actualState = firstState;

        while (stepString.length()>0){
           Character characterToProcess = stepString.charAt(0);
           stepString.deleteCharAt(0);

           State nextState;
           nextState = ((State)actualState.get(characterToProcess)); // pasa al siguiente State
           actualState = nextState;

           actualStateIntIndex=allStates.indexOf(actualState);

           System.out.println("the actual state for " + stepString + " is " + actualStateIntIndex);
           if ((actualState.isFinal==true) && (stepString.length()==0))
              {
                  System.out.println("THE STRING " + string + " IS ACCEPTED AT STATE " + actualStateIntIndex );
              }
           else if (stepString.length()==0 && (actualState.isFinal==false)){
                  System.out.println("THE STRING " + string + " IS REJECTED AT STATE " + actualStateIntIndex);
              }

           }
       }
    }
Était-ce utile?

La solution

  1. Si l'automate est un DFA, alors on peut utiliser la chaîne d'ID Accès le champ.
    Un accès à chaîne est une chaîne qui pourrait être utilisé pour atteindre l'état de l'état de départ. Il faudra construire la chaîne pendant la construction du DFA, cependant, il ne sera pas ajouter plus de complexité temporelle. (Oui, il faut alors Hashcode / égalent la chaîne)

  2. Ou en fait, les ID états par un numéro de série de plus en plus / string devrait fonctionner pour tous les automates. Ensuite hashcode / égal basé sur l'ID.

Optez pour le 2ème, plus facile et fonctionne mieux que 1, à moins que vous voulez prendre soin des états dupliqués.

Oui, vous avez besoin du hashcode et equals pour un type défini par l'utilisateur de travailler avec hachage.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top