2015-09-09 [一点资讯]--数据抓取和处理工程师--2面

时间:2015-09-09 11:00 ~ 12:00

地点:北京市海淀区王庄路1号 清华同方科技广场D座 西区 7层

 

1. str to float

源码链接:https://github.com/loverszhaokai/Demo/blob/master/str_to_float/src/str_to_float.cc

#include <climits>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <iomanip>
#include <string>

using namespace std;

int last_err_code = 0;
// last_err_code = 0 when there is no error
//
// last_err_code = 1 when there is invalid characters, the valid characters
//                   are 0~9, '.', '+-'
//
// last_err_code = 2 when there is no integer before '.' or there is no integer
//                   after '.'
//                   e.g. ".123", "123.", "."
//
// last_err_code = 3 when there is more than one '.'
//                   e.g. "123..456", "123.4.56"
//
// last_err_code = 4 when the integer is bigger than FLOAT_MAX
//                   e.g. "1111111111111111111111111111111111111.23"
//

// Clear the left and right whitespace
// e.g. "  123 456  " -> "123 456"
char *trim(char *str)
{
    while (*str == ' ' || *str == '\t')
        str++;

    char *start = str;

    if (!(*str))
        return str;

    char *end = str;

    while (*str) {
        if (*str != ' ' && *str != '\t')
            end = str;
        str++;
    }

    *(end + 1) = 0;

    return start;
}

// String to Float
float str_to_float(const char *pstr)
{
    char *pstr_copy, *str;
    // The sign of float, set -1 when the first character is '-'
    int sign = 1;
    // The value of integers
    long long integer = 0;
    // The value of decimals
    double decimal = 0;
    // The multiple of next decimal
    double dec_num = 0.1;
    // Has found dot '.'
    bool has_dot = 0;
    // Has integer
    bool has_integer = 0;

    if (pstr == NULL)
        return 0;

    pstr_copy = strdup(pstr);
    str = trim(pstr_copy);

    if (!(*str)) {
        // "   "
        return 0;
    }

    if (*str == '+' || *str == '-') {
        if (*str == '-')
            sign = -1;
        str++;
    }

    while (*str) {

        if (*str >= '0' && *str <= '9') {

            if (!has_dot) {
                // "123"
                if (!has_integer)
                    has_integer = 1;

                integer *= 10;
                integer += *str - '0';

                if (integer > (long long)INT_MAX) {
                    // e.g. "111111111111111111111111111111111.22"
                    last_err_code = 4;
                    return 0;
                }

            } else if (!has_integer) {
                // ".123"
                last_err_code = 2;
                return 0;
            } else {
                // "123.456"
                if (dec_num < (double)1e-10) {
                    // There are too many decimals, ignore the following decimals
                } else {
                    decimal += (*str - '0') * dec_num;
                    dec_num *= 0.1;
                }
            }

        } else if (*str == '.') {

            if (has_dot) {
                // e.g. "123...456"
                last_err_code = 3;
                return 0;
            }
            has_dot = 1;

        } else {
            // e.g. "123fgh?.456"
            last_err_code = 1;
            return 0;
        }

        str++;
    }

    if (has_dot && (!has_integer || dec_num == 0.1)) {
        // e.g. ".123" or "123." or "."
        last_err_code = 2;
        return 0;
    }

    free(pstr_copy);

    float ret = (float) integer + (float)decimal;
    return ret * sign;
}

int main()
{
    const struct TestCase {
        const char *str;
        const float ret;
        int last_err_code;
    } test_cases[] = {
        // last_err_code != 0
        { "abc", 0, 1 },
        { "123+.456", 0, 1 },
        { "++123.456", 0, 1 },

        { ".", 0, 2 },
        { ".123", 0, 2 },
        { "123.", 0, 2 },

        { "123..456", 0, 3 },
        { "123.4.56", 0, 3 },

        // Case #8:
        { "1111111111111111111111111111111.456", 0, 4 },

        // last_err_code == 0
        { "", 0, 0 },
        { "123.456", 123.456, 0 },
        // There are too many decimals
        { "1.12345678901234567890", 1.12345678, 0 },
    };

    int errors = 0;

    for (int iii = 0; iii < sizeof(test_cases) / sizeof(TestCase); iii++) {
        const TestCase &tc = test_cases[iii];
        // Clear last_err_code
        last_err_code = 0;
        const float actual_ret = str_to_float(tc.str);

        if (tc.ret != actual_ret || last_err_code != tc.last_err_code) {

            errors++;

            cout << "Case #" << iii << ": FAILED" <<  endl;
            cout << "\tExpected ret=" << tc.ret << endl;
            cout << "\tAcutal   ret=" << actual_ret << endl;
            cout << "\tExpected last_err_code=" << tc.last_err_code << endl;
            cout << "\tAcutal   last_err_code=" << last_err_code << endl;
        }
    }

    if (errors == 0)
        cout << "All test passed!" << endl;
    else
        cout << "There are " << errors << " cases failed." << endl;

    return 0;
}

 

2. longest increasing subsequence

源码链接:https://github.com/loverszhaokai/ALG/blob/master/src/longest_increasing_subsequence.cc

// Return the length of the longest increasing subsequence
// e.g. return 4 if nums = { 1, 9, 8, 2, 3, 9 }
int longest_increasing_subsequence(const std::vector<int> &nums)
{
    std::vector<int> max_value(nums.size());

    if (nums.size() == 0)
        return 0;

    max_value[0] = nums[0];

    int start = 0;
    int max_len = 1;
    int cnt_value;
    
    for (int iii = 0; iii < nums.size(); iii++) {
        cnt_value = nums[iii];

        for (int jjj = max_len - 1; jjj >= 0; jjj--) {

            if (cnt_value > max_value[jjj]) {

                max_value[jjj + 1] = cnt_value;

                if (jjj == max_len - 1)
                    max_len++;
                break;
            }
        }

    }

    return max_len;
}

 

posted @ 2015-09-11 01:28 loverszhaokai 阅读(...) 评论(...) 编辑 收藏