Проблема стека вызова функции в коде, переведенном с Java на R - PullRequest
0 голосов
/ 26 сентября 2018

Я перевел Java-код на R. Мне нужно проверить, все ли строки переведены правильно.

Некоторая часть, скорее всего, верна, потому что я запустил ее и R говорит:

Ошибка: использование стека C 7970192 слишком близко к пределу.

Я не уверен, какая часть пошла не так, потому что, когда я компилирую ее, она не выдает никакой ошибки для всех строк, кроме случаев, когда я пытаюсь ее запустить

Исходный код Java:

  public static void printQueens(int[] q) {
      int n = q.length;
      for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
          if (q[i] == j) StdOut.print("Q ");
          else           StdOut.print("* ");
        }
        StdOut.println();
      }  
      StdOut.println();
    }


  /***************************************************************************/

    public static void enumerate(int n) {
      int[] a = new int[n];
      enumerate(a, 0);
    }

  public static void enumerate(int[] q, int k) {
    int n = q.length;
    if (k == n) printQueens(q);
    else {
      for (int i = 0; i < n; i++) {
        q[k] = i;
        if (isConsistent(q, k)) enumerate(q, k+1);
      }
    }
  }  


  public static void main(String[] args) {
    int n = Integer.parseInt(args[0]);
    enumerate(n);
  }

}

Код R, подлежащий исправлению

# Prints n-by-n placement of queens from permutation q
printQueens <- function(q) {
  n = q.length
  for(i in seq_len(n)) {
    for(j in seq_len(n)) {
      if(q[i] == j) print("Q ")
      else{          print("* ")}
    }
    sep="/n"
  }  
  sep="/n"
}

#Try all permutations using backtracking

enumerate <- function(q, k) {
   n = q.length;
   if(k == n) print(Queens(q))
  else {
    for(i in seq_len(n)) {
      q[k] = i
      if (isConsistent(q, k)) enumerate(q, k+1)
    }
  }
}  

enumerate <- function(n) {
  a = n
  enumerate(a);
}

main <- function(args) {
  n =args[0];
  enumerate(n);
}

1 Ответ

0 голосов
/ 29 сентября 2018

Указанная вами ошибка (использование стека) означает, что ваш код либо неправильно переведен (произошла очень глубокая рекурсия и исчерпан вызов стека функций), либо вы пытаетесь решить очень высокую проблему N-queen (N> 30).

Существует множество проблем с прямым переводом вашего кода из Java в R:

  1. Массивы в Java индексируются из 0, в R - из 1.И вам придется переопределить индексную функцию [] в R.
  2. For-loop, однако аналогичные имеют различную семантику в R. Она имеет больше похожую функциональность foreach.Для моделирования Java for -loop в R необходимо использовать конструкцию while.
  3. Представленный исходный код не полный (функция isConsistent отсутствует).

Пожалуйста, смотрите код, который решает все проблемы, описанные выше:

StdOut.print <- cat
StdOut.println <- function(x) cat("\n")
index1 <- .Primitive('[')
`[.zero-based_vector` <- function(v, i) index1(as.vector(v), i+1)

isConsistent <- function(q, n) {
  i <- 0
  while(i < n) {
    if (q[i] == q[n])           
      return(FALSE)   # same column
    if ((q[i] - q[n]) == (n - i)) 
      return(FALSE)   # same major diagonal
    if ((q[n] - q[i]) == (n - i)) 
      return(FALSE)   # same minor diagonal

    i <- i + 1
  }
  return(TRUE)
}

printQueens <- function(q) {
  n <- length(q)
  for (i in seq.int(n) - 1) {
    for (j in seq.int(n) - 1) {
      if (q[i] == j) 
        StdOut.print("Q ")
      else
        StdOut.print("* ")
    }
    StdOut.println()
  }  
  StdOut.println()
}

enumerate_n <- function(n) {
  a <- integer(n)
  class(a) <- c("zero-based_vector", class(a))

    enumerate_qk(a, 0)
}

enumerate_qk <- function(q, k) {
  n <- length(q)
  if (k == n) {
    printQueens(q)
  } else {
    i <- 0
    while(i < n) {
      q[k + 1] <- i
      if (isConsistent(q, k)) {
        enumerate_qk(q, k + 1)
      }

      i <- i + 1
    }
  }
}  

main <- function(args) {
  n <- as.integer(args[1])
  enumerate_n(n)
}

main(4)

Вывод:

* Q * * 
* * * Q 
Q * * * 
* * Q * 

* * Q * 
Q * * * 
* * * Q 
* Q * * 

Для справки: Полный исходный код опубликован на Queens.java

...