C++面试题和笔试题(五)-手撕代码篇

一、编程题

给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。

说明:本题中,我们将字符串定义为有效的回文串

示例1:

输入:‘A man,a pla, a canal:Panama"

输出:true

解释:“amanaplanacanalpana ma"是回文串

示例2:

输入:“race a car"

输出:false

解释:"raceacar"不是回文串

提示:

1<=s.length<=2*105

字符串s由ASCII字符组成

请作答:

#include   
#include   
#include   
  
using namespace std;  
  
bool isPalindrome(string s) {  
    int left = 0;  
    int right = s.length() - 1;  
  
    while (left < right) {  
        // 跳过非字母和数字的字符  
        while (left < right && !isalnum(s[left])) {  
            left++;  
        }  
        while (left < right && !isalnum(s[right])) {  
            right--;  
        }  
  
        // 转换为小写进行比较  
        char leftChar = tolower(s[left]);  
        char rightChar = tolower(s[right]);  
  
        if (leftChar != rightChar) {  
            return false;  
        }  
  
        left++;  
        right--;  
    }  
  
    return true;  
}  
  
int main() {  
    string s1 = "A man,a plan,a canal:Panama";  
    string s2 = "race a car";  
  
    cout << isPalindrome(s1) << endl;  // 输出: true  
    cout << isPalindrome(s2) << endl;  // 输出: false  
  
    return 0;  
}

这道题的考点主要集中在以下两个方面:

  1. 字符串处理:本题要求验证一个字符串是否是回文串,并且只考虑字母和数字字符,同时忽略字母的大小写。这要求考生熟悉C++中字符串的处理方式,包括如何遍历字符串、如何判断字符的类型(字母、数字等)、以及如何进行大小写转换等。

  2. 双指针法:在解决回文串问题时,一个常见的方法是使用双指针法。本题要求考生能够运用双指针法,从字符串的两端开始比较字符,并逐步向中间移动,以判断字符串是否是回文串。这种方法要求考生对指针操作有一定的理解和掌握。

通过这道题,考官可以评估考生对C++字符串处理的基本技能以及双指针法的应用能力。同时,这道题也考察了考生对回文串概念的理解以及在实际编程中解决问题的能力。

二、编程题

 C++实现StringToDouble

要求:

  1. 不得使用库函数
  2. 忽略字符串中空格
  3. 只保留小数点后4位,如果小数点后非有效位时,则需要被删除(0.230018-->0.23)
  4. 小数点后4位需进行四舍五入(“0.230068-->0.2301)

b、例子:

"12.89"-->12.89

"+12.89"-->12.89

"-12.89"-->12.89

"12.8900023"-->12.89

"12.8900"-->12.89

"12.8900523"-->12.8901

c函数:double StringToDouble(const char *ch){}

请作答:   

#include   
#include   
  
double StringToDouble(const char* str) {  
    bool isNegative = false;  
    int decimalPos = -1;  
    double result = 0.0;  
    double decimalFactor = 0.1;  
      
    // 跳过前导空格  
    while (*str == ' ') {  
        str++;  
    }  
      
    // 检查符号  
    if (*str == '+' || *str == '-') {  
        isNegative = (*str == '-');  
        str++;  
    }  
      
    // 读取整数部分  
    while (*str >= '0' && *str <= '9') {  
        result = result * 10.0 + (*str - '0');  
        str++;  
    }  
      
    // 读取小数部分  
    if (*str == '.') {  
        str++;  
        decimalPos = 0;  
        while (*str >= '0' && *str <= '9' && decimalPos < 4) {  
            result += (*str - '0') * decimalFactor;  
            decimalFactor /= 10.0;  
            decimalPos++;  
            str++;  
        }  
          
        // 处理小数点后超过4位的部分  
        if (decimalPos == 4 && *str >= '5' && *str <= '9') {  
            result += decimalFactor;  
        }  
    }  
      
    // 如果原字符串是负数,则取反  
    if (isNegative) {  
        result = -result;  
    }  
      
    return result;  
}  
  
