Алгоритм обратного кубика - PullRequest
1 голос
/ 24 апреля 2020

Я весь день боролся за эту простую функцию, но я не могу заставить ее работать так, как хотелось бы. Сначала это может показаться простым, и в Переполнении стека действительно есть еще одна запись, в которой об этом говорится. Тем не менее, все становится грязным, когда вводятся скобки. Допустим, мы можем получить алгоритм для кубика Рубика, который будет выглядеть примерно так: (RUR 'U) U' (RU 'R') Важно отметить, что после каждого хода, имеет ли он "" "или нет, это пробел, за исключением тех, которые находятся перед скобками. Теперь для каждого алгоритма в кубике Рубика существует его обратный алгоритм, который отменяет его. Например, обратное значение R - это R ', а U - это U, а обратное к RU - это U' R '. Таким образом, обратный пример этого примера: (RU R ') U (U' RU 'R') Также важно отметить, что существует много ходов (F, B, D, U, u, f, M, S , x, y, z ...) Кроме того, у каждого alg есть свой обратный (R имеет R 'и наоборот. Можете ли вы получить какую-либо функцию в Java для этого? Я пробовал бесконечные циклы ifelse, for, switch. .. Я оставлю некоторые из моих попыток только для справки


        String fullAlg = text.toString() + " ";
        String reversedAlg = "hh";
        int numSpaces = 1;
        int pos1 = 0, pos2 = 0;
        for (int i = 0; i < text.length(); i++) {
            if (text.charAt(i) == ' ' && numSpaces == 0) {
                numSpaces++;
                pos1 = i;
            }

            if (text.charAt(i) == ' ' && numSpaces == 1) {
                numSpaces++;
                pos2 = i;
            }
            if (numSpaces == 2) {
                if (fullAlg.substring(pos1, pos2).matches("[a-zA-Z]+")){
                    Toast.makeText(this, "YES", Toast.LENGTH_SHORT).show();
                }
                switch (fullAlg.substring(pos1, pos2)) {

                    //Begin with (
                    case "(" + "[a-zA-Z]+":
                        reversedAlg += ")'" + fullAlg.substring(pos1, pos2).charAt(1);
                        break;
                    case "(" + "[a-zA-Z]+" + "\'":
                        reversedAlg += ")" + fullAlg.substring(pos1, pos2).charAt(1);
                        break;
                    case "(" + "[a-zA-Z]+" + "2":
                        reversedAlg += ")2" + fullAlg.substring(pos1, pos2).charAt(1);
                        break;

                    //No ()
                    case "[a-zA-Z]+":
                        reversedAlg += " '" + fullAlg.substring(pos1, pos2).charAt(0);
                        break;
                    case "[a-zA-Z]+" + "\'":
                        reversedAlg += " '" + fullAlg.substring(pos1, pos2).charAt(0);
                        break;
                    case "[a-zA-Z]+" + "2":
                        reversedAlg += " 2" + fullAlg.substring(pos1, pos2).charAt(0);
                        break;

                    //End with )
                    case "[a-zA-Z]+" + ")":
                        reversedAlg += " '" + fullAlg.substring(pos1, pos2).charAt(1) + "(";
                        break;
                    case "[a-zA-Z]+" + "\'" + ")":
                        reversedAlg += " " + fullAlg.substring(pos1, pos2).charAt(1) + "(";
                        break;
                    case "[a-zA-Z]+" + "2" + ")":
                        reversedAlg += " )2" + fullAlg.substring(pos1, pos2).charAt(1) + "(";
                        break;

                    //Encapsulated in ()
                    case "(" + "[a-zA-Z]+" + ")":
                        reversedAlg += " )'" + fullAlg.substring(pos1, pos2).charAt(1) + "(";
                        break;
                    case "(" + "[a-zA-Z]+" + "\'" + ")":
                        reversedAlg += " )" + fullAlg.substring(pos1, pos2).charAt(1) + "(";
                        break;
                    case "(" + "[a-zA-Z]+" + "2" + ")":
                        reversedAlg += " )2" + fullAlg.substring(pos1, pos2).charAt(1) + "(";
                        break;
                }
                numSpaces = 0;
            }
        }

        StringBuilder returnAlg = new StringBuilder(reversedAlg).reverse();
        algTV.setText(fullAlg.substring(pos1, pos2));

    }

