news 2026/5/20 16:21:33

(新卷,100分)- 在字符串中找出连续最长的数字串(含“+-”号)(Java JS Python)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
(新卷,100分)- 在字符串中找出连续最长的数字串(含“+-”号)(Java JS Python)

(新卷,100分)- 在字符串中找出连续最长的数字串(含“+-”号)(Java & JS & Python)

题目描述

请在一个字符串中找出连续最长的数字串,并返回这个数字串。

如果存在长度相同的连续数字串,返回最后一个。

如果没有符合条件的字符串,返回空字符串””。

注意:

  • 数字串可以由数字”0-9″、小数点”.”、正负号”±”组成,长度包括组成数字串的所有符号。
  • “.”、“±”仅能出现一次,”.”的两边必须是数字,”±”仅能出现在开头且其后必须要有数字。
  • 长度不定,可能含有空格。
输入描述

输出描述

用例
输入1234567890abcd9.+12345.678.9ed
输出+12345.678
说明
题目解析

本题我的思路是利用双指针。

定义两个指针变量L,R,其中L指向数字串的开头,R用于扫描。

首先,我们需要确定第一个数字串的开头位置,逻辑很简单,遍历输入字符串S的每一个字符c:

  • 如果c是数字,则c字符所在位置可以作为第一个数字串的开头位置,否则继续查找下一个c
  • 如果c是加减号,则还需要进一步检查这个加减号的后面是不是跟着数字,如果跟着数字,则可以作为第一个数字串的开头,否则继续查找下一个c

找到第一个数字串的开头后,即知道L位置后,我们可以初始化R = L+1,即R从L+1位置开始扫描,假设扫描到的字符是c,则存在以下情况:

  • c是数字,则不会中断数字串,可以继续R++扫描
  • c是点,则需要先判断,这个点是否是合法的数字串点(即点位置R前后都是数字):
  1. 如果点位置前后不都是数字,则说明,点位置 R 前面的内容无法复用到下一个数字串中,此时我们需要先将[L, R-1]范围的合法数字串记录下来,然后按照前面遍历S来找数字串开头位置的逻辑,来找下一个数字串开头位置
  2. 如果点位置前后都是数字,则此时我们进一步判断,当前数字串,即[L, R-1]部分是否还有其他点,如果有,则一个数字串中不能包含两个点,此时我们需要先记录[L, R-1]范围内的合法数字串,假设第一个点位置是dotIdx,则下一个数字开头位置L = dotIdx + 1,这样才能保证下一个数字串最长,然后更新dotIdx = R,最后继续R++扫描
  • c是加减号,此时会中断数字串,因此我们需要先记录[L, R-1]范围内的合法数字串,然后判断当前R位置的后面是否跟着数字,这将决定我们下一个数字的开头位置:
  1. 如果R+1位置是数字,则下一个数字串的开头L=R,因为数字串可以以加减号开头,只要加减号后面跟着数字,之后R++继续扫描
  2. 如果R+1位置不是数字,则我们应该按照前面遍历S来找数字串开头位置的逻辑,来找下一个数字串的开头位置。
  • c是其他字符,则会中断数字串,此时我们应该记录[L, R-1]部分合法数字串,然后按照前面遍历S来找数字串开头位置的逻辑,来找下一个数字串的开头位置。