int main() {  
    std::cout << StringToDouble("12.89") << std::endl;  
    std::cout << StringToDouble("+12.89") << std::endl;  
    std::cout << StringToDouble("-12.89") << std::endl;  
    std::cout << StringToDouble("12.8900023") << std::endl;  
    std::cout << StringToDouble("12.8900") << std::endl;  
    std::cout << StringToDouble("12.8900523") << std::endl;  
      
    return 0;  
}

我们有一个叫做StringToDouble的函数,它可以帮助我们把一个表示数字的字符串变成一个真正的数字。

double StringToDouble(const char* str) {

我们定义了一个叫做isNegative的开关,用来表示数字是不是负的。一开始我们假设它不是负的,所以给它一个“关”的状态

bool isNegative = false; // 是不是负数

然后,我们有一个计数器decimalPos,用来数小数点后面有多少数字。开始我们还没看到小数点,所以给它一个特殊的数字-1

int decimalPos = -1; // 小数点后面的数字数量

接下来,我们有一个盒子result,用来装我们转换得到的数字。开始我们先在盒子里放一个0。

double result = 0.0; // 转换得到的数字

我们还有一个小工具decimalFactor,它可以帮助我们计算小数点后面的数字是多少。开始我们先给它一个值0.1

double decimalFactor = 0.1; // 小数点后面计算的小工具

 现在,我们开始看字符串str。如果字符串开始的地方有空格,我们就一直跳过这些空格。

while (*str == ' ') {  
    str++;  
}

如果字符串开始的地方有一个加号或减号,我们就看它是加号还是减号,然后决定isNegative是“开”还是“关”。之后我们再继续看后面的字符。

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

 如果字符串现在的位置是一个数字(0到9之间),我们就把它加到result里。为了加上这个数字,我们先让result乘以10(因为我们要把它放在之前数字的后面),然后再加上这个数字。然后我们再继续看后面的字符。

while (*str >= '0' && *str <= '9') {  
    result = result * 10.0 + (*str - '0');  
    str++;  
}

 如果字符串现在的位置是一个小数点,我们就开始处理小数点后面的数字。每次处理一个数字,我们都用decimalFactor来帮助我们计算它的大小,并且让decimalFactor变得越来越小(因为小数点后面的数字比前面的数字小)。每次处理完一个数字,我们都让decimalPos加1。如果小数点后面有很多数字,我们只处理前4个,如果第5个数字是5到9之间的数,我们就让result变大一点点,实现四舍五入。

if (*str == '.') {  
    str++;  
    decimalPos = 0;  
    while (*str >= '0' && *str <= '9' && decimalPos < 4) {  
        result += (*str - '0') * decimalFactor;  
        decimalFactor /= 10.0;  
        decimalPos++;  
        str++;  
    }  
    if (decimalPos == 4 && *str >= '5' && *str <= '9') {  
        result += decimalFactor;  
    }  
}

 如果isNegative是“开”的状态(也就是说我们得到的数字是负数),我们就把result变成它的相反数。然后,我们就把result(也就是转换得到的数字)返回给调用这个函数的人。

if (isNegative) {  
    result = -result;  
}  
return result;  
}

这道题目的考点主要有以下几个方面:

  1. 字符串处理:题目考查了如何读取并解析一个字符串,特别是当字符串表示一个数字时。这包括跳过字符串前面的空格、识别正负号、处理整数部分和小数部分。

  2. 类型转换:题目要求将字符串形式的数字转换成实际的double类型数值。这涉及到字符串到数值的转换逻辑,比如如何将字符'0'到'9'转换成相应的数值,以及如何处理小数部分。

  3. 逻辑判断与条件控制:题目中涉及到多个条件判断,比如判断当前字符是否为数字、是否为小数点、是否为正负号等,并根据这些条件执行不同的操作。

  4. 循环与迭代:在处理字符串时,需要使用循环来逐个检查字符串中的每个字符,并根据字符的类型进行相应的处理。

  5. 四舍五入:在处理小数时,需要考虑到四舍五入的规则,特别是当小数部分超过一定位数时。

  6. 函数定义与调用:题目要求定义一个函数来完成转换任务,这涉及到函数的定义、参数传递、返回值处理等方面。

 

你可能感兴趣的:(c++,算法)