Как я должен реализовать методы equals и hashCode этой хэш-карты для представления состояния автомата?

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

Вопрос

Я хочу поместить объекты состояния (которые представляют собой хэш-карты с символом в качестве ключа и состоянием в качестве значения) в список массивов с именем allStates.Должен ли я переопределить методы equals и hashCode здесь?Почему?Каким образом?

Этот код предназначен для классов Automaton и State, которые я создал до сих пор:

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);
              }

           }
       }
    }
Это было полезно?

Решение

  1. Если автомат является DFA, то можно использовать строку доступа для идентификации поля.
    Строка доступа - это любая строка, которая может быть использована для перехода к состоянию из начального состояния.При построении DFA придется создавать строку, однако это не добавит больше временных сложностей.(Да, затем нужно хэш-кодировать / равнять строку)

  2. Или, на самом деле, идентификация состояний по возрастающему серийному номеру / строке должна работать для всех автоматов.Затем hashcode / равно на основе идентификатора.

Выберите 2-й вариант, он проще и работает лучше, чем 1, если только вы не хотите позаботиться о дублированных состояниях.

Да, вам нужен hashcode и equals для пользовательского типа для работы с hash.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top