Roman to Integer

做这道题之前首先要知道罗马数字的规律。

Roman NumeralHindu-Arabic Equivalent
I 1
V 5
X 10
L 50
C 100
D 500
M 1000

There are a few rules for writing numbers with Roman numerals.

1. Repeating a numeral up to three times represents addition of the number. For example, III represents 1 + 1 + 1 = 3. Only I, X, C, and M can be repeated; V, L, and D cannot be, and there is no need to do so.

2. Writing numerals that decrease from left to right represents addition of the numbers. For example, LX represents 50 + 10 = 60 and XVI represents 10 + 5 + 1 = 16.

3. To write a number that otherwise would take repeating of a numeral four or more times, there is a subtraction rule. Writing a smaller numeral to the left of a larger numeral represents subtraction. For example, IV represents 5 - 1 = 4 and IX represents 10 - 1 = 9. To avoid ambiguity, the only pairs of numerals that use this subtraction rule are

Roman NumeralHindu-Arabic Equivalent
IV 4 = 5 - 1
IX 9 = 10 - 1
XL 40 = 50 - 10
XC 90 = 100 - 10
CD 400 = 500 - 100
CM 900 = 1000 - 100

 

 

4. To represent larger numbers, a bar over a numeral means to multiply the number by 1000. For example, $\bar{D}$ represents 1000 x 500 = 500,000 and M bar represents 1000 x 1000 = 1,000,000, one million

Problem 1. Write the following numbers using Roman numerals:

  1. 47 
  2. 123
  3. 1998
  4. 2345

Problem 2. Write the following numbers using Hindu-Arabic numerals:

  1. DCXLVIII
  2. MMDXLIX
  3. MCMXLIV
  4. MCMXCIX

Problem 3. What is the largest number you can write in Roman numerals without using bars?

Problem 4. Perform the following arithmetic operations. Can you do these without converting the numbers to usual notation?

  1. LXVI + XXXIV
  2. CXLVII + MCV
  3. XXXIV × XLV

Solution:

Problem 1.

XLVII; CXXIII; MCMXCVIII; MMCCCXLV

Problem 2. 

规律是,从左往右看,如果数字一直在减小就相加,如果中间某一段数字在增加就做subtraction.

648; 2549; 1944; 1999;

Problem3.

3999 MMMCMXCIX 

Problem4.

The most basic arithmetic in roman numerals is actually pretty easy: addition and subtraction are simple, and it’s obvious why they work. On the other hand, multiplication and division are *not* easy in roman numerals.

### Addition

To add two roman numerals, what you do is:

1. Convert any subtractive prefixes to additive suffixes. So, for example, IX would be rewritten to VIIII.
2. Concatenate the two numbers to add.
3. Sort the letters, large to small.
4. Do internal sums (e.g., replace “IIIII” with “V”)
5. Convert back to subtractive prefixes.

So, for example: 123 + 69. In roman numerals, that’s “CXXIII + “LXIX”.

1. “CXXIII” has no subtractive prefixes. “LXIX” becomes “LXVIIII”.
2. Concatenate: “CXXIIILXVIIII”
3. Sort: “CLXXXVIIIIIII”.
4. Internal sum: reduce the “IIIIIII” to “VII” giving “CLXXXVVII”; then reduce the “VV” to “X”: “CLXXXXII”
5. Switch to subtractive prefix: “XXXX” = “XL”, giving “CLXLII”. “LXL”=”XC”, giving “CXCII”, or 192.

### Subtraction

Subtraction isn’t any harder than addition. To subtract A-B:

1. Convert subtractive prefixes to additive suffixes.
2. Eliminate any common symbols that appear in both A and B.
3. For the largest remaining symbol in B, take the first symbol in A larger than it, and expand it. Then go back to step two, until there’s nothing left.
4. Convert back to subtractive prefixes.

So 192-69 = “CXCII-LXIX”.

1. Remove prefixes: CLXXXXII – LXVIIII.
2. Remove common symbols. CXXX – VII.
3. Expand an “X” in “CXXX”: CXXVIIIII – VII.
4. Remove common symbols: CXXIII = 123.

### Multiplication

Multiplication using roman numerals is not particularly easy or obvious. You can do the trivial thing, which is repeated addition. But it should be pretty obvious that that’s not practical for large numbers. The trick that they used was actually pretty nifty. It’s basically a strange version of binary multiplication. You need to be able to add and divide by two, but those are both pretty easy things to do. So here goes:

Given A×B, you create two columns, and write A in the left column, and B in the right. Then:

