Разделение значения в связанном списке - PullRequest
0 голосов
/ 12 апреля 2020

Я пишу код, который представляет процесс рекомбинантной ДНК. Я бью кирпичную стену о том, как двигаться вперед с помощью метода вырезания и соединения. Я дошел до того, что написал некоторое время oop, которое ищет индекс фермента, который мы ищем, но теперь я столкнулся с кирпичной стеной.

Мой класс представляет собой связанный список, и он предназначен для следующих действий:

  • Сначала он получает цепочку ДНК, представленную в виде строки, и помещает всю строку в первый узел LinkedList.
  • Чем он ищет определенную c последовательность фермента в цепи (String в узле) (в то время как l oop в cutAndConnect)
  • Чем ему нужно разрезать строку в этой точке, а в конце фермента, вырезая фермента.
  • Чем нужно разместить соединение в новом узле, и ту часть цепи (String), которая появилась после последовательности фермента в другом новом узле.
  • И это необходимо сделать для всей цепи, поэтому за все время, когда в цепи встречается специфическая c последовательность фермента.

Я также добавил все из методов, которые я еще не вставил ни в какое тело. DnaStreng - это интерфейс, который используется в этом проекте, но он не добавил интерфейс в этот вопрос, потому что он содержит только javascript для всех методов.

Я надеюсь, что некоторые из вас помогут мне продвинуться вперед в этом. У меня есть следующий код:

public class LinkStreng implements DnaStreng{

    public static LinkStreng STRING_LEEG = new LinkStreng();
    private String dna;
    List<String> dnaList= new LinkedList<String>();
    Node head;
    Node next;

    /* Makes a new String with length 0*/
    public LinkStreng(){
        this("");
    }

    /* Makes a new LinkStreng with the given DNA(in the main class there is a 
     filechooser used.*/
    public LinkStreng(String hetDna){
     dna = hetDna;
     head = null;
     Node firstNode = new Node(hetDna);
    }

    /*Counts the number of Nodes in the list*/
    public int getCount(){
        Node temp = head;
        int count = 0;
        while (temp!= null){
            count++;
            temp = temp.next;
        }
        return count;
    }

    / ** Simulates a cut by a restriction enzyme. Seeks the first occurrence
    * of the enzyme in this strand and removes the enzyme and everything after it
    * coming. Returns the part after the enzyme as a new strand. If the
    * enzyme does not occur in this strength, it remains unchanged and an
    * returned empty strand will be returned.
    * @param enzyme the string to search for
    * @return the part of this strength after the enzyme */
    public DnaStreng cutWith(String enzym) {
        // Here I get an error that it cannot find the getCount method
        if (dnaList.getCount() >1){
            throw new RuntimeException("Linkstreng heeft meer dan 1 node");
        } else {             
        int enzymBegin = dna.indexOf(enzym);
        if (enzymBegin == -1) return STRENG_LEEG;

        // Enzyme found: cut
        String dnaAchterEnzym = dna.substring(enzymBegin + enzym.length());
        DnaStreng achter = new LinkStreng(dnaAchterEnzym);
        initialiseer(dna.substring(0, enzymBegin));
        return achter;
        }
    }



     /** Cut this strand wherever the enzyme occurs and connect the
     * pieces by placing the connection between them.
     * @param enzym the string to search for
     * @param connectionthe DNA that will replace the enzyme
     * @return the new strand (the original strand remains unchanged) */
    public DnaStreng cutAndConnect(String enzym, String connection) {
        // With this getCount I get the same error
        if (dnaList.getCount() > 1){
            throw new RuntimeException("Linkstreng heeft meer dan 1 node");
        }
        String teSplitsen = " " + dna + " ";
        int i = 0;
        while ( i < dna.length()){
        dna.indexOf(enzym, i);
        i++;
        }

        return new LinkStreng();

    }

    /* Gives the number of letters in the strand */
    public long lengte() {
      // this method isn't working as well, it returns the wrong number
       return dnaList.toString().length();
    }

    /** Initializes this strand by inserting the DNA, any
     * previous data is erased. Does not check for valid DNA letters.
     * @param dna the DNA string placed in this strand * /
    public void initialiseer(String hetDna) {

    }



    /** Adds the addition behind this strand.
     * @param addition the strand being added */
    public void voegToe(DnaStreng addition) {

    }

    /** Adds the addition behind this strand.
     * @param addition the strand being added */
    public void voegToe(String addition) {

    }


    public String toString(){
        Node current = head;
        StringBuilder recombinant = new StringBuilder((CharSequence) dnaList);
        while(current != null){
            recombinant = recombinant.append(head.value);
            current = current.next;
        }
        return recombinant.toString();
    }
}

public class Node {
    public Node next;
    public String value;

    public Node(String s){
        value = s;
        next = null;
    }
}

} ​​

1 Ответ

0 голосов
/ 13 апреля 2020

