• (字符串,哈希) leetcode 8. atoi,12. Integer to Roman


    思路:判断各种边界条件。

    1)首先过滤字符串前面的空格,即找到第一个不为空格的字符;
    2)如果第一个字符是+或-,设置flag值;
    3)接下来的字符如果在'0' - '9' 范围内,则转换为数字,否则结束循环; 注意上一步中,如果结果已经大于INT_MAX或小于INT_MIN,则直接返回INT_MAX或INT_MIN;
    4)如果过滤掉空格后的字符不是一个有效的整数字符,则返回0;
    5)整数之后可能有多余的其他字符,可以忽略不计。
    class Solution {
    public:
        int myAtoi(string str) {
            int s = str.size();
            if(s==0)
                return 0;
            int i=0, flag=1, cur;   //用i遍历,flag存储正负号
            long ans = 0;    //计算数字的值,因为可能超出int边界,故定义为long
            while(i<s && str[i] == ' ')
                //过滤前面的空格
                i++;
            
            if(str[i]=='-' || str[i] == '+'){
                //处理 + 和 -
                if(str[i] == '-')
                    flag = -1;
                i++;
            }
            
            while(i<s && str[i]>='0' && str[i]<='9'){
                cur = str[i] - '0';
                ans = ans*10 + cur;
                if(ans * flag < INT_MIN)
                    return INT_MIN;
                if(ans * flag > INT_MAX)
                    return INT_MAX;
                i++;
            }
            return ans*flag;
        }
    };

     

    题意是将数字转化为罗马数字。因为通常情况下,罗马数字中小的数字在大的数字的右边。所以用贪心来做,将输入的数字num 与1000比较大小,若比1000大,则将M放入str中,再将num-1000的数值再与900比较,以此类推....

    但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX;所以,4,9,40,90,400,900也需要放到哈希表中。

    注意输入数字大小在1-3999之间。

    class Solution {
    public:
        string intToRoman(int num) {
            vector<int> value = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5,4,1};
            vector<string> roman = {"M", "CM", "D","CD","C","XC","L","XL","X","IX","V","IV",
    "I"};
            string str;
            int i = 0;
            while(num>0 && i<value.size()){
                if(num >= value[i]){
                    str += roman[i];
                    num -= value[i];
                }
                else
                    i++;
            }
            return str;
        }
    };

     

    class Solution {
    public:
        int romanToInt(string s) {
            unordered_map<string, int> mp = {{"I",1}, {"IV", 4}, {"V", 5}, {"IX", 9}, {"X", 10}, {"XL", 40}, {"L", 50}, {"XC", 90}, {"C", 100}, {"CD", 400}, {"D", 500}, {"CM", 900}, {"M", 1000}};
            int r = 0, i = 0;
            while(i<s.size()){
                string two = s.substr(i, 2);
                string one = s.substr(i, 1);
                if(mp[two]){
                    r += mp[two];
                    i+=2;
                }
                else if(mp[one]){
                    r += mp[one];
                    i++;
                } 
            }
            return r;
        }
    };
    class Solution {
    public:
        int romanToInt(string s) {
            unordered_map<string, int> mp = {{"I",1}, {"V", 5},  {"X", 10}, {"L", 50},  {"C", 100}, {"D", 500}, {"M", 1000}};
            int r = mp[s.substr(0,1)];
            
            for(int i=1; i<s.size(); ++i){
                if( mp[s.substr(i-1,1)] < mp[s.substr(i,1)] )
                    // 类似"IV"的情况, 因为r多加了一个mp[s.substr(i-1,1)],所以要减去
                    r += mp[s.substr(i,1)] - 2 * mp[s.substr(i-1,1)];
                else
                   r += mp[s.substr(i,1)];
            }
            return r;
        }
    };

    思路:

    注意:res[high] += ans/10; 高位需要加上自身。对于string类型字符串,假如是 str1 = "abcdef", str1[0]为a,而str1[str1.size()-1]为f ;但是对于 vector和数组,若res = {0,1,2,3,4,5}, 则 res[0] 为5,res[res.size()-1] 为0,所以对于这个两重循环,从两个字符串的末尾开始遍历,存储到vector类型的res的高位,所以再排除开头的0时,需要直接从res的索引为0开始,往字符串r中添加。

    class Solution {
    public:
        string multiply(string num1, string num2) {
            if(num1.size()==0 || num2.size()==0)
                return "0";
            int s1 = num1.size(), s2 = num2.size();
            vector<int> res(s1+s2, 0);
            string r="";
            int low=0, high = 0, ans=0;
            
            for(int i=s1-1; i>=0; --i){
                for(int j=s2-1; j>=0; --j){
                    low = i+j+1, high = i+j;
                    ans = (num1[i]-'0')*(num2[j]-'0') + res[low];  //加上进位
                    res[low] = ans%10;   //模10取余
                    res[high] += ans/10;   //储存进位
                } //res索引大的存储的是数值的低位
            }
         
            for(int a: res)
                if(!r.empty() || a!=0) 
                    r.push_back(a+'0');
            return r.empty()? "0": r;
        }
    };
    class Solution {
    public:
        string multiply(string num1, string num2) {
            if(num1.size()==0 || num2.size()==0 || num1=="0" || num2=="0")
                return "0";
            int s1 = num1.size(), s2 = num2.size();
            vector<int> res(s1+s2, 0);
            string r="";
            int low=0, high = 0, ans=0;
            
            for(int i=s1-1; i>=0; --i){
                for(int j=s2-1; j>=0; --j){
                    low = i+j+1, high = i+j;
                    ans = (num1[i]-'0')*(num2[j]-'0') + res[low];  //加上进位
                    res[low] = ans%10;   //模10取余
                    res[high] += ans/10;   //储存进位
                }
            }
        
            int k = 0;
            while(res[k]==0 && k<res.size())
                k++;
            for(int i = k; i<res.size(); ++i)
                r += char(res[i]+'0');
            return r.empty()? "0": r;
     
        }
    };
  • 相关阅读:
    大数据技术与应用案例测试电子商务大数据分析
    贴现值作业
    测试02– 架构评价
    架构师修炼之道读书笔记
    架构漫谈 读后感2
    Linux运维脚本
    nginx ssl配置
    MySQL的时间差函数TIMESTAMPDIFF、DATEDIFF的用法
    MySQL中LOCATE()函数的详解
    shell脚本中echo显示内容带颜色
  • 原文地址:https://www.cnblogs.com/Bella2017/p/11247458.html
Copyright © 2020-2023  润新知