1. Divide the number in the left column by two, discarding the remainder. Write it down in the next row of the left column.
2. Multiply the number in the right column by two. Write it down in the right column next the the result from step 1.
3. Repeat from step 1 until the value in the left column is 1.
4. Go down the table, and cross out every row where the number in the left column is *even*.
5. Add up the remaining values in the right column.

Let’s look at an example: 21 * 17; XXI * XVII in roman numerals

We build the table:

Left Right
XXI(21) XVII (17)
X(10) XXXIV (34)
V(5) LXVIII (68)
II(2) CXXXVI (136)
I(1) CCLXXII (272)

Then strike out the rows where the left hand side are even:

Left Right
XXI(21) XVII (17)
V(5) LXVIII (68)
I(1) CCLXXII (272)

Now add the right hand column:

XVII + LXVIII + CCLXXII = CCLLXXXXVVIIIIIII = CCCXXXXXVII = CCCLVII = 357

Why does it work? It’s binary arithmetic. In binary arithmetic, to multiply A by B, you start with 0 for the result, nad then for each digit dn of A, if dn=1, then add *B* with n 0s appended to the result.

The divide-by-two is giving you the binary digit of A for each position: if it’s odd, then the digit there was 1, if it’s even, the digit in that position was 0. The *multiply by 2* on the right is giving you the results of appending the zeros in binary – for the Nth digit, you’ve multiplied by two *n* times.

### Division in Roman Numerals

Division is the biggest problem in roman numerals. There is no good trick that works in general. It really comes down to repeated subtraction. The only thing you can do to simplify is variations on finding a common factor of both numbers that’s easy to factor out. For example, if both numbers are even, you can divide each of them by two before starting the repeated subtraction. It’s also fairly easy to recognize when both numbers are multiples of 5 or 10, and to do the division by 5 or 10 on both numbers. But beyond that, you take a guess, do the multiplication, subtract, repeat.

验证:https://www.rapidtables.com/convert/number/roman-numerals-converter.html

答案是:C; MCCLII; 啊乘法看起来太麻烦了不想做。

 

回到题目。

Given a roman numeral, convert it to an integer.

Input is guaranteed to be within the range from 1 to 3999.

我写的解答。打败了71.88%的人。用到的switch是我以前没接触过的。主要思想就是go though a string 如果后一位比前一位大的话就减去这个前一位。

这样循环后最后一位肯定是没有被加上的,于是我在循环结束后又提取了最后一位加到sum里去。

class Solution {
public:
    int roman(char c){ //helper function we use which could transfer the input character to number
      switch(c){
        case 'I':
            return 1;
        case 'V':
            return 5;
        case 'X':
            return 10;
        case 'L':
            return 50;
        case 'C':
            return 100;
        case 'D':
            return 500;
        case 'M':
            return 1000;
        default:
            return 0;
      }
    }
    
    int romanToInt(string s) {
        int sum=0;
        int curr,next;
        for(int i=0; i<s.length()-1;i++){
            curr = roman(s[i]);
            next = roman(s[i+1]);
            if(curr<next)
                sum-=curr;
            else
                sum+=curr;
        }
        int last=roman(s[s.length()-1]);
        return sum+last;
    }
};

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

啊~~就是因为我太穷了所以才买不起想买的过膝靴、化妆品、护肤品,吃不起好吃的东西,不能去想去的地方玩

就是因为太穷了所以喜欢猫猫狗狗也没法养,每天想着在饭店里点一个菜是吃两顿还是再挤一挤吃三顿。

靠别人是不可能的,这辈子都没可能的。到最后也不会有人来为我买单的。你心心念念的那些人其实只活在梦里,他们都不会出现的。

不好好写代码的话以后工作也找不到,然后就越来越穷。想想就好难过好委屈。

啊~又想起高中的时候一起吃饭的朋友们总爱出去吃,她们随随便便点的就是十块左右的大排面还要加鸡蛋,而我想了又想还是只舍得点一碗榨菜面的时候了。

好穷啊。为了省一块钱的车费愿意走一小时。好穷啊。向爸爸要钱怎么说他也不给。好穷啊。喜欢的东西看了又看从来没舍得买过。好穷啊。真的好穷啊。

可是以前那么穷那么委屈,我还愿意攒好久的饭钱给同学买一个生日礼物,没有用的音乐盒,是白色钢琴的形状,要86元,好好包装一下用礼物盒装起来,是95元。喜欢的明星的CD,别致地包装好,周围洒满亮晶晶地糖果,装在礼品盒子里,是80多。csj说骑车冷,第二天我就能送她手套。现在呢,只有越来越势利,越来越小气。越来越小气……好没有用啊,自己做不到的事情,就会怪别人。真没用啊。

posted @ 2018-04-16 03:15  吹离了空白  阅读(176)  评论(0)    收藏  举报