博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Leetcode——Integer to Roman(这不仅仅是一道题,更多是关于指针和地址的运用以及动态存储空间的申请,绝对值得借鉴一下)
阅读量:2338 次
发布时间:2019-05-10

本文共 6795 字,大约阅读时间需要 22 分钟。

题目简介

Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M.

罗马数字是用七个不同的标志表示:I, V, X, L, C, D 和M.

Symbol       ValueI             1V             5X             10L             50C             100D             500M             1000

For example, two is written as II in Roman numeral, just two one’s added together. Twelve is written as, XII, which is simply X + II. The number twenty seven is written as XXVII, which is XX + V + II.

例如:2在罗马数字中使用II表示,仅仅是两个1相加。12写作XII,仅仅是X和II相加。27写作XXVII,就是XX+V+II

Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not IIII. Instead, the number four is written as IV. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as IX. There are six instances where subtraction is used:

罗马数字常常是由左到右,按照最大到最小的方式去写的。然而,数字4并不是IIII。而是,数字4写为IV。因为1在左边表示减去1,5减1,就是4.同样的原则也适用于9,写作IX。下面有六个使用减法的例子。

* I can be placed before V (5) and X (10) to make 4 and 9. * X can be placed before L (50) and C (100) to make 40 and 90. * C can be placed before D (500) and M (1000) to make 400 and 900.

Given an integer, convert it to a roman numeral. Input is guaranteed to be within the range from 1 to 3999.

给于一个整数将之转化为罗马数字。输入的数字要确保是在1到3999之内的

Example 1:

Input: 3Output: "III"

Example 2:

Input: 4Output: "IV"

Example 3:

Input: 9Output: "IX"

Example 4:

Input: 58Output: "LVIII"

Explanation: L = 50, V = 5, III = 3.

Example 5:

Input: 1994Output: "MCMXCIV"

Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.

思路分析

  • 按照由简入繁的思路进行思考和分析
    • 假设没有减法,从尾部到头部遍历各个位上的数字,用对应的字母进行拼接。
    • 有减法:在遍历每个位数字的同时,留意是否为特殊的数字,如果是特殊的数字就用特定的字符代替,特殊字符分别为4、9.

代码实现

#include 
#include
#include
char *intToRoman(int num);int main(){
//今日份leetcode printf("%s\n",intToRoman(3)); return 0;}/* 功能描述:实现整型数字到罗马数字的转变*/char *intToRoman(int num){
//获取个位的数字,同时将原来的数字右移一位 int a = num % 10; num = num / 10; //用1和5构成原来的数字 int five = a / 5; int one = a % 5; char result1[9] = ""; if(a == 9) {
strcat(result1,"IX"); } else if(a ==4) {
strcat(result1,"IV"); } else {
if(five) {
strcat(result1,"V"); } while(one) {
strcat(result1,"I"); one --; } } //对十位进行操作 a = num % 10; num = num / 10; int five2 = a / 5; int one2 = a % 5; char result2[9] = ""; if(a == 9) {
strcat(result2,"XC"); } else if(a ==4) {
strcat(result2,"XL"); } else {
if(five2) {
strcat(result2,"X"); } while(one2) {
strcat(result2,"L"); one2 --; } } //对百位进行操作 a = num % 10; num = num / 10; int five3 = a / 5; int one3 = a % 5; char result3[9] = ""; if(a == 9) {
strcat(result3,"CM"); } else if(a ==4) {
strcat(result3,"CD"); } else {
if(five3) {
strcat(result3,"C"); } while(one3) {
strcat(result3,"D"); one3 --; } } //对千位进行操作 a = num % 10; num = num / 10; int five4 = a / 5; int one4 = a % 5; char result4[9] = ""; if(five4) {
strcat(result4,""); } while(one4) {
strcat(result4,"M"); one4 --; } //进行拼接 char *result = NULL; result = (char *)malloc(40 * sizeof(char)); *result = ""; strcat(result,result4); strcat(result,result3); strcat(result,result2); strcat(result,result1); return result;}

改良和优化——同样步骤的代码进行提取,简化代码

