力扣468验证IP地址C++判断合法IP字符串

2023-11-05

前言

这是一道常见的笔试面试题,我找实习已经碰到两次了,和矩阵的乘法出现频率一样高,你校招要是全程没遇到可以过来打我;(这道题大厂面试笔试也很常见);

同时,评论区很多人吐槽这种题目是烂题,觉得debug很烦,边界很烦,条件太多,我笑了,等你真正进入公司,参与实际业务中的debug,那么debug的奥秘就能很好地从这道题中体现出来;

而什么DP 贪心之类的纯算法一年到头可能用不到几次;(刷题别刷魔怔了)

题目描述

在这里插入图片描述

请务必注意做笔试题时的好习惯,看下输入数据的范围! 这道题中,也就是提示部分;

解题思路

主功能函数分类大框架

在做着这种字符串处理问题的时候,得找技巧,比如说标记位之类的,可以把大问题按模块清晰整理整多个小问题;

这道题让判断是ipv4还是ipv6还是都不是Neither,那么简单粗暴,直接根据ipv4或者ipv6独有的特征,进入看看规则是否完全匹配即可;

(这里独有的特征可以从提示中得出,ipv4–>. ipv6–>: )

for(auto&c:queryIP){//根据协议特征,进入判断是否完全匹配这个协议
            if(c == '.') return Ipv4(queryIP);
            if(c == ':') return Ipv6(queryIP);
        }

提示字符串只由**英文字母,数字,. 和 : **组成;

怎么按照特定的字符’.'或者‘:’分割成若干子串参考我的这篇博客,当然你乐意可以写一个分割功能的子函数,就是有点麻烦了;


判断IPv4是否合法

那么在判断ipv4中,我们需要判断分割出来的子串部分: 1. 有没有前导0; 2. 有没有出现字母; 3.数字的值是否在0~255之间; 4. 分割出来子串个数是否是4个;

string Ipv4(string s)
    {

        int len = s.size();
        int n = 0;
        for(int i = 0;i<len;i++){
             if(s[i]!='.'&&(s[i]<'0'||s[i]>'9')) return "Neither";//如果出现字母,那么非法
            
            if(i<len-1&&s[i] == s[i+1]&&s[i] == '.') return "Neither";//边界条件,如果两个..出现在一起显然是非法的,我们这个逻辑会这个非法们当成‘ ’分割的时候忽略(直接想不到,调试直接发现的)
            
            if(s[i]=='.') s[i] = ' ';  //为了下面stringstream 默认以' ' 分割(注意这条语句需要放在循环最后,否则提前改了'.'可能影响上面两个if的判断)     
        }

        stringstream ss;
        ss<<s;
        string tmp;
        while(ss>>tmp)//每轮的tmp为分割出来的子串
        {
            n++;//记录子串总数
            
            if(tmp.size()!=1&&tmp[0]=='0'){//有没有前导0?
                return "Neither";
            }

            int itmp = atoi(tmp.c_str());//子串对应数字是否在0~255
            if(itmp<0||itmp>255){
                return "Neither";
            }
        }
    
        if(n==4) return "IPv4";//子串总数需要==4
        return "Neither";
    }

判断IPv6是否合法

那么在判断ipv6中,我们需要判断分割出来的子串部分: 1. 有没有出现f/F之后的字母; 2.子串单位长度是否在1~4; 3. 分割出来子串个数是否是8个;

