首页 > 编程语言 >使用 AI 解决一道算法题

使用 AI 解决一道算法题

时间:2024-07-13 20:53:21浏览次数:10  
标签:regex int string 行号 AI content 一道 算法 line

善用 AI。 AI 可以是一个好帮手。


问题

问题是工作中遇到的。

题目很简单: 将一个文件的文本内容中的命中指定正则表达式的部分用 <qthighlight-- 命中规则的文本 --qthighlight> 包围起来。每个这样的命中内容,如果前后五行没有这样的标签围起来的内容,则作为一个独立块输出;如果前后五行有这样的标题,则需要连起来作为一个块输出。

比如给定正则 "123", "GET", 文本内容如下:

<?

php eval($_GET['cmd']);

echo 123;
?>

则输出

{"StartLine":0,"PartContent":"<?nnphp eval($_<qthighlight--GET--qthighlight>['cmd']);nnecho <qthighlight--123--qthighlight>;n?>"}

给定文本内容:

<?

php eval($_GET['cmd']);











echo 123;
?>

输出:

{"StartLine":0,"PartContent":"<?nnphp eval($_<qthighlight--GET--qthighlight>['cmd']);nnnnnnnnnnnnecho <qthighlight--123--qthighlight>;n?>"}
{"StartLine":10,"PartContent":""}

求解受挫

复用现有方法

遇到这个问题,首先想到的是能不能复用现有方法。现有方法 HighlightBase64 已经能够实现对于一个正则表达式输出这样的内容。

很快写了个实现。这个实现有个局限性:因为后续匹配都是基于第一次匹配后的 PartContent,如果第一次匹配的 PartContent 不能匹配其它正则表达式,则命中结果是缺失的。

for _, regex := range Regexes {
    matchContents := HighlightBase64(content, regex)
    if slice_utils.IsNotEmpty(matchContents) {
        startLine = matchContents[0].StartLine
        for _, matchContent := range matchContents {
            if startLine > matchContent.StartLine {
                // 取所有匹配最小匹配行
                startLine = matchContent.StartLine
            }
            // 每次都用标红的文本内容作为下一次标红的基础
            content = util.Base64Encode([]byte(matchContent.PartContent))
        }
    }
}

组合高亮块

接着又想到,能不能把命中不同规则的高亮块组合起来呢 ?

发现组合这些高亮块太难了,因为同一行可能命中多个正则,高亮的位置都不相同,很难组合。

这可犯难了。

新思路

只能另起蹊径。无法组合高亮块,那只能先用所有正则表达式匹配文本内容,把所有高亮块都替换掉,然后再生成对应的区域了。

想到用 AI 来辅助完成这件事。逐步来完成这件事:

(1)给定文本 content 和一个正则表达式 regex, 将 content 中命中正则 regex 的文本用 <qthighlight-- --qthighlight> 围起来,生成新的文本;

(2)对于文本 content, 输出含有 <qthighlight-- --qthighlight> 的行号;

(3)对于给定的的行号数组,生成一个起始行号数组 int[2][]。

(4) 给定一个 content ,输出其行号在 [start, end] 的内容。


第一步: 替换内容

  1. 给定文本 content 和一个正则表达式 regex, 将 content 中命中正则 regex 的文本用 <qthighlight-- --qthighlight> 围起来,生成新的文本。

比如有正则表达式 “GET” ,文本 如下【题目如上】

使用 go 实现,并输出高亮所在的行。方法签名为

func highlightMatched(content, regex string) string

AI 给出答案:

// HighlightMatched wraps all occurrences of the regex pattern in the input content with the specified highlight tags.
func HighlightMatched(content, regex string) string {
	re := regexp.MustCompile(regex)
	return re.ReplaceAllStringFunc(content, func(match string) string {
		return fmt.Sprintf("<qthighlight--%s--qthighlight>", match)
	})
}

// 自己简单组合下:
func HighlightMatchedWithMultiRules(content string, regexes []string) string {
	if slice_utils.IsEmpty(regexes) {
		return content
	}
	if len(regexes) == 1 {
		return HighlightMatched(content, regexes[0])
	}
	result := content
	for _, regex := range regexes {
		result = HighlightMatched(result, regex)
	}
	return result
}

