Java substr не работает должным образом

Так что я делаю интерпретатор брейкфак на Java, и у меня нет проблем с ним, за исключением [и]. (Неизбежно) Проблема в разборе строки. Итак, что я делаю, чтобы разобраться с циклом, это расположить код между двумя скобками и вызвать функцию (рекурсия), чтобы повторить код внутри скобок. Это звучит хорошо на бумаге, но substring не сотрудничает со мной. Здесь я имею дело с [

void openBracket(short i, String brainfuck)
    {
        /*LOGIC EXPLAINED: First set balance = 1, then loop through all characters after this,
         if another opening bracket is found increment balance, if a close bracket is found, 
         decrement balance. Also, when another close bracket is found test if balance is 1, if
         so then this is the proper bracket*/
        String codeSection = brainfuck.substring(i);
        short balance = 1;
        String codeToRedo;
        short endPoint = -1;

        for (short j = i; j < codeSection.length(); j++) 
        {
        //Check the character
        if (codeSection.charAt(j) == '[') 
        {
            balance++;
        } else if (codeSection.charAt(j) == ']') 
        {
            balance--;

        }
        //Check if it's the right bracket
        if (balance == 1) {
            endPoint = j;
        }
        }

        //Only do such a thing if the cell is not equal to 0
        if (cell[pointer] > 0 && endPoint != -1) 
        {
        codeToRedo = brainfuck.substring(i, endPoint);
        output += brainfuckExecute(codeToRedo);
        } 
        else if (endPoint == -1) //If endpoint is equal to -1, that means that there was no closing bracket
        {
        errorList += "ERROR: No closing bracket (" + i + ")";
        }
    }

Я прошу прощения за отступ, он не очень хорошо копировал Netbeans. Но в любом случае, как вы можете видеть в верхней части кода, я создаю переменную с именем 'codeSection', и она должна содержать правильный текст. Вот что я даю за аргумент "бред": +++[>+++++ +++++<-]>+++. Вот что я получаю, когда печатаю переменную:

[>+++++ +++++<-]>+++.
[>+++++ +++

Да, я печатаю переменную с помощью System.out.println, и у меня печатаются две разные вещи. В первый раз это правильная строка. Во второй раз я получаю то, что обрабатывается, и это не имеет закрывающей скобки. У меня есть система проверки ошибок, встроенная в код для brainfuck, так что я могу проверить. И я получаю ошибку, я должен. (ОШИБКА: нет закрывающей скобки (0)) Я действительно ошеломлен и смущен этим, поэтому любая помощь, предоставленная с благодарностью.

PS Дополнительный код, например, где он называется и так: где он называется:

String brainfuckExecute(String brainfuck)
    {
        //Reset the output
        output = "";

        //Loop through all instructions
        for(short i = 0; i < brainfuck.length(); i++)
        {
        //Execute a switch to do the instructions
        switch(brainfuck.charAt(i))
        {
            //Increment current cell
            case '+': 
            incrementCell();
            break;
            //Decrement current cell
            case '-': 
            decrementCell(i);
            break;
            //Move pointer up
            case '>': 
            incrementPointer(i);
            break;
            //Move pointer down
            case '<': 
            decrementPointer(i);
            break;
            //Get user input and store it in the current cell
            case ',': 
            getInput();
            break;
            //Add the cell to the output string
            case '.': 
            addOutput();
            break;
            //Start the while loop -- Recurssive
            case '[': 
            openBracket(i, brainfuck);
            break;
        }
        }

        //Return said output
        return output;
    }

(Это внутри класса, который имеет все эти переменные) Где main это:

Brainfuck codeTranslator = new Brainfuck();
    System.out.println(codeTranslator.brainfuckExecute("+++[>+++++ +++++<-]>+++."));
    System.out.println(codeTranslator.getErrors());

Еще раз спасибо

1 ответ

Решение

Когда вы звоните openBracket() впервые у вас есть i == 3 а также brainfuck == "+++[>+++++ +++++<-]>+++.", Итак, в первом substring() Вам звонят

String codeSection = brainfuck.substring(3);

Что приводит к:

String codeSection = "+++[>+++++ +++++<-]>+++.".substring(3);
String codeSection = "[>+++++ +++++<-]>+++."

Затем вы перебираете codeSection чтобы увидеть, если он сбалансирован. Проблема в том, что вы уже вырезали деталь перед [, но вы начинаете свой цикл в j = 3, Я отмечу текущие позиции индекса ( )так проще следовать

Вы начинаете цикл в j = 3:

[>+(+)+++ +++++<-]>+++.

И идти до j = 14, который является индексом - как раз перед ]:

[>+++++ +++++<(-)]>+++.

Так как вы не нашли первый [, значение balance было 1 все это время. Итак, в конце концов, вы сделали endPoint = 14,

if (balance == 1) {
    endPoint = j;
}

В следующей итерации вы найдете ], а также balance уменьшается до 0так что цикл продолжает идти, но endPoint не обновляется снова.

После этого вы делаете:

codeToRedo = brainfuck.substring(i, endPoint);

Что приводит к:

codeToRedo = brainfuck.substring(3, 14);
codeToRedo = "+++[>+++++ +++++<-]>+++.".substring(3, 14);
codeToRedo = "[>+++++ +++";

Я полагаю, что ваш цикл действительно должен быть:

for (short j = 0; j < codeSection.length(); j++) { ... }

И наконец, чтобы получить только часть brainfuck это между скобками, вы должны заметить, что в то время как balance 1, вы продолжаете обновлять значение endPoint, Я думаю, что вы хотите остановиться, когда найдете балансировочный кронштейн, так что вы можете добавить break внутри вашего if:

for (short j = 0; j < codeSection.length(); j++) {
    //Check the character
    if (codeSection.charAt(j) == '[') {
        balance++;
    } else if (codeSection.charAt(j) == ']') {
        balance--;
    }
    //Check if it's the right bracket
    if (balance == 1) {
        endPoint = j;
        break; // Stop when you find the ] position
    }
}

Затем сделайте:

codeToRedo = brainfuck.substring(i + 1, i + endPoint);

Или же:

codeToRedo = codeSection.substring(1, endPoint);

Кроме того, вы объединяете результаты brainfuckExecute() когда вы делаете output += brainfuckExecute(codeToRedo), Наверное, поэтому он выглядит так, будто печатает дважды.

Другие вопросы по тегам