string Ipv6(string s)
    {
        int n = 0;
        int len = s.size();
        for(int i = 0;i<len;i++){

            if(s[i]!=':'&&((s[i]>'f'&&s[i]<='z')||(s[i]>'F'&&s[i]<'Z'))) return "Neither";//判断有没有f/F之后的字母
            if(i<len-1&&s[i] == s[i+1]&&s[i] == ':') return "Neither";//边界条件,如果两个:: 出现在一起显然是非法的,我们这个逻辑会把这个非法当成‘空格 ’分割的时候忽略(直接想不到,调试直接发现的)
            if(s[i]==':') s[i] = ' ';  //为了下面stringstream 默认以' ' 分割(注意这条语句需要放在循环最后,否则提前改了'.'可能影响上面两个if的判断)     

        }
        string tmp;
        stringstream ss;
        ss<<s;
        while(ss>>tmp)//每轮的tmp为分割出来的子串
        {
            n++;//记录子串总数
            int tlen = tmp.size();
            if(tlen>4) return "Neither";//判断子串单位长度是否1~4
            
        }

        if(n == 8)return "IPv6";//子串总数需要==8
        return "Neither";
    }

其余小边界条件(调试后得)

空串直接return 非法

注意到了上面俩边界条件都是我们用stringstream分割子串的问题,还有个问题就是分隔符’.‘和’:'不可以出现在首位,这个非法我们也会忽略,所以需要拉出去讨论;

string validIPAddress(string queryIP) {
      	
        int len = queryIP.size();
        if(len == 0) return"Neither";//空串防止下面越界
        
        if(queryIP[len-1]==':'||queryIP[len-1]=='.'||queryIP[0]=='.'||queryIP[0]==':') return "Neither";//边界,如果首位有分隔符则不符合规则(直接想不到,调试直接发现的) 
        
        for(auto&c:queryIP){//根据协议特征,进入判断是否完全匹配这个协议
            if(c == '.') return Ipv4(queryIP);
            if(c == ':') return Ipv6(queryIP);
        }
        return "Neither";  
    }

完整代码

class Solution {
public:
    string Ipv4(string s)
    {

        int len = s.size();
        int n = 0;
        for(int i = 0;i<len;i++){
             if(s[i]!='.'&&(s[i]<'0'||s[i]>'9')) return "Neither";
             if(i<len-1&&s[i] == s[i+1]&&s[i] == '.') return "Neither";
             if(s[i]=='.') s[i] = ' ';       
        }
        stringstream ss;
        ss<<s;
        string tmp;
        while(ss>>tmp)
        {
            n++;
            if(tmp.size()!=1&&tmp[0]=='0'){
                return "Neither";
            }
            int itmp = atoi(tmp.c_str());
            if(itmp<0||itmp>255){
                return "Neither";
            }
        }
        if(n==4) return "IPv4";
        return "Neither";
    }
    string Ipv6(string s)
    {
        int n = 0;
        int len = s.size();
        for(int i = 0;i<len;i++){

            if(s[i]!=':'&&((s[i]>'f'&&s[i]<='z')||(s[i]>'F'&&s[i]<'Z'))) return "Neither";
            if(i<len-1&&s[i] == s[i+1]&&s[i] == ':') return "Neither";
            if(s[i]==':') s[i] = ' ';  
        }
        string tmp;
        stringstream ss;
        ss<<s;
        while(ss>>tmp)
        {
            n++;
            int tlen = tmp.size();
            if(tlen>4) return "Neither";
        }

        if(n == 8)return "IPv6";
        return "Neither";
    }
    string validIPAddress(string queryIP) {
      	
        int len = queryIP.size();
        if(len == 0) return"Neither";
        
        if(queryIP[len-1]==':'||queryIP[len-1]=='.'||queryIP[0]=='.'||queryIP[0]==':') return "Neither";
        
        for(auto&c:queryIP){//根据协议特征,进入判断是否完全匹配这个协议
            if(c == '.') return Ipv4(queryIP);
            if(c == ':') return Ipv6(queryIP);
        }
        return "Neither";

        
    }
};

其实个人感觉,只要大方向框架对,分类讨论的思想,那么调个几次也问题不大,而且面试的时候,你会被提醒的,他们这道题都看腻了;

我这个写法不一定好,但是按照我写的来做,思路清晰的情况下两下就能写好功能框架;

其中比较难直接想到的边界条件1.首尾不能出现分隔符; 2.串中不能连续出现分隔符; 这俩条件,调试两次就出来了,就能过了!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