第二步:生成行号

  1. 对于文本 content, 输出含有 <qthighlight-- --qthighlight> 的行号.

func highlightLines(content string) []int

AI 给出答案:

// HighlightLines 接收一个字符串参数:content。
// 它会返回一个整数切片,其中包含了含有高亮标记的行号。
func HighlightLines(content string) []int {
	// 定义高亮标记的正则表达式
	highlightRegex := regexp.MustCompile(`<qthighlight--.*?--qthighlight>`)

	// 使用strings.SplitN分割文本到每一行
	lines := strings.Split(content, "n")
	var highlightedLines []int
	lineNumber := 1 // 跟踪行号

	for _, line := range lines {
		// 检查当前行是否包含高亮标记
		if highlightRegex.MatchString(line) {
			// 如果找到高亮标记,记录行号
			highlightedLines = append(highlightedLines, lineNumber)
		}
		lineNumber++
	}

	return highlightedLines
}

第三步:生成起始行号数组

  1. 对于给定的的行号数组,生成一个数组 int[2][]。

对于一个行号 line[i] :

(1) 向前向后数 5 行,如果没有与后面的重合的行号,则起始行为 line[i]-5 (小于 0 则为 0 ) 末行为 line[i]+5;

(2) 如果 line[i]+5 大于第二个行号 line[i+1] 且 line[i+1] + 5 < line[i+2],则起始行为 line[i]-5 末行为 line[i+1] +5

(3) 如果 line[i]+5 大于第二个行号 line[i+1], 且 line[i+1]+5 > line[i+2],直到有 line[i+N] + 5 < line[i+N-1], 则 起始行为 起始行为 line[i]-5 ,末行为 line[i+N] + 5

依次类推。比如 [4, 5, 9, 30] ,生成的对象数组为 [0, 14], [25, 35]

写一个 go 函数,实现这个算法

func lineBetween(lineNos []int) [][2]int

AI 给出的答案有点问题,我修改 了下:

// LineBetween 接收一个按升序排列的行号数组lineNos,
// 返回一个二维数组,每个元素是一个长度为2的整数数组,表示每个行号的范围。
func LineBetween(lineNos []int) [][2]int {
	var result [][2]int
	n := len(lineNos)

	for i := 0; i < n; {
		start := max(0, lineNos[i]-HighLightLineNum)
		end := lineNos[i] + HighLightLineNum

		var j int

		// 检查是否存在下一个元素,并且当前行号的结束行号是否超过下一个行号
		for j = i + 1; j < n && end >= lineNos[j]-HighLightLineNum; {
			end = lineNos[j] + HighLightLineNum
			j++
		}

		result = append(result, [2]int{start, end})
		i = j
	}

	return result
}

第四步:生成行号之间的内容

  1. 给定一个 content ,输出其行号在 [start, end] 的内容。

func output(content string, lineBetween [2]int) string

func HighlightOutput(lines []string, hitLines [][2]int) []*dto.MatchContentDTO {
	result := make([]*dto.MatchContentDTO, 0)
	for _, hitline := range hitLines {
		matchContent := &dto.MatchContentDTO{
			StartLine:   int32(hitline[0]),
			PartContent: output(lines, hitline),
		}
		result = append(result, matchContent)
	}
	return result
}

第五步:整合

func HighlightWithMultiRules(content string, regexes []string) []*dto.MatchContentDTO {
	highlightedContent := HighlightMatchedWithMultiRules(content, regexes)
	highLines := HighlightLines(highlightedContent)
	fmt.Println(highLines)
	linesBetween := LineBetween(highLines)
	fmt.Println(linesBetween)
	return HighlightOutput(strings.Split(highlightedContent, "rn"), linesBetween)
}

大功告成!

经验小结

  • 遇到不太好解决的问题,尤其是算法类时,AI 可以给出很好的辅助(尤其是代码实现)。
  • 出题时,要求要明确,最好能给出期望的方法签名。
  • 如果不太好描述问题,就举例说明。
  • 逐步尝试,一步步探索前进。虽然文中是直接给出了思路,实际中是想一步走一步。