Код представляется смесью противоречивых подходов, направленных на достижение одной и той же цели.

Например:

List<String> dnaList = new LinkedList<String>();
Node head;
Node next;
  • С одной стороны, Первая строка в этом примере предполагает, что вы пытаетесь использовать LinkedList из стандартной библиотеки Java.

  • С другой стороны, следующие две строки свидетельствуют о попытке иметь собственную реализацию структуры данных связанного списка.

Есть и другие примеры того, почему этот код не работает, я считаю, что он достаточно убедителен.

Вообще, чтобы избежать хаотического c подхода к написанию всей программы за один раз (Рим не был построен за один день!), Я настоятельно рекомендую работать с одним небольшим битом за раз и писать тесты для каждого бита.

Я продемонстрирую предложенный подход и пошагово перейду к вашему списку:

  1. Сначала он получает цепочку ДНК в виде строки и помещает всю Строка в первом узле LinkedList.

По всей вероятности, вы не хотите хранить всю строку в одном узле. Что вам действительно нужно - это сохранить символ (который представляет собой всего одну букву, тогда как строка представляет собой последовательность букв).

public class DNAStrand {
    Node head = null;

    public DNAStrand(final String dnaStrand) {
        if (dnaStrand.isEmpty()) {
            return;
        }

        // Initialise the first node of a list
        Node currentNode = new Node(dnaStrand.charAt(0));

        // Assign the first Node to `head`
        head = currentNode;

        // Iterate through the rest of string storing remaining characters
        for (int i = 1; i < dnaStrand.length(); i++) {
            final Node nextNode = new Node(dnaStrand.charAt(i));
            currentNode.next = nextNode;
            currentNode = nextNode;
        }
    }

    private static class Node {
        public Node next;
        public char value;

        public Node(char s) {
            value = s;
            next = null;
        }
    }

    // Tests are located below this line
    private static void testDnaStrandIsPlaceDInTheFirstNodeOfLinkedList() {
        final DNAStrand dnaStrand = new DNAStrand("acgt");
        if (dnaStrand.head == null) {
            throw new AssertionError("The head is null after creating an object from a string");
        }

        List<Character> actualString = new ArrayList<>();
        Node listPointer = dnaStrand.head;
        do {
            actualString.add(listPointer.value);
            listPointer = listPointer.next;
        } while (listPointer != null);

        if (!"acgt".equals(actualString.stream().map(String::valueOf).collect(Collectors.joining()))) {
            throw new AssertionError("Wrong value in the first node, expected: 'agct;, got: "
                    + dnaStrand.head.value);
        }
    }

    public static void main(String[] args) {
        testDnaStrandIsPlaceDInTheFirstNodeOfLinkedList();
    }
}

Метод main в моем примере выполняет тест testDnaStrandIsPlaceDInTheFirstNodeOfLinkedList. Этот тест гарантирует, что простой контракт будет выполнен. По мере того, как код становится больше, вам лучше добавлять больше тестов, чтобы не нарушать старые функции и доказать, что новый код работает хорошо.

  • Чем он ищет определенную c последовательность ферментов в цепочке (String in the node) (в то время как l oop в cutAndConnect)
  • Затем необходимо отрезать строку в этой точке, а в конце фермента - вырезать энзим вышел.
  • Затем ему нужно поместить соединение в новый узел, а ту часть цепи (String), которая появилась после последовательности фермента в другом новом узле.
  • И это необходимо сделать это для всей цепи, поэтому для всех случаев, когда в цепи встречается указанная c последовательность фермента.

По сути, это описание одного метода. Я добавлю cutAndConnect(), который выполняет то, что вы просите, вместе с тестами, которые объясняют / доказывают, что это работает.

public class DNAStrand {
    Node head = null;

    public DNAStrand(final String dnaStrand) {
        if (dnaStrand.isEmpty()) {
            return;
        }

        head = stringToListNodes(dnaStrand);
    }

    private static class Node {
        public Node next;
        public Node previous;
        public char value;

        public Node(char character, final Node previousNode) {
            this.value = character;
            this.next = null;
            this.previous = previousNode;
        }
    }

    private Node stringToListNodes(final String string) {
        // Initialise the first node of a list
        Node currentNode = new Node(string.charAt(0), null);

        // Assign the first Node to `head`
        final Node head = currentNode;

        // Iterate through the rest of string storing remaining characters
        for (int i = 1; i < string.length(); i++) {
            final Node nextNode = new Node(string.charAt(i), currentNode);
            currentNode.next = nextNode;
            currentNode = nextNode;
        }

        return head;
    }

