news 2026/4/23 13:02:25

(新卷,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/4/23 12:49:42

人工智能论文改写工具横向评测:8大网站降重能力解析

在AI论文工具的选择上&#xff0c;8款热门平台针对降重、降低AIGC检测率及论文写作等核心功能进行了实测对比&#xff0c;结合效率、准确性和用户体验的综合评估&#xff0c;以下排名基于客观数据与真实反馈得出&#xff0c;帮助用户快速匹配需求。 排名 工具名称 关键优势 …

作者头像 李华
网站建设 2026/4/9 17:19:35

8大论文改写网站AI工具横向对比:降重与改写能力深度分析

热门AI论文工具实测对比显示&#xff0c;8款主流平台在降重、规避AIGC检测及论文写作等核心功能上表现各异&#xff0c;通过效率、准确率与用户体验的多维度测评&#xff0c;最终排名基于客观测试数据与真实用户反馈生成&#xff0c;可高效适配不同场景需求。 排名 工具名称 …

作者头像 李华
网站建设 2026/4/23 11:29:53

AI智能体开发全攻略:从Monica到Manus的成功路径

文章讲述了华人团队创建的AI智能体公司Manus从成立到被Meta收购的历程。Manus产品仅发布9个月就被估值数十亿美元完成收购&#xff0c;其技术与产品哲学源于更早的Monica浏览器插件。团队采取全球化战略&#xff0c;从工具到Agent实现产品跃迁&#xff0c;将AI从"回答问题…

作者头像 李华
网站建设 2026/4/23 12:11:38

Flutter 数据库模块之 Draft 设计

目录 &#x1f4c2; 1. 简介 1.1 Drift vs sqflite 1.2 Drift vs Hive / Sembast vs SharedPreferences 2. &#x1f531; 核心架构设计 3. &#x1f4a0; 使用步骤 3.1 添加依赖 3.2 插入数据 3.3 查询数据 3.4 Drift 核心操作配套表 1. 为什么有“终结方法”&#x…

作者头像 李华
网站建设 2026/4/23 12:20:32

测试卡壳?掌握这7招,让你的业务代码“可测性”起飞!

01、为什么要进行可测性改造 业务项目测试前、或者测试的过程中&#xff0c;常常会遇到以下方面的困难&#xff1a; 由于项目历史实现包袱&#xff0c;或者当前项目的技术架构实现&#xff0c;导致某些场景根本无法进行测试&#xff1b; 某些场景虽然可以测试&#xff0c;但测…

作者头像 李华