размещение данных в стеке изменяет все данные внутри до последних переданных данных. - PullRequest
0 голосов
/ 14 декабря 2018

В основном я должен реализовать метод отмены и возврата.этот метод будет применяться к списку символов двойной ссылки каждый раз, когда я изменяю список ссылок, я должен поместить его в стек отмены.Однако всякий раз, когда я нажимаю, список отправленных новейших ссылок меняет все в стеке на этот новый список ссылок.имейте в виду, что я не могу использовать массив, если я не использую массив для реализации стека.Я пытался решить эту проблему в течение 2 дней, но каждый метод, который я продолжаю делать, в итоге дает одинаковые результаты. Я уверен, что проблема в том, что я неправильно нажимаю на список ссылок, но я не могу понять это.Работают стек и список ссылок. Я тестировал их в других программах

Это мои методы push и pop

public void push(DoubleLinkList temp) {// simple push function
    size++;
    array[++top] = temp;
}

public DoubleLinkList pop() {
    if (size == 0) {
        return null;
    }
    size--;
    DoubleLinkList n = array[top];
    array[top] = null;// to prevent possible errors
    top--;
    return n;
}

Это мои методы отмены и возврата

public void undo() {
    DoubleLinkList temp = new DoubleLinkList();
    temp.head = head;
    temp.tail = tail;
    redo.push(temp);
    DoubleLinkList x = undo.pop();

    head = x.head;
    tail = x.tail;

}

public void UndoStack() {
    DoubleLinkList temp = new DoubleLinkList();
    temp.head = head;
    temp.tail = tail;
    undo.push(temp);
}

public void redo() {
    UndoStack();
    DoubleLinkList temp = redo.pop();
    head = temp.head;
    tail = temp.tail;
}

Наконец, я вызываю этот метод каждый раз, когда меняю что-то из других функций, чтобы поместить его в стек

public void appendsub(String S) {// simple append add after the last character
    UndoStack();
    for (int i = 0; i < S.length(); i++) {
        add(S.charAt(i));
    }
}

Это код списка двойной ссылки

public class DoubleLinkList {

    Node head, tail;
    int size;
    StackUndo undo;
    StackUndo redo;

    public DoubleLinkList() {
        // empty constructor
    }

    public DoubleLinkList(String S) {
        undo = new StackUndo();// creat a undo and redo stack
        redo = new StackUndo();
        size = 0;// Initialize the size
        for (int i = 0; i < S.length(); i++) {// for loop to convert the string into a link list of characters
            add(S.charAt(i));
            size++;
        }

    }

    public void Insert(int n, String S) {// the main insert function to insert at a position n
        UndoStack();
        if (n < size) {// to clear any potential errors
            Node x;
            int count = 1;
            for (x = head; x != null && count != n; x = x.getNext()) {// Traverse to the specific index
                count++;
            }
            for (int i = S.length() - 1; i >= 0; i--) {// add characters after the specific index
                addafter(x, S.charAt(i));
            }

        } else
            appendsub(S);// if the index is greater than the size just append
    }

    public void appendsub(String S) {// simple append add after the last character
        UndoStack();
        for (int i = 0; i < S.length(); i++) {
            add(S.charAt(i));
        }
    }

    public void Erasen(int pos, int n) {// function to erase n characters starting at a specific position
        UndoStack();
        Node x;
        int count = 0;
        if (pos < size) {// if the pis is greater than the size of the link list then do nothing
            for (x = head; x != null && count != pos; x = x.getNext()) {// Traverse to the specific index
                count++;
            }
            for (int i = 0; i < n; i++) {// start removing node by node n times
                Remove(x);
                x = x.getNext();
            }
        } else
            return;// if it is larger than the size then just exit
    }

    public void trailing(int n) {// function to remover from the end n elements
        UndoStack();
        Node x;
        int count = 0;
        for (x = tail; x != null && count != n; x = x.getPrev()) {
            {// reach the last element we want to keep
                count++;
            }
            tail = x;// set the last element as the new tail
            tail.setNext(null); // remove everything after that. this port isn't necessary but is just a helpful
                                // visual aid
        }
    }