    public void cutAndConnect(final String enzyme, final String linker) {
        if (linker.isEmpty()) {
            throw new IllegalArgumentException("Linked can't be empty");
        }
        Node potentialEnzymeStart = head;
        while (potentialEnzymeStart != null) {
            Node currentNode = potentialEnzymeStart;
            boolean dismatchFound = false;

            for (char enzymeSymbol : enzyme.toCharArray()) {
                if (enzymeSymbol != currentNode.value) {
                    dismatchFound = true;
                    break;
                }
                currentNode = currentNode.next;
            }

            if (!dismatchFound) {
                // The enzyme does match the sequence
                // The DNA has the following structure <left piece> <enzyme> <right piece>. Find the left and right piece nodes
                Node leftPieceEnd = potentialEnzymeStart.previous;
                if (leftPieceEnd == null) {
                    // Replace the current head
                    head = stringToListNodes(linker);
                } else {
                    // Simply connect a node of a doubly linked list
                    final Node linkedInAFormOfList = stringToListNodes(linker);
                    leftPieceEnd.next = linkedInAFormOfList;
                    linkedInAFormOfList.previous = leftPieceEnd;
                }

                Node connectionPoint = leftPieceEnd == null ? head : leftPieceEnd.next;
                for (int i = 0; i < linker.length() - 1; ++i) {
                    connectionPoint = connectionPoint.next;
                }

                Node rightPieceStart = potentialEnzymeStart;
                for (int i = 0; i < enzyme.length(); ++i) {
                    rightPieceStart = rightPieceStart.next;
                }

                if (rightPieceStart != null) {
                    connectionPoint.next = rightPieceStart;
                    rightPieceStart.previous = connectionPoint;
                }
            }

            potentialEnzymeStart = potentialEnzymeStart.next;
        }
    }

    // Tests are located below this line
    private static void testDnaStrandIsPlaceDInTheFirstNodeOfLinkedList() {
        final DNAStrand dnaStrand = new DNAStrand("acgt");
        if (dnaStrand.head == null) {
            throw new AssertionError("The head is null after creating an object from a string");
        }

        List<Character> actualString = new ArrayList<>();
        Node listPointer = dnaStrand.head;
        do {
            actualString.add(listPointer.value);
            listPointer = listPointer.next;
        } while (listPointer != null);

        if (!"acgt".equals(actualString.stream().map(String::valueOf).collect(Collectors.joining()))) {
            throw new AssertionError("Wrong value in the first node, expected: 'agct`, got: "
                    + dnaStrand.head.value);
        }
    }

    private static void testCutAndConnectCutEntireDNAString() {
        final DNAStrand dnaStrand = new DNAStrand("acgt");
        dnaStrand.cutAndConnect("acgt", "a");
        if (dnaStrand.head == null) {
            throw new AssertionError("The head of a list must not be null");
        }

        if (dnaStrand.head.value != 'a') {
            throw new AssertionError("The head of the list contains wrong value, expected: 'a`, got: " +
                    dnaStrand.head.value);
        }

        if (dnaStrand.head.next != null) {
            throw new AssertionError("The list must have the length 1");
        }
    }

    private static void testCutAndConnectCutTheMiddleOfDNAString() {
        final DNAStrand dnaStrand = new DNAStrand("acca");
        dnaStrand.cutAndConnect("cc", "g");

        List<Character> actualString = new ArrayList<>();
        Node listPointer = dnaStrand.head;
        do {
            actualString.add(listPointer.value);
            listPointer = listPointer.next;
        } while (listPointer != null);

        if (!"aga".equals(actualString.stream().map(String::valueOf).collect(Collectors.joining()))) {
            throw new AssertionError("Wrong value in the list, expected: 'aga`, got: "
                    + dnaStrand.head.value);
        }
    }

    private static void testCutAndConnectCutMultipleOccurrencesOfAnEnzyme() {
        final DNAStrand dnaStrand = new DNAStrand("accacca");
        dnaStrand.cutAndConnect("cc", "g");

        List<Character> actualString = new ArrayList<>();
        Node listPointer = dnaStrand.head;
        do {
            actualString.add(listPointer.value);
            listPointer = listPointer.next;
        } while (listPointer != null);

        if (!"agaga".equals(actualString.stream().map(String::valueOf).collect(Collectors.joining()))) {
            throw new AssertionError("Wrong value in the list, expected: 'agaga`, got: "
                    + dnaStrand.head.value);
        }
    }

    public static void main(String[] args) {
        testDnaStrandIsPlaceDInTheFirstNodeOfLinkedList();
        testCutAndConnectCutEntireDNAString();
        testCutAndConnectCutTheMiddleOfDNAString();
        testCutAndConnectCutMultipleOccurrencesOfAnEnzyme();
    }
}

Я добавил больше тестов, тесты довольно хороши для описания того, что происходит. Я бы посоветовал начать с них читать.

Похоже ли это на то, чего вы хотели достичь?

В целом, вопрос, который вы разместили, не соответствует критериям StackOverflow. Просто потому, что это не вопрос, а скорее «мой код не работает»:)

В следующий раз попытайтесь сузить сферу своего вопроса и приведите минимальный пример кода.

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