JS算法源码
/* JavaScript Node ACM模式 控制台输入获取 */ const readline = require("readline"); const rl = readline.createInterface({ input: process.stdin, output: process.stdout, }); rl.on("line", (line) => { console.log(getResult(line)); }); function getResult(s) { // 记录题解 let ans = ""; // 记录数字串中“.”的位置,-1表示数字串中没有点 let dotIdx = -1; // l 指向数字串的开头 l = findStartIdx(s, 0); // r 用于扫描数字串 r = l + 1; while (r < s.length) { // 当前扫描的到的字符 const c = s[r]; if (isDigit(c)) { // c是数字,则继续扫描下一个 r++; } else if (isSign(c)) { // c是加减号,则数字串扫描中断,我们需要先记录[l, r-1]范围的数字串 ans = getAns(s, l, r, ans); if (isValidSign(r, s)) { // 由于加减号可以作为数字串开头,如果r位置的加减号是一个合法数字串开头加减号,则可以当成下一个数字串的开头 l = r; } else { // 否则,从r+1开始继续找下一个数字的开头 l = findStartIdx(s, r + 1); } // 新数字串的开头找到后,从l+1开始扫描 r = l + 1; // 同时注意重置dotIdx记录 dotIdx = -1; } else if (isDot(c)) { // 由于dot处理比较复杂,这里无论dot是否会中断数字串扫描,都先将[l, r-1]部分的数字串记录下来 ans = getAns(s, l, r, ans); if (isValidDot(r, s)) { // 如果是合法数字串dot, 则判断当前数字串是否已存在”.“ if (dotIdx != -1) { // 如果已存在".", 则当前数字串包含了两个".",肯定不合法,此时需要舍弃第一个".", 即新数字串开头位置设置在第一个"."后面 l = dotIdx + 1; } // 更新dotIdx为第二个"."的位置 dotIdx = r; // r继续扫描下一个 r++; } else { // 如果不是合法数字串dot,即该dot前后不都是数字,则新数字串不能包含进当前dot位置,新数字串开头需要从r+1开始找 l = findStartIdx(s, r + 1); r = l + 1; dotIdx = -1; } } else { // c是其他字符, 则数字串被打断,此时需要先记录[l, r-1]范围的当前数字串, 然后重新寻找下一个数字串的开头 ans = getAns(s, l, r, ans); l = findStartIdx(s, r + 1); r = l + 1; dotIdx = -1; } } return getAns(s, l, r, ans); } function isSign(c) { return c == "+" || c == "-"; } function isDot(c) { return c == "."; } function isDigit(c) { return c >= "0" && c <= "9"; } // ”.”的两边必须是数字 function isValidDot(dotIdx, s) { const preIdx = dotIdx - 1; const nxtIdx = dotIdx + 1; return ( preIdx >= 0 && isDigit(s[preIdx]) && nxtIdx < s.length && isDigit(s[nxtIdx]) ); } // ”±”仅能出现在开头且其后必须要有数字 function isValidSign(signIdx, s) { const nxtIdx = signIdx + 1; return nxtIdx < s.length && isDigit(s[nxtIdx]); } // 记录数字串时,只保留最长的数字串 function getAns(s, l, r, ans) { // 如果存在长度相同的连续数字串,返回最后一个。 因此下面判断是>= return l < s.length && r - l >= ans.length ? s.slice(l, r) : ans; } // 从s字符串的start位置开始找数字串的开头字符,数字串的开头字符可以是数字,也可以是符号 function findStartIdx(s, i) { while (i < s.length) { const c = s[i]; if (isDigit(c) || (isSign(c) && isValidSign(i, s))) break; i++; } return i; }
Java算法源码
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.println(getResult(sc.nextLine())); } public static String getResult(String s) { // 记录题解 String ans = ""; // 记录数字串中“.”的位置,-1表示数字串中没有点 int dotIdx = -1; // l 指向数字串的开头 int l = findStartIdx(s, 0); // r 用于扫描数字串 int r = l + 1; while (r < s.length()) { // 当前扫描的到的字符 char c = s.charAt(r); if (isDigit(c)) { // c是数字,则继续扫描下一个 r++; } else if (isSign(c)) { // c是加减号,则数字串扫描中断,我们需要先记录[l, r-1]范围的数字串 ans = getAns(s, l, r, ans); if (isValidSign(r, s)) { // 由于加减号可以作为数字串开头,如果r位置的加减号是一个合法数字串开头加减号,则可以当成下一个数字串的开头 l = r; } else { // 否则,从r+1开始继续找下一个数字的开头 l = findStartIdx(s, r + 1); } // 新数字串的开头找到后,从l+1开始扫描 r = l + 1; // 同时注意重置dotIdx记录 dotIdx = -1; } else if (isDot(c)) { // 由于dot处理比较复杂,这里无论dot是否会中断数字串扫描,都先将[l, r-1]部分的数字串记录下来 ans = getAns(s, l, r, ans); if (isValidDot(r, s)) { // 如果是合法数字串dot, 则判断当前数字串是否已存在”.“ if (dotIdx != -1) { // 如果已存在".", 则当前数字串包含了两个".",肯定不合法,此时需要舍弃第一个".", 即新数字串开头位置设置在第一个"."后面 l = dotIdx + 1; } // 更新dotIdx为第二个"."的位置 dotIdx = r; // r继续扫描下一个 r++; } else { // 如果不是合法数字串dot,即该dot前后不都是数字,则新数字串不能包含进当前dot位置,新数字串开头需要从r+1开始找 l = findStartIdx(s, r + 1); r = l + 1; dotIdx = -1; } } else { // c是其他字符, 则数字串被打断,此时需要先记录[l, r-1]范围的当前数字串, 然后重新寻找下一个数字串的开头 ans = getAns(s, l, r, ans); l = findStartIdx(s, r + 1); r = l + 1; dotIdx = -1; } } return getAns(s, l, r, ans); } public static boolean isDigit(char c) { return c >= '0' && c <= '9'; } public static boolean isSign(char c) { return c == '+' || c == '-'; } public static boolean isDot(char c) { return c == '.'; } // ”.”的两边必须是数字 public static boolean isValidDot(int dotIdx, String s) { int preIdx = dotIdx - 1; int nxtIdx = dotIdx + 1; return preIdx >= 0 && isDigit(s.charAt(preIdx)) && nxtIdx < s.length() && isDigit(s.charAt(nxtIdx)); } // ”±”仅能出现在开头且其后必须要有数字 public static boolean isValidSign(int signIdx, String s) { int nxtIdx = signIdx + 1; return nxtIdx < s.length() && isDigit(s.charAt(nxtIdx)); } // 从s字符串的i位置开始找数字串的开头字符,数字串的开头字符可以是数字,也可以是符号 public static int findStartIdx(String s, int i) { while (i < s.length()) { char c = s.charAt(i); if (isDigit(c) || (isSign(c) && isValidSign(i, s))) break; i++; } return i; } // 记录数字串时,只保留最长的数字串 public static String getAns(String s, int l, int r, String ans) { // 如果存在长度相同的连续数字串,返回最后一个。 因此下面判断是>= return l < s.length() && r - l >= ans.length() ? s.substring(l, r) : ans; } }
Python算法源码
# 输入获取 s = input() def isSign(c): return c == '+' or c == '-' def isDot(c): return c == '.' # ”±”仅能出现在开头且其后必须要有数字 def isValidSign(signIdx): nxtIdx = signIdx + 1 return nxtIdx < len(s) and s[nxtIdx].isdigit() # ”.”的两边必须是数字 def isValidDot(dotIdx): preIdx = dotIdx - 1 nxtIdx = dotIdx + 1 return preIdx >= 0 and s[preIdx].isdigit() and nxtIdx < len(s) and s[nxtIdx].isdigit() # 记录数字串时,只保留最长的数字串 def getAns(l, r, ans): # 如果存在长度相同的连续数字串,返回最后一个。 因此下面判断是>= return s[l:r] if l < len(s) and r - l >= len(ans) else ans # 从s字符串的start位置开始找数字串的开头字符,数字串的开头字符可以是数字,也可以是符号 def findStartIdx(i): while i < len(s): c = s[i] if c.isdigit() or (isSign(c) and isValidSign(i)): break i += 1 return i # 算法入口 def getResult(): # 记录题解 ans = "" # 记录数字串中“.”的位置,-1表示数字串中没有点 dotIdx = -1 # l 指向数字串的开头 l = findStartIdx(0) # r 用于扫描数字串 r = l + 1 while r < len(s): # 当前扫描的到的字符 c = s[r] if c.isdigit(): # c是数字,则继续扫描下一个 r += 1 elif isSign(c): # c是加减号,则数字串扫描中断,我们需要先记录[l, r-1]范围的数字串 ans = getAns(l, r, ans) if isValidSign(r): # 由于加减号可以作为数字串开头,如果r位置的加减号是一个合法数字串开头加减号,则可以当成下一个数字串的开头 l = r else: # 否则,从r+1开始继续找下一个数字的开头 l = findStartIdx(r+1) # 新数字串的开头找到后,从l+1开始扫描 r = l + 1 # 同时注意重置dotIdx记录 dotIdx = -1 elif isDot(c): # 由于dot处理比较复杂,这里无论dot是否会中断数字串扫描,都先将[l, r-1]部分的数字串记录下来 ans = getAns(l, r, ans) if isValidDot(r): # 如果是合法数字串dot, 则判断当前数字串是否已存在”.“ if dotIdx != -1: # 如果已存在".", 则当前数字串包含了两个".",肯定不合法,此时需要舍弃第一个".", 即新数字串开头位置设置在第一个"."后面 l = dotIdx + 1 # 更新dotIdx为第二个"."的位置 dotIdx = r # r继续扫描下一个 r += 1 else: # 如果不是合法数字串dot,即该dot前后不都是数字,则新数字串不能包含进当前dot位置,新数字串开头需要从r+1开始找 l = findStartIdx(r+1) r = l + 1 dotIdx = -1 else: # c是其他字符, 则数字串被打断,此时需要先记录[l, r-1]范围的当前数字串, 然后重新寻找下一个数字串的开头 ans = getAns(l, r, ans) l = findStartIdx(r + 1) r = l + 1 dotIdx = -1 return getAns(l, r, ans) # 算法调用 print(getResult())
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/15 14:27:16

(新卷,100分)- 字符串筛选排序(Java JS Python C)

(新卷,100分)- 字符串筛选排序&#xff08;Java & JS & Python & C&#xff09;题目描述输入一个由N个大小写字母组成的字符串按照ASCII码值从小到大进行排序查找字符串中第K个最小ASCII码值的字母(k>1)输出该字母所在字符串中的位置索引(字符串的第一个位置索引…

作者头像 李华
网站建设 2026/5/16 15:03:23

深度学习毕设项目:机器学习基于CNN卷积网络的动物是否疲劳识别

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/5/20 12:54:33

1小时原型:用OpenWeatherMap打造旅行天气规划器

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 快速开发一个旅行天气规划器原型&#xff0c;功能&#xff1a;1. 用户输入旅行日期和目的地 2. 获取OpenWeatherMap的天气预报数据 3. 根据天气情况自动生成打包建议(如带伞、防晒…

作者头像 李华
网站建设 2026/5/16 16:05:55

RStudio官网秘籍:1小时搭建数据科学原型

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个数据科学原型框架&#xff1a;1) 预置常用数据科学工作流模板 2) 集成自动化EDA(探索性数据分析)功能 3) 包含模型快速验证模块 4) 支持一键生成演示报告。使用plumber创建…

作者头像 李华
网站建设 2026/5/20 12:12:36

大模型产品经理全栈指南:技术理解、产品设计与职业发展,如何从零开始成为产品经理

本文系统介绍了大模型产品经理的定义、职责、发展方向及必备技能&#xff0c;详述了从初级到专家的职业发展路径&#xff0c;分析了就业前景与市场需求。文章提供了一套完整的大模型学习体系&#xff0c;包括基础篇、进阶篇和实战篇&#xff0c;涵盖Python入门、大模型核心原理…

作者头像 李华
网站建设 2026/5/20 12:12:39

基于Python的历届奥运会数据可视化分析系统毕业设计项目源码

项目简介基于 Python 的历届奥运会数据可视化分析系统&#xff0c;聚焦体育数据洞察 “历史溯源、趋势挖掘、价值呈现” 的核心需求&#xff0c;针对传统体育数据 “维度单一、分析浅层、交互不足” 的痛点&#xff0c;构建覆盖体育爱好者、数据分析师、体育管理机构的全流程数…

作者头像 李华