罗马数字转整数
罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。
字符 | 数值 |
---|---|
I | 1 |
V | 5 |
X | 10 |
L | 50 |
C | 100 |
D | 500 |
M | 1000 |
例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。
通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下三种情况:
- I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
- X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
- C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
给定一个罗马数字,将其转换成整数。输入确保在 1 到 3999 的范围内。
示例 1:输入: “III”;输出: 3
示例 2:输入: “IV”;输出: 4
示例 3:输入: “IX”;输出: 9
示例 4:输入: “LVIII”;输出: 58;解释: L = 50, V= 5, III = 3.
示例 5:输入: “MCMXCIV”;输出: 1994;解释: M = 1000, CM = 900, XC = 90, IV = 4.
从例子上我们不难看出,出去上述六种特殊情况,罗马数字就只是单纯的相加就可以准华为十进制;所以我们只需要将这六种特殊情况单独运算,就可以得到最终值;
int romanToInt(char* s)
{
int sum =0;
while(*s)
{
if(*s =='I')
{
if(*(s+1)=='V')
{
sum +=4;
s+=2;
}
else if(*(s+1)=='X')
{
sum+=9;
s+=2;
}
else
{
sum += 1;
s++;
}
}
else if(*s=='V')
{
sum+=5;
s++;
}
else if(*s=='X')
{
if(*(s+1)=='L')
{
sum+=40;
s+=2;
}
else if(*(s+1)=='C')
{
sum+=90;
s+=2;
}
else
{
sum+=10;
s++;
}
}
else if(*s=='L')
{
sum+=50;
s++;
}
else if(*s=='C')
{
if(*(s+1)=='D')
{
sum+=400;
s+=2;
}
else if(*(s+1)=='M')
{
sum+=900;
s+=2;
}
else
{
sum+=100;
s++;
}
}
else if(*s=='D')
{
sum+=500;
s++;
}
else
{
sum+=1000;
s++;
}
}
return sum;
}
最长公共前缀
编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串 “”。
示例 1:输入: [“flower”,“flow”,“flight”];输出: “fl”
示例 2:输入: [“dog”,“racecar”,“car”];输出: “”
解释: 输入不存在公共前缀。
说明:
所有输入只包含小写字母 a-z 。
这里笔者使用的是纵向扫描法:第一次检测所有字符串的首元素是否相同;相同存进要返回的内从中,然后第二次检测所有字符串的第二个字符,看是否相同,直到出现不同位止,时间复杂度为O(M*N);
char* longestCommonPrefix(char** strs, int strsSize)
{
char* save_same = (char*)malloc(sizeof(char) * 2);
int size = 2;
int i = 0, j = 0;
while (i<size)
{
save_same[i] = 0;
i++;
}
for (j = 0;; j++)
{
if (*(strs[0] + j) != '\0')
{
save_same[j] = *(strs[0] + j);
for (i = 0; i<strsSize; i++)
{
if (*(strs[i] + j) == '\0' || *(strs[i] + j) != save_same[j])
{
save_same[j] = 0;
return save_same;
}
}
realloc(save_same, ++size);
save_same[size - 1] = 0;
}
else
{
return save_same;
}
}
}
二进制求和
给定两个二进制字符串,返回他们的和(用二进制表示)。
输入为非空字符串且只包含数字 1 和 0。
示例 1:输入: a = “11”, b = “1”;输出: “100”
示例 2:输入: a = “1010”, b = “1011”;输出: “10101”
这里笔者使用的是直接运算字符串,如果将字符串先转化成十进制,在字符串很长的情况下就会造成溢出;这里先计算出两个字符串的长度,动态创建一个最长字符串长度+2(’\0’位和预留最高位进位);然后从各自的末尾开始相加,设置一个进位位,一旦两个字符串相同位加起来大于1,就使得进位位加一,然后原位-2;这样就实现了使用十进制数模拟二进制;当一个字符串已经加完时,就将另一个字符串的其余位直接拷贝到返回的result里,最后再判断一下首元素(最高位)是否为0;若为0就直接从第二位返回
char* addBinary(char* a, char* b)
{
int numa = 0, numb = 0;
while (*(a + numa)) { numa++; }
while (*(b + numb)) { numb++; }
int max = 0, i = numa - 1, j = numb - 1, add = 0;
max = numa>numb ? numa : numb;
char* result = (char*)malloc(sizeof(char)*(max + 2));
result[max+1] = '\0';
for (int n = max ; n >= 0; j--, i--, n--)
{
int value = 0;
if (i >= 0 || j >= 0)
{
if (i >= 0 && j >= 0)
{
value = a[i] - '0' + b[j] - '0' + add;
}
else if (i >= 0)
{
value = a[i] - '0' + add;
}
else if (j >= 0)
{
value = b[j] - '0' + add;
}
}
else
{
value = add;
}
if (value >= 2)
{
add = 1;
value -= 2;
}
else
{
add = 0;
}
result[n] = value + '0';
}
if (result[0] - '0' == 0)
{
result++;
}
return result;
}