    public void leading(int n) {// a function to remove from the beginning
        UndoStack();
        Node x;
        int count = 0;
        for (x = head; x != null && count != n; x = x.getNext()) {// reach the first element we want to keep
            count++;
        }
        head = x;// set the new element as the head and remove everything before it
        head.setPrev(null);
    }

    public void replace(String S, String N) {// the main replace function to replace every occurrence of sub string S
                                             // with the substring N
        UndoStack();
        Node x;
        for (x = head; x != null; x = x.getNext()) {// traverse the link list
            if (x.getC() == S.charAt(0)) {// check if the character is equal to the first character of the string that
                                          // we want to replace
                if (checkSub(x, S)) {// send it to check if the whole string is correct
                    for (int i = 0; i < S.length(); i++) {// if it is correct then start removing the element
                        Remove(x);
                        x = x.getNext();
                    }
                    for (int i = N.length() - 1; i >= 0; i--)// replace the removed element with the new string N
                        addafter(x.getPrev(), N.charAt(i));
                }
            }
        }
    }

    public void add(char c) {// a function to add a character to the end of the link list
        Node n = new Node(c);
        if (head == null) {
            head = n;
            tail = n;
            size++;
        }
        tail.setNext(n);
        n.setPrev(tail);
        tail = n;
        size++;
    }

    public void addafter(Node x, char c) {// a function to add a character after a specifiv node
        Node n = new Node(c);
        x.getNext().setPrev(n);
        n.setNext(x.getNext());
        x.setNext(n);
        n.setPrev(x);
        size++;
    }

    public void Remove(Node x) {// function to remove a node
        if (x != null) {
            Node pre = x.getPrev();
            Node nex = x.getNext();
            pre.setNext(nex);
            nex.setPrev(pre);
        }
    }

    public boolean checkSub(Node x, String S) {// this will check if a string is equal to another starting from a
                                               // specific node in a link list of characters
        for (int i = 0; i < S.length(); i++) {
            if (S.charAt(i) != x.getC())
                return false;// if it is not equal then it will return false and end else it will return true
            x = x.getNext();
        }
        return true;
    }

    public void print() {// simple print function
        for (Node i = head; i != null; i = i.getNext()) {
            System.out.print(i.getC());
        }
        System.out.println();
    }

    public void undo() {
        DoubleLinkList temp = new DoubleLinkList();
        temp.head = head;
        temp.tail = tail;
        redo.push(temp);
        DoubleLinkList x = undo.pop();

        head = x.head;
        tail = x.tail;

    }

    public void UndoStack() {
        DoubleLinkList temp = new DoubleLinkList();
        temp.head = head;
        temp.tail = tail;
        undo.push(temp);
    }

    public void redo() {
        UndoStack();
        DoubleLinkList temp = redo.pop();
        head = temp.head;
        tail = temp.tail;
    }

}

Это стеккод

public class StackUndo {
    private DoubleLinkList[] array;
    private int top = -1;
    private int size = 0;

    public StackUndo() {
        this.array = new DoubleLinkList[200];
    }

    public void push(DoubleLinkList temp) {// simple push function
        size++;
        array[++top] = temp;
    }

    public DoubleLinkList pop() {
        if (size == 0) {
            return null;
        }
        size--;
        DoubleLinkList n = array[top];
        array[top] = null;// to prevent possible errors
        top--;
        return n;
    }

    public DoubleLinkList getTop() {// return the top element
        DoubleLinkList n = array[top];
        return n;
    }

    public void printstack() {// print the whole stack
        for (int i = 0; i < size; i++)
            array[i].print();
    }
}

код узла

public class Node {

    private char C;
    private Node next;
    private Node prev;

    public Node(char c) {
        super();
        C = c;
    }

    public char getC() {
        return C;
    }

    public void setC(char c) {
        C = c;
    }

    public Node getNext() {
        return next;
    }

    public void setNext(Node next) {
        this.next = next;
    }

    public Node getPrev() {
        return prev;
    }

    public void setPrev(Node prev) {
        this.prev = prev;
    }

}

тестовый класс