力扣468验证IP地址C++判断合法IP字符串 的相关文章

  • 如何使用MemoryCache代替Timer来触发一个方法?

    以下方法通过等待已运行操作的结果来处理并发请求 对数据的请求可能会使用相同 不同的凭据同时出现 对于每组唯一的凭据 最多可以有一个GetCurrentInternal呼叫正在进行中 当准备就绪时 该呼叫的结果将返回给所有排队的服务员 pri
  • VB.NET 相当于 C# 属性简写吗?

    是否有与 C 等效的 VB NET public string FirstName get set 我知道你能做到 Public Property name As String Get Return name ToString End Ge
  • 如何修复此错误“GDI+ 中发生一般错误”?

    从默认名称打开图像并以默认名称保存 覆盖它 我需要从 Image Default jpg 制作图形 将其放在 picturebox1 image 上并在 picurebox1 上绘制一些图形 它有效 这不是我的问题 但我无法保存 pictu
  • 如何访问另一个窗体上的ListView控件

    当单击与 ListView 所在表单不同的表单中的按钮时 我试图填充 ListView 我在 Form1 中创建了一个方法以在 Form2 中使用 并将参数传递给 Form1 中的方法 然后填充 ListView 当我调试时 我得到了传递的
  • C++中的类查找结构体数组

    我正在尝试创建一个结构数组 它将输入字符串链接到类 如下所示 struct string command CommandPath cPath cPathLookup set an alarm AlarmCommandPath send an
  • 在 C# 中循环遍历文件文件夹的最简单方法是什么?

    我尝试编写一个程序 使用包含相关文件路径的配置文件来导航本地文件系统 我的问题是 在 C 中执行文件 I O 这将是从桌面应用程序到服务器并返回 和文件系统导航时使用的最佳实践是什么 我知道如何谷歌 并且找到了几种解决方案 但我想知道各种功
  • 使用 C 语言使用 strftime() 获取缩写时区

    我看过this https stackoverflow com questions 34408909 how to get abbreviated timezone and this https stackoverflow com ques
  • 使用 JNI 从 Java 代码中检索 String 值的内存泄漏

    我使用 GetStringUTFChars 从使用 JNI 的 java 代码中检索字符串的值 并使用 ReleaseStringUTFChars 释放该字符串 当代码在 JRE 1 4 上运行时 不会出现内存泄漏 但如果相同的代码在 JR
  • 未经许可更改内存值

    我有一个二维数组 当我第一次打印数组的数据时 日期打印正确 但其他时候 array last i 的数据从 i 0 到 last 1 显然是一个逻辑错误 但我不明白原因 因为我复制并粘贴了 for 语句 那么 C 更改数据吗 I use g
  • 在一个字节中存储 4 个不同的值

    我有一个任务要做 但我不知道从哪里开始 我不期待也绝对不想要代码中的答案 我想要一些关于该怎么做的指导 因为我感到有点失落 将变量打包和解包到一个字节中 您需要在一个字节中存储 4 个不同的值 这些值为 NAME RANGE BITS en
  • 上下文敏感与歧义

    我对上下文敏感性和歧义如何相互影响感到困惑 我认为正确的是 歧义 歧义语法会导致使用左推导或右推导构建多个解析树 所有可能的语法都是二义性的语言是二义性语言 例如 C 是一种不明确的语言 因为 x y 总是可以表示两个不同的事物 如下所述
  • 使用 Moq 使用内部构造函数模拟类型

    我正在尝试模拟 Microsoft Sync Framework 中的一个类 它只有一个内部构造函数 当我尝试以下操作时 var fullEnumerationContextMock new Mock
  • 私有模板函数

    我有一堂课 C h class C private template
  • HttpWebRequest 在第二次调用时超时

    为什么以下代码在第二次 及后续 运行时超时 代码挂在 using Stream objStream request GetResponse GetResponseStream 然后引发 WebException 表示请求已超时 我已经尝试过
  • 有人可以提供一个使用 Amazon Web Services 的 itemsearch 的 C# 示例吗

    我正在尝试使用 Amazon Web Services 查询艺术家和标题信息并接收回专辑封面 使用 C 我找不到任何与此接近的示例 所有在线示例都已过时 并且不适用于 AWS 的较新版本 有一个开源项目CodePlex http www c
  • (de)从 CSV 序列化为对象(或者最好是类型对象的列表)

    我是一名 C 程序员 试图学习 C 似乎有一些内置的对象序列化 但我在这里有点不知所措 我被要求将测试数据从 CSV 文件加载到对象集合中 CSV 比 xml 更受青睐 因为它更简单且更易于人类阅读 我们正在创建测试数据来运行单元测试 该集
  • Process.Start() 方法在什么情况下返回 false?

    From MSDN https msdn microsoft com en us library e8zac0ca v vs 110 aspx 返回值 true 表示有新的进程资源 开始了 如果由 FileName 成员指定的进程资源 St
  • 英特尔 Pin 与 C++14

    问题 我有一些关于在 C 14 或其他 C 版本中使用英特尔 Pin 的问题 使用较新版本从较旧的 C 编译代码很少会出现任何问题 但由于 Intel Pin 是操作指令级别的 如果我使用 C 11 或 C 14 编译它 是否会出现任何不良
  • memset 未填充数组

    u32 iterations 5 u32 ecx u32 malloc sizeof u32 iterations memset ecx 0xBAADF00D sizeof u32 iterations printf 8X n ecx 0
  • 在客户端系统中安装后桌面应用程序无法打开

    我目前正在使用 Visual Studio 2017 和 4 6 1 net 框架 我为桌面应用程序创建了安装文件 安装程序在我的系统中完美安装并运行 问题是安装程序在其他计算机上成功安装 但应用程序无法打开 edit 在客户端系统中下载了

