- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个指定的字符串,我需要检查该字符串是否有指定长度的相同部分。例如,如果字符串为“abcdab”且长度指定为 2,则该字符串中的相同部分为“ab”(始终查找重复次数最多的部分)。为了获得最佳性能,我重新设计了算法 4-5 次,但最终,如果 String 的长度超过 1m+,则会抛出 Java 堆空间错误。
所以我的问题是:如何解决错误,也许有另一种方法来检查相同的部分,或者也许有其他方法来构建整个算法。我想出了一种可能的解决方案,但它的工作速度非常慢,所以我只要求与我当前算法一样快的解决方案,或者甚至更快的解决方案。这是当前代码:
int length = 2;
String str = "ababkjdklfhcjacajca";
ArrayList<String> h = new ArrayList<String>();
h.add(str.substring(0, length));
ArrayList<Integer> contains = new ArrayList<Integer>();
contains.add(1);
String c;
for (int g = 1; g < str.length()-length+1; g++) {
c = str.substring(g, length+g);
for (int e = 0; e < h.size(); e++) {
if (h.get(e).charAt(0) == c.charAt(0) && h.get(e).charAt(length-1) == c.charAt(length-1)) {
if (h.get(e).equals(c)) {
contains.set(e, contains.get(e)+1);
break;
}
}
else if (e+1 == h.size()) {
h.add(c);
contains.add(1);
break;
}
}
}
ArrayList h
存储字符串的每个唯一部分,ArrayList 包含表示字符串的每个唯一部分的重复次数。String c
是主要问题(这里是java堆空间点)。它在存储到 ArrayList h
之前逐渐表示字符串的每个部分(如果该 c
是唯一的)。之后,我将使用 ArrayLists 找到最重复的列表并打印它们。
最佳答案
如果您想在时间和内存方面高效地进行搜索,我建议您执行以下操作:
首先,创建一个简单的字符直方图,其中包含每个字符出现的次数。如果子字符串的第一个字符的出现次数少于我们迄今为止找到的最常见子字符串,我们可以跳过该子字符串。
我们不使用创建包含字符内容副本的子字符串,而是使用 CharBuffer
其中wraps字符串并调整其 position
和 limit
来表示一个子序列。当然,一旦缓冲区作为键存储在映射中,我们就不能修改它,因此当每个键存储在映射中时,我们为每个键创建一个新的缓冲区。因此,我们最多为每个不同的子字符串创建一个 CharBuffer
,这些缓冲区仍然只包装 String
而不是复制任何字符数据
public static Map<String,Integer> mostCommonSubstring(String s, int len) {
int[] charHistogram = new int[Character.MAX_VALUE+1];
s.chars().forEach(ch -> charHistogram[ch]++);
int most = 0;
HashMap<Buffer, Integer> subStrings = new HashMap<>();
CharBuffer cb = CharBuffer.wrap(s);
for(int ix = 0, e = s.length()-len; ix <= e; ix++) {
if(charHistogram[s.charAt(ix)] < most) continue;
int num = subStrings.merge(cb.limit(ix+len).position(ix), 1, Integer::sum);
if(num == 1) cb = CharBuffer.wrap(s);
if(num > most) most = num;
}
final int mostOccurences = most;
return subStrings.entrySet().stream()
.filter(e -> e.getValue() == mostOccurences)
.collect(Collectors.toMap(e -> e.getKey().toString(), Map.Entry::getValue));
}
前两行创建我们的直方图
int[] charHistogram = new int[Character.MAX_VALUE+1];
s.chars().forEach(ch -> charHistogram[ch]++);
循环内
if(charHistogram[s.charAt(ix)] < most) continue;
检查当前子字符串的第一个字符的出现次数是否少于我们迄今为止找到的最常见字符串,并在这种情况下跳过后续测试。
下一行调整当前缓冲区来表示子字符串,并更新映射,将缓冲区与 1
关联(如果不存在),或者将 1
添加到子字符串的计数中现有的映射。
int num = subStrings.merge(cb.limit(ix+len).position(ix), 1, Integer::sum);
我们使用返回值来检测merge
操作是否在映射中创建了一个新的关联,只有当结果为1时才会出现这种情况。在这种情况下,我们之后不能修改缓冲区,因此,创建一个新的
if(num == 1) cb = CharBuffer.wrap(s);
然后,我们使用结果来跟踪最高出现次数
if(num > most) most = num;
循环后的最后一步很简单。我们已经拥有最高的出现次数,过滤映射以保留具有匹配编号的条目(可能存在平局)并创建一个新映射,现在将缓冲区转换为 String
实例,就像我们所做的那样。不想保留对原始 String
的引用,而且它只影响少数结果子字符串。
final int mostOccurences = most; // needed because most is not “effectively final”
return subStrings.entrySet().stream()
.filter(e -> e.getValue() == mostOccurences)
.collect(Collectors.toMap(e -> e.getKey().toString(), Map.Entry::getValue));
关于检查非常非常长的字符串时发生 Java 堆空间错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48386176/
我已经使用 vue-cli 两个星期了,直到今天一切正常。我在本地建立这个项目。 https://drive.google.com/open?id=0BwGw1zyyKjW7S3RYWXRaX24tQ
您好,我正在尝试使用 python 库 pytesseract 从图像中提取文本。请找到代码: from PIL import Image from pytesseract import image_
我的错误 /usr/bin/ld: errno: TLS definition in /lib/libc.so.6 section .tbss mismatches non-TLS reference
我已经训练了一个模型,我正在尝试使用 predict函数但它返回以下错误。 Error in contrasts<-(*tmp*, value = contr.funs[1 + isOF[nn]])
根据Microsoft DataConnectors的信息我想通过 this ODBC driver 创建一个从 PowerBi 到 PostgreSQL 的连接器使用直接查询。我重用了 Micros
我已经为 SoundManagement 创建了一个包,其中有一个扩展 MediaPlayer 的类。我希望全局控制这个变量。这是我的代码: package soundmanagement; impo
我在Heroku上部署了一个应用程序。我正在使用免费服务。 我经常收到以下错误消息。 PG::Error: ERROR: out of memory 如果刷新浏览器,就可以了。但是随后,它又随机发生
我正在运行 LAMP 服务器,这个 .htaccess 给我一个 500 错误。其作用是过滤关键字并重定向到相应的域名。 Options +FollowSymLinks RewriteEngine
我有两个驱动器 A 和 B。使用 python 脚本,我在“A”驱动器中创建一些文件,并运行 powerscript,该脚本以 1 秒的间隔将驱动器 A 中的所有文件复制到驱动器 B。 我在 powe
下面的函数一直返回这个错误信息。我认为可能是 double_precision 字段类型导致了这种情况,我尝试使用 CAST,但要么不是这样,要么我没有做对...帮助? 这是错误: ERROR: i
这个问题已经有答案了: Syntax error due to using a reserved word as a table or column name in MySQL (1 个回答) 已关闭
我的数据库有这个小问题。 我创建了一个表“articoli”,其中包含商品的品牌、型号和价格。 每篇文章都由一个 id (ID_ARTICOLO)` 定义,它是一个自动递增字段。 好吧,现在当我尝试插
我是新来的。我目前正在 DeVry 在线学习中级 C++ 编程。我们正在使用 C++ Primer Plus 这本书,到目前为止我一直做得很好。我的老师最近向我们扔了一个曲线球。我目前的任务是这样的:
这个问题在这里已经有了答案: What is an undefined reference/unresolved external symbol error and how do I fix it?
我的网站中有一段代码有问题;此错误仅发生在 Internet Explorer 7 中。 我没有在这里发布我所有的 HTML/CSS 标记,而是发布了网站的一个版本 here . 如您所见,我在列中有
如果尝试在 USB 设备上构建 node.js 应用程序时在我的树莓派上使用 npm 时遇到一些问题。 package.json 看起来像这样: { "name" : "node-todo",
在 Python 中,您有 None单例,在某些情况下表现得很奇怪: >>> a = None >>> type(a) >>> isinstance(a,None) Traceback (most
这是我的 build.gradle (Module:app) 文件: apply plugin: 'com.android.application' android { compileSdkV
我是 android 的新手,我的项目刚才编译和运行正常,但在我尝试实现抽屉导航后,它给了我这个错误 FAILURE: Build failed with an exception. What wen
谁能解释一下?我想我正在做一些非常愚蠢的事情,并且急切地等待着启蒙。 我得到这个输出: phpversion() == 7.2.25-1+0~20191128.32+debian8~1.gbp108
我是一名优秀的程序员,十分优秀!