Попытка решить зигзагообразный паттерн для алгоритма - PullRequest
0 голосов
/ 02 апреля 2020

Вопрос заключается в следующем:

Строка "PAYPALISHIRING" написана зигзагообразным шаблоном на заданном количестве строк, например: (вы можете захотеть отобразить этот шаблон фиксированным шрифтом для лучшей читаемости )

P   A   H   N
A P L S I I G
Y   I   R

И затем читать построчно: "PAHNAPLSIIGYIR"

Напишите код, который будет принимать строку, и выполните это преобразование с учетом числа строк:

преобразование строки (строка s, int numRows); Пример 1:

Вход: s = "PAYPALISHIRING", numRows = 3 Выход: "PAHNAPLSIIGYIR" Пример 2:

Вход: s = "PAYPALISHIRING", numRows = 4 Выход: "PINALSIGYAHRPI" Объяснение:

P     I    N
A   L S  I G
Y A   H R
P     I

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

const convert = (s, numRows) => {
    let startRow = 0
    let endRow = numRows - 1
    let startColumn = 0
    let endColumn = Math.floor((s.length / 2) - 1)
    s = s.split('')
    let results = []
    // to setup the columns

    for (let i = 0; i < numRows; i++) {
        results.push([])
    }

    while (startRow <= endRow && startColumn <= endColumn && s.length) {
        for (let i = startRow; i <= endRow; i++) {
            results[i][startColumn] = s.shift()
        }
        for (let i = endRow - 1; i >= startRow; i--) {
            results[i][startColumn + 1] = s.shift()
            startColumn++
        }
        //this line seems to be the issue
        startRow++
    }
    return results
}

console.log(convert('PAYPALISHIRING', 4))

Ответы [ 2 ]

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

Мой предварительный расчет немного ржавый, но логика c, стоящая за этой проблемой, выглядит как синусоида. Я где-то допустил математическую ошибку при создании уравнения sin, которое мешает этому работать (r никогда не равно c с текущими параметрами), но, надеюсь, это поможет, если вы выберете направление go in.

/*If x-axis is position in string, and y-axis is row number...
n=number of rows

Equation for a sin curve: y = A sin(B(x + C)) + D
D=vertical shift (y value of mid point)
D=median of 1 and n
n:  median:
1   1
2   1.5
3   2
4   2.5
5   3
6   3.5
7   4
median=(n+1)/2
D=(n+1)/2

A=amplitude (from the mid-point, how high does the curve go)
median + amplitude = number of rows
amplitude = number of rows - median
A=n-D

C=phase shift
Phase shift for a sin curve starting at its lowest point: 3π/2
(so at time 1, row number is 1, and curve goes up from there)
C=3π/2


Period is 2π/B
n   p
3   4
4   6
5   8
6   10
period=2(n-1)
2(n-1)=2π/B
B(2(n-1)=2π
B=2π/2(n-1)
B=π/(n-1)

Variables:
s = string
n = number of rows
c = current row number being evaluated
p = position in string
r = row number

*/
var output='';
function convert(s,n) {
    D=(n+1)/2
    A=n-D
    C=(3*Math.PI)/2
    B=Math.PI/(n-1)
  for (c=1;c<=n;c++) { //loop from 1st row to number of rows
    for (p=1;p<=s.length;p++) { //loop from 1st to last character in string
    r=A*Math.sin(B*(p+C))+D //calculate the row this character belongs in
        if (r==c) { output+= s.charAt(r) } //if the character belongs in this row, add it to the output variable. (minus one because character number 1 is at position 0)
}}
//do something with output here
}
0 голосов
/ 02 апреля 2020

Я переписал ваше время l oop следующим образом, где я просто выгуливаю "зигзагообразный" паттерн! Надеюсь, это достаточно просто понять.

let c=0, row=0,col=0, down=0;
while(c<s.length) {
    results[row][col]=s[c];
    if(down==0) { // moving down 
        row++;
        if(row==numRows) {
            down = 1;
            col++;
            row-=2;
        }
    } else { // moving up
        row--;
        col++;
        if(row==0) {
            down=0;
        }
    }
    c++;
}

Ps. Выше код не обрабатывает numRows < 3, поэтому вы должны управлять ими до этого l oop.

...