0

I would like some help with this please, and if you guys come up with some fancy out of my league way of doing it, just explain it.

Im sure with a huge IF or a SWITCH I could do this, but there has to be a more optimized way. I was thinking assigning values and then making an algorithm to check for ALL cases.

Or possible just comparing the first element to the element after it, then subtract if the first is less than the second, and otherwise add.

I do plan on using arrays

For your reference.

M 1000

D 500

C 100

L 50

X 10

V 5

I 1

  • This problem would best be solved, IMHO, with [`LinkedHashMap`s](http://docs.oracle.com/javase/7/docs/api/java/util/LinkedHashMap.html). A couple of the answers to [this StackOverflow question](http://stackoverflow.com/questions/12967896/converting-integers-to-roman-numerals-java) use it well. – Ray Toal Feb 13 '14 at 02:42
  • Refer to this link : http://rosettacode.org/wiki/Roman_numerals/Decode#Java – Aditya Peshave Feb 13 '14 at 02:48
  • Doesn't the order of characters in the number string make a difference (i.e. IV and VI aren't the same). You could make a class that represents the idea of a number, instantiate them with each value as you look at the input string, and a method that allows it to compare itself to the characters next door. I'm talking about the interpreter pattern http://en.wikipedia.org/wiki/Interpreter_pattern – nexus_2006 Feb 13 '14 at 03:00

2 Answers2

0

Using a map, store all possible values and then look them up:

Map lookup = new LinkedHashMap<Integer, String>();

lookup.put(10, "X");
lookup.put(11, "XI);
// and so on

Integer year = lookup.get("MMXIV");
System.out.println(year); //prints 2014

You could put all values in a file and parse it to populate your map.

zmf
  • 9,095
  • 2
  • 26
  • 28
  • Could you explain more, Ive never used this before. I kinda get what you mean but no idea how to implement it – user2963396 Feb 13 '14 at 03:39
  • If you could reference the API for this Map thing would be awesome. Also, how can i use this to check is the numeral is valid? for instance you can only have 3 consecutive numerals of the same value, and cant have something like VX – user2963396 Feb 13 '14 at 04:04
  • [LinkedHashMap](http://docs.oracle.com/javase/7/docs/api/java/util/LinkedHashMap.html) is part of the Java collections framework. If you only put valid entries into the map (such as real years) you can assume that if the map doesn't contain a record, the input is invalid. (lookup.get("VX") == null;). – zmf Feb 13 '14 at 04:17
0

const map = {
  I: 1,
  V: 5,
  X: 10,
  L: 50,
  C: 100,
  D: 500,
  M: 1000,
};
function isValidRoman(roman) {
  const length = roman.length;
  let exceptions = 0;
  let min = map[roman[0]];
  for (let i = 1; i < length; i++) {
    const value = map[roman[i]];
    if (value > min) {
      const isExceptionValid = checkIsExceptionValid(value, min);
      if (!isExceptionValid) return false;
      else {
        exceptions++;
        if (exceptions === 2) return false;
      }
    }
  }
  return true;
}
function checkIsExceptionValid(value, min) {
  if (min === 1) return [5, 10].includes(value);
  else if (min === 10) return [50, 100].includes(value);
  else if (min === 100) return [500, 1000].includes(value);
  return false;
}

const testCases = [
  "IXC",
  "CDM",
  "IXV",
  "I",
  "X",
  "L",
  "MMDCL",
  "IL",
  "XM",
  "VX",
  "MCMLXXXVII",
];
const expected = [
  false,
  false,
  false,
  true,
  true,
  true,
  true,
  false,
  false,
  false,
  true,
];

testCases.forEach((testcase, index) => {
  console.log(
    "result for testcase = ",
    testcase,
    " = ",
    isValidRoman(testcase),
    ",expected = ",
    expected[index]
  );
});
Gaurav Sobti
  • 569
  • 1
  • 4
  • 14