Рекурсивное целое число в римскую цифру Funciton сходит с ума в конце - PullRequest
0 голосов
/ 10 июля 2020

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

возвращаемое значение в конце идет от

MMCCCXXVIII -
MMCCCXXVII -
MMCCCXXVI -
MMCCCXXV -
MMCCCXX -
MMCCCX -
MMCCC -
MMCC- 
MM-
M

function romanToInt(int, rom = '') {
    function binarySearch(arr, q, rom, le, ri) {
        // set left right middle
        let l = le || 0,
            r = ri || arr.length - 1,
            m = Math.floor((r + l) / 2);

        // check if the middle is q
        if (arr[m] === q) {
            return m;
        }

        if (arr[l] === q) {
            return l;
        }

        if (arr[r] === q) {
            return r;
        }

        if (q > arr[m] && m + 1 < r) {
            return binarySearch(arr, q, rom, m, ri);
        }

        if (q < arr[m] && m - 1 > l) {
            return binarySearch(arr, q, rom, le, m);
        }
        let numToUse = '0';
        let lTemp = 500000000000000000000000000000,
            rTemp = 500000000000000000000000000000,
            mTemp = 500000000000000000000000000000;

        if (arr[l] - q < 0) {
            lTemp = Math.abs(arr[l] - q);
        }
        if (arr[m] - q < 0) {
            mTemp = Math.abs(arr[m] - q);
        }
        if (arr[r] - q < 0) {
            rTemp = Math.abs(arr[r] - q);
        }

        let tempToFind = Math.min(lTemp, mTemp, rTemp);
        if (lTemp === tempToFind) {
            return l;
        }
        if (rTemp === tempToFind) {
            return r;
        }
        if (mTemp === tempToFind) {
            return m;
        }
        return `pending`;
    }
    let convArr = [
            [1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000],
            ['I', 'IV', 'V', 'IX', 'X', 'XL', 'L', 'XC', 'C', 'CD', 'D', 'CM', 'M'],
        ],
        romanNumeral = rom;
    let returnedVal = binarySearch(convArr[0], int);
    romanNumeral = romanNumeral + convArr[1][returnedVal];

    let newQ = int - convArr[0][returnedVal];
    if (newQ === 0) {
        return romanNumeral;
    } else {
        romanToInt(newQ, romanNumeral);
    }

    return romanNumeral;
}

const rom = 2328;
console.log(romanToInt(rom));

Ответы [ 2 ]

1 голос
/ 10 июля 2020

Не уверен в бинарном поиске. Это немного другой рекурсивный подход.

const numberToRoman = (num, rom = "") => {
  if (num === 0) return rom;
  for (var i = convArr[0].length - 1; i >= 0; i--) {
    if (num >= convArr[0][i]) {
      return numberToRoman(num - convArr[0][i], rom + convArr[1][i]);
    }
  }
};

const convArr = [
  [1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000],
  ['I', 'IV', 'V', 'IX', 'X', 'XL', 'L', 'XC', 'C', 'CD', 'D', 'CM', 'M'],
];

const someNumber = 2328;
console.log(numberToRoman(someNumber));
1 голос
/ 10 июля 2020

Вы забыли return рекурсивное возвращаемое значение.

if (newQ === 0) {
    return romanNumeral;
} else {
    romanToInt(newQ, romanNumeral);
}

return romanNumeral;

Должно быть:

if (newQ === 0) {
    return romanNumeral;
} else {
    return romanToInt(newQ, romanNumeral); // <- return the recursive result
}

// or use a guard clause
if (newQ === 0) return romanNumeral;
return romanToInt(newQ, romanNumeral)

function romanToInt(int, rom = '') {
    function binarySearch(arr, q, rom, le, ri) {
        // set left right middle
        let l = le || 0,
            r = ri || arr.length - 1,
            m = Math.floor((r + l) / 2);

        // check if the middle is q
        if (arr[m] === q) {
            return m;
        }

        if (arr[l] === q) {
            return l;
        }

        if (arr[r] === q) {
            return r;
        }

        if (q > arr[m] && m + 1 < r) {
            return binarySearch(arr, q, rom, m, ri);
        }

        if (q < arr[m] && m - 1 > l) {
            return binarySearch(arr, q, rom, le, m);
        }
        let numToUse = '0';
        let lTemp = 500000000000000000000000000000,
            rTemp = 500000000000000000000000000000,
            mTemp = 500000000000000000000000000000;

        if (arr[l] - q < 0) {
            lTemp = Math.abs(arr[l] - q);
        }
        if (arr[m] - q < 0) {
            mTemp = Math.abs(arr[m] - q);
        }
        if (arr[r] - q < 0) {
            rTemp = Math.abs(arr[r] - q);
        }

        let tempToFind = Math.min(lTemp, mTemp, rTemp);
        if (lTemp === tempToFind) {
            return l;
        }
        if (rTemp === tempToFind) {
            return r;
        }
        if (mTemp === tempToFind) {
            return m;
        }
        return `pending`;
    }
    let convArr = [
            [1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000],
            ['I', 'IV', 'V', 'IX', 'X', 'XL', 'L', 'XC', 'C', 'CD', 'D', 'CM', 'M'],
        ],
        romanNumeral = rom;
    let returnedVal = binarySearch(convArr[0], int);
    romanNumeral = romanNumeral + convArr[1][returnedVal];

    let newQ = int - convArr[0][returnedVal];
    
    if (newQ === 0) {
        return romanNumeral;
    } else {
        return romanToInt(newQ, romanNumeral); // <- return the recursive result
    }
}

const rom = 2328;
console.log(romanToInt(rom));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...