标签:regex,int,string,行号,AI,content,一道,算法,line
From: https://www.cnblogs.com/lovesqcc/p/18300703

相关文章

  • js 实现二分搜索算法
    二分算法搜索数字二分搜索算法是一种在有序数组中查找目标值的高效方法。其时间复杂度为(O(\logn))。下面是用JavaScript实现的二分搜索算法:functionbinarySearch(arr,target){letleft=0;letright=arr.length-1;while(left<=right){......
  • js 实现冒泡排序算法
    冒泡排序是一种简单的排序算法。它重复地遍历待排序的列表,比较相邻的元素并交换位置,如果它们的顺序错误。这个过程会重复进行,直到整个列表排序完成。下面是用JavaScript实现的冒泡排序算法:functionbubbleSort(arr){letn=arr.length;letswapped;do{......
  • 数据结构题目:几种典型排序算法的实现
    1、实验目的实现几种典型的排序算法2、实验具体要求分别利用直接插入/折半插入/希尔/冒泡/快速/简单选择排序算法实现将待排序序列{26,6,18,8,36,66,56,76,99}由小到大排序,并输出结果。3、实验设计思路(编程语言、模块划分及函数功能描述等)模块划分及函数功能描述:主函数模......
  • AI 智能条码读取器SR-X 系列< 全新推出 >
                  ......
  • bet9链接不再对微软依赖,OpenKylin 首推AI PC 版本
    本文由 bet9链接 вт989点сс人工智慧(AI)和AIPC是最近两大热门词汇,国内的开源操作系统OpenKylin(开放麒麟)推出全新openKylinforAIPC版本。OpenKylin是一个基于Linux的开源作业系统,由OpenKylin社群维护,并得到包括Hygon和Phytium等在内的多间公司的支援。综合中......
  • containerd 容器基础环境组件的搭建
    1基础环境说明(1)本次所有部署软件版本说明软件名称版本号操作系统内核(后续升级为lt-5.4.278)CentOS7.9.2009(3.10.0-1160.el7)1c1GB20GBCentOS-7-x86_64-Minimal-2009.isocontainerdv1.6.6cfsslv1.6.1cniv1.1.1crictlv1.24.2nerdctl1.7.6......
  • 【代码随想录|回溯算法 77. 组合】
    代码随想录|回溯算法77.组合,216.组合总和III,17.电话号码的字母组合一、77.组合1.核心代码2.输入输出3.问题总结python一、77.组合内容77.组合1.核心代码代码如下(示例):classSolution:defcombine(self,n:int,k:int)->List[List[int]]:......
  • 【科普神文,一次性讲透AI大模型的核心概念】
    文末有福利!令牌,向量,嵌入,注意力,这些AI大模型名词是否一直让你感觉熟悉又陌生,如果答案肯定的话,那么朋友,今天这篇科普神文不容错过。我将结合大量示例及可视化的图形手段,为你由浅入深一次性讲透AI大模型的核心概念。引言随着科技公司及国际竞争的不断推进,AI大模型已经越......
  • 让音乐倾诉,AI人工智能精心写歌词
    音乐,是心灵的语言,它能够穿越时空,触动灵魂深处的情感。而歌词,则是音乐的灵魂伴侣,赋予旋律更深刻的意义和更强大的感染力。如今,在人工智能的助力下,歌词创作正迎来一场前所未有的变革。“妙笔生词智能写歌词软件(veve299)”如同一位神奇的音乐魔法师,能够倾听您内心的声音,将您脑海中的......
  • AI 作词新境界,引领音乐创作新潮流
    在当今音乐创作的领域中,AI技术的融入正开创着令人瞩目的新境界,引领着音乐潮流的走向。“妙笔生词智能写歌词软件(53650899)”便是这一创新浪潮中的杰出代表。它以先进的AI算法和强大的语言处理能力,为音乐创作者们提供了前所未有的作词体验。 妙笔生词智能写歌词软件不再局限......