随机推荐

  • SpringBoot+Jersey跨域文件上传

    说明 本次所使用的 Spring内置的tomcat端口号为8070 tomcat文件服务器端口号为8060 uni ui的端口号为8080 一 需要的工具 tomcat服务器 作为文件服务器 Spring项目文件 二 创建过程 一 配置To
  • 超平实版Pytorch Self-Attention: 参数详解(尤其是mask)(使用nn.MultiheadAttention)

    目录 Self Attention的结构图 forward输入中的query key value forward的输出 实例化一个nn MultiheadAttention 进行forward操作 关于mask Reference Self
  • redis:redis初识(一)

    1 Redis介绍 Redis是一个将数据存储到内存之中的内存数据库 它主要的作用就是可以快速存取 1 1redis出现的背景 随着互联网 大数据时代的来临 传统的mysql等关系型数据库 数据存储在硬盘之中 已无法满足大型网站日益增长的访
  • 数据资源

    本文综合整理自网站企研 中国学术大数据平台 https r qiyandata com 来源 企研 中国学术大数据平台 公共数据资源 前文回顾 数据资源 八大板块 数据公开下载渠道 上 目录 三农 地理信息 生态环境 碳中和 调查数据 省级
  • 命令行操作数据库

    第一招 mysql服务的启动和停止 net stop mysql net start mysql 第二招 登陆mysql 语法如下 mysql u用户名 p用户密码 键入命令mysql uroot p 回车后提示你输入密码 输入12345
  • 模板特化详解

    模板特化 就是在实例化模板时 对特定类型的实参进行特殊处理 即实例化一个特殊的实例版本 当以特化定义时的形参使用模板时 将调用特化版本 模板特化分为全特化和偏特化 1 函数模板的特化 只能全特化 泛型版本 template
  • MyBatis中的几种查询结果集返回类型映射

    MyBatis中的几种查询结果集返回类型映射 一 MyBatis查询结果类型 MyBatis查询是比较常用的功能操作 对于查询语句来说 它是需要返回查询结果的 不同查询可以返回不同类型的查询结果 例如 查询记录总数 那么就是返回整数类型 查
  • MCC(移动国家码)和 MNC(移动网络码)

    本文转自 MCC 移动国家码 和 MNC 移动网络码 自我的进化http www shanxing top p 164 MCC Mobile Country Code 移动国家码 MCC的资源由国际电联 ITU 统一分配和管理 唯一识别移动
  • 最新ChatGPT网站AI系统源码+详细图文搭建教程/支持GPT4/AI绘画/H5端/Prompt知识库

    一 AI系统 如何搭建部署AI创作ChatGPT系统呢 小编这里写一个详细图文教程吧 SparkAi使用Nestjs和Vue3框架技术 持续集成AI能力到AIGC系统 1 1 程序核心功能 程序已支持ChatGPT3 5 GPT 4提问 A
  • bean依赖注入三种方式

    bean依赖注入的三种方式如下 构造方法注入 set方法注入 P命名空间注入 此处演示的项目结构如下 方法一 构造方法注入 UserDaoImpl java public class UserDaoImpl implements IUser
  • postgreSQL函数糖

    SQL的编写可以直观数据分布 大部分同学用SQL用的都是select xx from join xx on where SQL的优势不在于它的单原子数据处理 当表很多的时候 相似处理的抽象让代码变得简洁 IDE 推荐DataGrip 编译运
  • 图片加载 预制体加载 视频加载 文字加载

    using System Collections using System Collections Generic using UnityEngine using UnityEngine UI using RenderHeads Media
  • deque相关用法

    1 queue的相关用法 include
  • 值得收藏的25道Python练手题(附详细答案)

    题目 1 水仙花数 水仙花数 Narcissistic number 也被称为超完全数字不变数 pluperfect digital invariant PPDI 自恋数 自幂数 阿姆斯壮数或阿姆斯特朗数 Armstrong number
  • 按键控制LED闪烁实验

    实验任务 本节实验任务是使用底板上的PL KEY0和PL KEY1按键来控制底板上的PL LED0和PL LED1两个LED的闪烁方式 没有按键按下时 两个LED保持常亮 如果按键0按下 则两个LED交替闪烁 如果按键1按下 则两个LED同
  • shell脚本系列:1、shell、bash和shell脚本

    shell脚本系列 1 shell bash和shell脚本 文章目录 shell脚本系列 1 shell bash和shell脚本 1 前言 2 shell Bash shell script简介 2 1 shell 2 2 Bash 2
  • Ubuntu安装qt 5.12

    1 下载qt5 12 10 qt下载网址 https download qt io archive qt 下载完成后 将下载的文件拷入Ubuntu 去到文件目录添加执行权限 chmod x 文件名 2 安装 运行该文件 如 qt opens
  • 《遥感原理与应用》总结——遥感图像自动识别分类

    目录 遥感图像自动识别分类 1 基础知识 2 特征变换及特征选择 3 监督分类 4 非监督分类 5 非监督分类与监督分类的结合 6 分类后处理和误差分析 7 提高分类精度的方法 8 基于目标的信息提取 遥感图像自动识别分类 遥感图像自动分类
  • BCGSoft Demo示例展示:Ribbon示例集合

    BCGSoft公司的BCGControlBar产品是全球最优秀的MFC界面类库 功能强大 显示丰富 在国际上享有盛誉 并屡次获奖 是VC界面设计的必备首选 本文中的这些示例程序主要演示了如何在MDI和SDI应用程序中使用Ribbon控件和R
  • 力扣468验证IP地址C++判断合法IP字符串

    目录 前言 题目描述 解题思路 主功能函数分类大框架 判断IPv4是否合法 判断IPv6是否合法 其余小边界条件 调试后得 完整代码 前言 这是一道常见的笔试面试题 我找实习已经碰到两次了 和矩阵的乘法出现频率一样高 你校招要是全程没遇到可