/*    功能描述:将传入的数字组合成特定的字符    参数列表:a,是经过处理的每一个位的数字              x,y,x是对应的需要改变的数字    返回值:经过转换的拼装之后的字符组合*/char *handleNum(int a,char *x,char *y,char *z){
int five = a / 5; int one = a % 5; char *result1 = NULL; result1 = (char *)malloc(9 * sizeof(char)); if(!result1) {
printf("申请失败"); return NULL; } memset(result1,0,9 * sizeof(char)); if(a == 9) {
strcat(result1,x); strcat(result1,z); } else if(a ==4) {
strcat(result1,x); strcat(result1,y); } else {
if(five) {
strcat(result1,y); } while(one) {
strcat(result1,x); one --; } } return result1;}/* 功能描述:实现整型数字到罗马数字的转变*/char *intToRoman(int num){
//获取个位的数字,同时将原来的数字右移一位 int a = num % 10; num = num / 10; //用1和5构成原来的数字 char *result1 = NULL; result1 = handleNum(a,"I","V","X"); // printf("第一次:%s \n",result1); //对十位进行操作 a = num % 10; num = num / 10; char *result2 = NULL; result2 = handleNum(a,"X","L","C"); // printf("第二次:%s \n",result2); //对百位进行操作 a = num % 10; num = num / 10; char *result3 = NULL; result3 = handleNum(a,"C","D","M"); //printf("第三次:%s \n",result3); //对千位进行操作 a = num % 10; num = num / 10; char *result4 = NULL; result4 = handleNum(a,"M","",""); // printf("第四次:%s \n",result4); char *result = NULL; result = (char *)malloc(40 * sizeof(char)); if(!result) {
printf("申请内存失败"); return NULL; } memset(result,0,40 * sizeof(char)); strcat(result,result4); strcat(result,result3); strcat(result,result2); strcat(result,result1); return result;}

在这里插入图片描述

分析总结

  • 如果使用字符数组实现字符串,一定记得要初始化。否则字符串数组内会随机存储不同的乱码。
  • 在函数中的申请的字符串数组在函数调用的时候会由系统自动申请内存进行分配,但是函数结束之后,系统的会自动回收分配的内存,函数之内所有申请的变量都会自动回收,而指向这些内存的指针就会变成空指针。
int main(){
char *s = NULL; printf("%s \n",convert(s)); return 0;}void convert(char *p){
char t[] = "asdfgh"; p = t;}

在这里插入图片描述

  • 申请内存的时候先判定是否申请到了,再去将申请到的内存初始化,在使用。
char *result1 = NULL;    result1 = (char *)malloc(9 * sizeof(char));    if(!result1)    {
printf("申请失败"); return NULL; } memset(result1,0,9 * sizeof(char));
  • 使用字符串拼接函数,不能出现下面的傻逼错误。兄弟,没有多余的内存,你怎么可以这样的,字符串常量又是存储在静态存储区的,这不是为难计算机吗?
char *x = "x";char *y = "y";strcat(x,y);

借鉴和学习

基本思路
  • 将所有可能的组合都列出来:1,4,5,9,10,40,50,90,100,400,500,900,1000
  • 从大到小逐个相减,如果结果为正数,那就增加对应数字的组合;如果结果为负数,那就下一个数值,直到最后的结果为零
  • 返回最后的字符串
代码实现
/*    功能描述:采用减法的形式去形成对应的字符序列*/char *intToRoman(int num){
char *symbol[13] = {
"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"}; int value[13] = {
1000,900,500,400,100,90,50,40,10,9,5,4,1}; char *result = NULL; result = (char *)malloc(40*sizeof(char)); if(!result) {
printf("申请空间失败!"); return NULL; } memset(result,0,40*sizeof(char)); for(int i = 0;i < 13;i ++) {
while(num - value[i] >= 0) {
strcat(result,symbol[i]); num -= value[i]; } } return result;}
效果

在这里插入图片描述

总结
  • 简洁的代码反而换了更慢的速度,感觉是因为循环结构远远的慢于选择结构。

转载地址:http://aggpb.baihongyu.com/

你可能感兴趣的文章
整合Struts和Spring
查看>>
Hibernate和Spring的整合
查看>>
我的校招——同花顺
查看>>
Ego Surfing = Ego + Surfing
查看>>
13日cnblog会谈摘要
查看>>
尝试解决MT的Add to My Yahoo!的字符集问题
查看>>
MoreGoogle提供的网页缩略图服务
查看>>
每天到REFERER到我的网站上来的主页上去溜达一下
查看>>
北京羽毛球场地预定电话
查看>>
本周CNBlog例会:Grassland搜索的后台迁移
查看>>
Flickr的网络收藏夹服务
查看>>
BLOG="Better Listings On Google" ? Google BlogSearch上的 BSP索引收录量比较
查看>>
用sed批量替换文件中的字符
查看>>
九型性格心理测试 (From Ulla Zang荣格的个人性格测验题目)
查看>>
MT模板修改2则: 评论分段和firefox的缺省字体适应
查看>>
[MT] 3.32升级备忘
查看>>
MT 3.33发布: 安全漏洞修正
查看>>
给Blog加上雅虎通PingMe服务:和网站用户即时聊天
查看>>
顶级域名注册分布统计:2006年09月 .com .de .net .uk .cn
查看>>
雅虎通可以批量添加MSN用户了
查看>>