import java.util.Scanner;

public class Test {

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int choice = 0;
        int n1 = 0, n2 = 0;
        String s, s1, s2;
        System.out.println("Enter the string:");
        System.out.print("Your string is:");
        s = input.nextLine();
        DoubleLinkList p = new DoubleLinkList(s);
        while (choice != 9) {
            System.out.print("Actions:\r\n" + "1- Insert a substring at a given position\r\n"
                    + "2- Append a substring to the end of the string\r\n"
                    + "3- Erase n characters at a given position\r\n" + "4- Erase trailing n characters\r\n"
                    + "5- Erase leading n characters\r\n" + "6- Replace all occurrences of a substring by another\r\n"
                    + "7- Undo\r\n" + "8- Redo\r\n" + "9- Exit\n" + "Enter your choice: ");
            choice = input.nextInt();
            switch (choice) {
            case 1:
                System.out.print("Enter substring to be inserted: ");
                input.nextLine();
                s = input.nextLine();
                System.out.print("Enter inserting position: ");
                n1 = input.nextInt();
                p.Insert(n1, s);
                System.out.println("Your string is: ");
                p.print();
                break;
            case 2:
                System.out.print("Enter substring to be appended: ");
                input.nextLine();
                s = input.nextLine();
                p.appendsub(s);
                System.out.println("Your string is: ");
                p.print();

                break;
            case 3:
                System.out.println("Enter the positon you want to start erasing: ");
                n1 = input.nextInt();
                System.out.println("Enter the number of characters you want to erase: ");
                n2 = input.nextInt();
                p.Erasen(n1, n2);
                System.out.println("Your string is: ");
                p.print();

                break;
            case 4:
                System.out.println("Enter the number of characters you want to erase: ");
                n1 = input.nextInt();
                p.trailing(n1);
                System.out.println("Your string is: ");
                p.print();

                break;
            case 5:
                System.out.println("Enter the number of characters you want to erase: ");
                n1 = input.nextInt();
                p.leading(n1);
                System.out.println("Your string is: ");
                p.print();

                break;
            case 6:
                System.out.print("Enter substring to be inserted: ");
                input.nextLine();
                s1 = input.nextLine();
                System.out.print("Enter substring to be replaced: ");
                s2 = input.nextLine();
                p.replace(s2, s1);
                System.out.println("Your string is: ");
                p.print();
                break;
            case 7:
                p.undo();
                p.print();
                break;
            case 8:
                p.redo();
                p.print();
                break;
            case 9:
                System.out.println("Thank you for using our program!!!!!!!!!!!!!!!!!!1");
                break;
            default:
                System.out.println("WRONG INPUT WARNING TRY AGAIN!!");
                break;
            }

        }
    }

}

1 Ответ

0 голосов
/ 15 декабря 2018

В DoubleLinkList вы держите head, который является началом списка символов, и tail, который является концом списка.Когда вы добавляете еще одну строку, вы сохраняете тот же head и просто двигаетесь tail.Таким образом, вы получите последовательность символов, например ...

head ch ch tail1 ch ch ch tail2 ch tail3

И каждая из ваших записей в очереди отмены будет иметь такой же head.

Когда вы печатаетесписок персонажей.Вы начинаете с head и продолжаете, пока не останется больше символов.

public void print() {// simple print function
    for (Node i = head; i != null; i = i.getNext()) {
        System.out.print(i.getC());
    }
    System.out.println();
}

Так что не имеет значения, что вы установили для tail, так как он не используется в методе print(),В результате вы получаете одну и ту же вещь, напечатанную для каждого DoubleLinkList, который имеет одинаковые head.

. Вы можете добавить чек на tail в ваш print ()

, например:

public void print() {// simple print function
    for (Node i = head; i != null && i != tail; i = i.getNext()) {
        System.out.print(i.getC());
    }
    System.out.println(tail.getC());
}

Или вы можете клонировать свой список персонажей, чтобы каждый раз иметь разные головы.

Я бы порекомендовал вам взглянуть на среду модульного тестирования (например, Junit).если вы еще этого не сделалиЭто значительно облегчает отладку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...