Или этот


        String fullAlg = text.toString();
        String fullAldReversed = "";
        int posStart = 0, posEnd = 0;
        for (int i = 0; i < fullAlg.length(); i++) {
            if (fullAlg.charAt(i) == '('){
                posStart = i;
            } else if (fullAlg.charAt(i) == ')'){
                posEnd = i;
                fullAldReversed += "(" + reverseAlg(fullAlg.substring(posStart, posEnd)) + ")";
                posStart = 0;
            }
        }
        if (posEnd == 0){
            fullAldReversed = "" + reverseAlg(fullAlg);
        }
        algTV.setText(fullAldReversed);
    }

    private StringBuilder reverseAlg(CharSequence text) {

        StringBuilder builder;
        if (!(text.charAt(0) == ' ' || text.charAt(text.length() - 1) == ' ')) {
            builder = new StringBuilder(text + " ");
        } else {
            builder = new StringBuilder(text);
        }
        int subStart = 0;
        StringBuilder auxBuilder;
        String substring = "", auxString = "";
        for (int i = 0; i < builder.length(); i++) {
            substring = "";
                int subEnd = i;
                int identifierMove = 0;
                for (int j = subStart; j <= subEnd; j++) {
                    if (builder.charAt(j) == '\'')
                        identifierMove = 1;
                    else if (builder.charAt(j) == '2')
                        identifierMove = 2;
                    else if (identifierMove == 0)
                        identifierMove = 3;
                }

                String letterMove;

                switch (identifierMove) {
                    case 1:
                        letterMove = builder.substring(subStart, subEnd - 1);
                        subStart = subEnd + 1;
                        substring = " " + letterMove;
                        break;
                    case 2:
                        letterMove = builder.substring(subStart, subEnd - 1);
                        subStart = subEnd + 1;
                        substring = " 2" + letterMove;
                        break;
                    case 3:
                        letterMove = builder.substring(subStart, subEnd);
                        subStart = subEnd + 1;
                        substring = " '" + letterMove;
                        break;
                }
            auxString += substring;
        }

        auxBuilder = new StringBuilder(auxString);
        auxBuilder.reverse().toString();
        return auxBuilder;
    }

Спасибо !!

Ответы [ 3 ]

1 голос
/ 24 апреля 2020

Извините за задержку! Твои попытки, на мой взгляд, довольно сложны. Я подумал, что это лучший выбор, чтобы создать класс для представления алгоритма куба Rubix, потому что он немного сложен, и класс также оставит место для дальнейшего расширения. В любом случае, как это работает, просто. Конструктор класса принимает строку в качестве входных данных и преобразует текст в целые числа для упрощения хранения и манипулирования. Отсюда, обратный алгоритм очень прост! Все, что вам нужно сделать, это изменить порядок массива в обратном порядке и умножить все целые числа на -1! (Их противоположности, т. Е. R ', сохраняются как отрицательные значения.) Затем, если вы хотите вывести его в виде строки, вы можете использовать функцию toStrng () для отображения алгоритма.

import java.util.ArrayList;
import java.util.Arrays;

class RubixAlg {
  //We will store our list of moves as integers. (And also parentheses) Any X' is the negative value of X
  //For example, U corresponds to 2, and U' corresponds to -2.
  ArrayList<Integer> moves = new ArrayList<Integer>();
  RubixAlg(String input){
    String input1 = input+" ";//Adding a space to the end prevents the algorithm from breaking when it checks for an apostrophe where no text exists.
    while(input1.length()>0){
      println(input1.charAt(0)); 
      //This part figures out what character is the first in the string, what move that corresponds to, and then deletes it until there's no more characters.
      switch(input1.charAt(0)){ 
        case ' ':
          input1=input1.substring(1);
          break;
        case '(':
          moves.add(1);
          input1=input1.substring(1);
          break;
        case ')':
          moves.add(-1);
          input1=input1.substring(1);
          break;
        case 'U':
          if(input1.charAt(1)=='\''){
            moves.add(-2);
            input1=input1.substring(2);
          } else {
            moves.add(2);
            input1=input1.substring(1);
          }
          break;
        case 'D':
          if(input1.charAt(1)=='\''){
            moves.add(-3);
            input1=input1.substring(2);
          } else {
            moves.add(3);
            input1=input1.substring(1);
          }
          break;
        case 'F':
          if(input1.charAt(1)=='\''){
            moves.add(-4);
            input1=input1.substring(2);
          } else {
            moves.add(4);
            input1=input1.substring(1);
          }
          break;
        case 'B':
          if(input1.charAt(1)=='\''){
            moves.add(-5);
            input1=input1.substring(2);
          } else {
            moves.add(5);
            input1=input1.substring(1);
          }
          break;
        case 'R':
          if(input1.charAt(1)=='\''){
            moves.add(-6);
            input1=input1.substring(2);
          } else {
            moves.add(6);
            input1=input1.substring(1);
          }
          break;
        case 'L':
          if(input1.charAt(1)=='\''){
            moves.add(-7);
            input1=input1.substring(2);
          } else {
            moves.add(7);
            input1=input1.substring(1);
          }
          break;
        default:
          input1=input1.substring(1);
          break;
      }
    }
  }
  String toStrng(){
    String output = "";
    for(int i=0;i<moves.size();i++){
      //println(moves.get(i));
      int move = moves.get(i);
      switch(move){
        case 1:
          output+="(";
          break;
        case -1:
          output=output.substring(0,output.length()-1);
          output+=")";
          break;
        case 2:
          output+="U ";
          break;
        case -2:
          output+="U\' ";
          break;
        case 3:
          output+="D ";
          break;
        case -3:
          output+="D\' ";
          break;
        case 4:
          output+="F ";
          break;
        case -4:
          output+="F\' ";
          break;
        case 5:
          output+="B ";
          break;
        case -5:
          output+="B\' ";
          break;
        case 6:
          output+="R ";
          break;
        case -6:
          output+="R\' ";
          break;
        case 7:
          output+="L ";
          break;
        case -7:
          output+="L\' ";
          break;
        default:
          break;
      }
    }
    return output;
  }
  void revers(){
    //What this algorithm does is pretty simple. It changes the direction by multiplying all of the stored integers by -1, and then reversing their order.
    Integer[] intermediate = new Integer[moves.size()];
    intermediate=moves.toArray(new Integer[0]);
    intermediate=ReverseNegArray(intermediate);
    for(int i=0;i<intermediate.length;i++){
      moves.set(i,intermediate[i]);
    }
  }
}
Integer[] ReverseNegArray(Integer[] x){
  Integer[] y = new Integer[x.length];
  for(int i = 1;i<=x.length;i++){
    println(-x[x.length-i]);
    y[i-1]=-x[x.length-i];
  }
  return y;
}
0 голосов
/ 24 апреля 2020

После того, как я прочитал несколько ответов, я придумал это. Надеюсь, что любой, у кого есть такой же вопрос, может получить положительный отзыв. Спасибо всем, кто пытался мне помочь!

private void reverseAlg(CharSequence text) {
        StringBuilder fullAlg;
        if (!(text.charAt(0) == ' ' || text.charAt(text.length() - 1) == ' ')) {
            fullAlg = new StringBuilder(text + " ");
        } else {
            fullAlg = new StringBuilder(text);
        }
        StringBuilder reversedAlg = new StringBuilder();
        for (int i = 0; i < text.length(); i++) {
            if (fullAlg.charAt(i) != '(' && fullAlg.charAt(i) != ')' && fullAlg.charAt(i) != ' '
                    && fullAlg.charAt(i) != '\'' && fullAlg.charAt(i) != '2') {

                if (fullAlg.charAt(i + 1) == '\'') {

                    if (fullAlg.charAt(i + 2) == ')') {
                        reversedAlg.append(fullAlg.charAt(i)).append(")");
                    } else {
                        reversedAlg.append(fullAlg.charAt(i));
                    }

                } else if (fullAlg.charAt(i + 1) == ' ') {

                    reversedAlg.append("\'").append(fullAlg.charAt(i));

                } else if (fullAlg.charAt(i + 1) == '2') {

                    if (fullAlg.charAt(i + 2) == ')') {
                        reversedAlg.append("2").append(fullAlg.charAt(i)).append(")");
                    } else {
                        reversedAlg.append("2").append(fullAlg.charAt(i));
                    }

                } else if (fullAlg.charAt(i + 1) == ')') {

                    reversedAlg.append("\'").append(fullAlg.charAt(i)).append(")");

                }

            } else if (fullAlg.charAt(i) == ' ' || fullAlg.charAt(i) == '(') {
                reversedAlg.append(fullAlg.charAt(i));
            }
        }

        StringBuilder aux = new StringBuilder(reversedAlg.toString()).reverse();
        for (int i = 0; i < aux.length(); i++) {
            if (aux.charAt(i) == '(') {
                aux.setCharAt(i, ')');
            } else if (aux.charAt(i) == ')') {
                aux.setCharAt(i, '(');
            }
        }
        algTV.setText(aux);
    }
0 голосов
/ 24 апреля 2020

У меня есть частичное решение, которое будет полным, если вы сможете преобразовать свое представление String в объект Algorithm. Это представляет алгоритм кубика Рубика в виде последовательности отдельных ходов и других вложенных алгоритмов, где каждое движение имеет сторону и направление (то есть, независимо от того, инвертировано оно или нет).

import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Deque;

public class Rubiks
{
  public static void main(String[] args)
  {
    // (R U R' U) U' (R U' R')
    Instruction g1 = new Algorithm(Move.fore('R'), Move.fore('U'), Move.back('R'), Move.back('U'));
    Instruction g2 = new Algorithm(Move.fore('R'), Move.back('U'), Move.back('R'));
    Instruction full = new Algorithm(g1, Move.back('U'), g2);
    System.out.println("This algorithm: " + full);
    System.out.println("Inverts to be:  " + full.inverted());
  }
}

class Move implements Instruction
{
  private final char side;
  private final boolean inverse;

  private Move(final char side, final boolean inverse)
  {
    this.side = side;
    this.inverse = inverse;
  }

  public static Move fore(final char side)
  {
    return new Move(side, false);
  }
  public static Move back(final char side)
  {
    return new Move(side, true);
  }

  public Move inverted()
  {
    return new Move(side, !inverse);
  }

  @Override
  public String toString()
  {
    return side + (inverse ? "'" : "");
  }

  @Override
  public String toSubString()
  {
    return toString();
  }
}

class Algorithm implements Instruction
{
  private final Deque<Instruction> moves;

  private Algorithm(Deque<Instruction> moves)
  {
    this.moves = moves;
  }

  public Algorithm(Instruction... moves)
  {
    this.moves = new ArrayDeque<>(Arrays.asList(moves));
  }

  public Algorithm inverted()
  {
    Deque<Instruction> newMoves = new ArrayDeque<>(moves.size());
    for (Instruction instruction : (Iterable<Instruction>) moves::descendingIterator)
    {
      newMoves.add(instruction.inverted());
    }
    return new Algorithm(newMoves);
  }

  @Override
  public String toString()
  {
    StringBuilder sb = new StringBuilder();
    boolean first = true;
    for (Instruction instruction : moves)
    {
      if(! first)
      {
        sb.append(' ');
      }
      first = false;
      sb.append(instruction.toSubString());
    }
    return sb.toString();
  }
}

interface Instruction
{
  /**
   * Returns the inverse of this instruction
   * @return an instruction that undoes this instruction
   */
  Instruction inverted();

  /**
   * Returns the string representation of the instruction, if it were nested in another instruction
   * @return the result of toString, with parentheses if this is a complex instruction
   */
  default String toSubString()
  {
    return "(" + toString() + ")";
  }
}

Я использовал класс Rubiks, чтобы продемонстрировать, что он работает на начальном примере, который вы предоставили. Он выводит следующее:

This algorithm: (R U R' U') U' (R U' R')
Inverts to be:  (R U R') U (U R U' R')

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

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