Java 不同子串的串联
问题-按字典顺序排列给定字符串的所有不同子字符串并将它们连接起来。打印连接字符串的第k个字符。可以保证给定的K值是有效的,即存在第K个字符 输入格式 第一行将包含一个数字T,即测试用例的数量。 每个测试用例的第一行将包含一个包含字符(a)的字符串−z) 第二行将包含一个数字K 输出格式 打印第k个字符(字符串索引为1) 约束条件 1.≤T≤5. 1.≤长度≤105 K将是一个适当的整数 样本输入#00 样本输出#00 说明#00 按字典顺序排列的子字符串如下 a、 ac,b,ba,bac,c,d,db,dba,dbac 在连接它们时,我们得到 aacbbabaccddbdbac 这个字符串中的第三个字符是c,因此是答案 这是我的代码:Java 不同子串的串联,java,string,out-of-memory,substring,concatenation,Java,String,Out Of Memory,Substring,Concatenation,问题-按字典顺序排列给定字符串的所有不同子字符串并将它们连接起来。打印连接字符串的第k个字符。可以保证给定的K值是有效的,即存在第K个字符 输入格式 第一行将包含一个数字T,即测试用例的数量。 每个测试用例的第一行将包含一个包含字符(a)的字符串−z) 第二行将包含一个数字K 输出格式 打印第k个字符(字符串索引为1) 约束条件 1.≤T≤5. 1.≤长度≤105 K将是一个适当的整数 样本输入#00 样本输出#00 说明#00 按字典顺序排列的子字符串如下 a、 ac,b,ba,bac,c,d
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
public class Solution
{
public static void gen(String str,int k)
{
int i,c;ArrayList<String>al=new ArrayList<String>();
for(c=0;c<str.length();c++)
{
for(i=1;i<=str.length()-c;i++)
{
String sub = str.substring(c,c+i);
al.add(sub);
}
}
HashSet hs = new HashSet();
hs.addAll(al);
al.clear();
al.addAll(hs);
String[] res = al.toArray(new String[al.size()]);
Arrays.sort(res);
StringBuilder sb= new StringBuilder();
for(String temp:res)
{
sb.append(temp);
}
String s = sb.toString();
System.out.println(s.charAt(k-1));
}
public static void main(String[] args)
{
Scanner sc = new Scanner (System.in);
int t = Integer.parseInt(sc.nextLine());
while((t--)>0)
{
String str = sc.nextLine();
int k = Integer.parseInt(sc.nextLine());
gen(str,k);
}
}
}
import java.io.*;
导入java.util.*;
导入java.text.*;
导入java.math.*;
导入java.util.regex.*;
公共类解决方案
{
公共静态void gen(字符串str,int k)
{
int i,c;ArrayListal=新的ArrayList();
对于(c=0;c您的内存不足。您可以通过使用-Xms256m-Xmx1024启动JVM来增加JVM正在使用的内存,并且可以尝试一些优化
public static void gen(String str, int k) {
int i, c;
//Adding directly to the Set prevents a larger list because you remove the duplicates
Set<String> set = new TreeSet<String>();
for (c = 0; c < str.length(); c++) {
for (i = 1; i <= str.length() - c; i++) {
String sub = str.substring(c, c + i);
set.add(sub);
}
}
//TreeSet already orders by the String comparator
StringBuilder sb = new StringBuilder();
for (String temp : set) {
sb.append(temp);
if(sb.length()>k){
break;
}
}
String s = sb.toString();
System.out.println(s.charAt(k - 1));
}
publicstaticvoidgen(stringstr,intk){
int i,c;
//直接添加到集合中可以防止出现更大的列表,因为您删除了重复项
Set=新树集();
对于(c=0;c
[EDIT]增加了小的性能提升。试试看它是否更快,我没有看StringBuilder.length()的性能查看它是否会改善或减少。内存不足。可以通过使用-Xms256m-Xmx1024启动JVM来增加JVM正在使用的内存,并且可以尝试一些优化
public static void gen(String str, int k) {
int i, c;
//Adding directly to the Set prevents a larger list because you remove the duplicates
Set<String> set = new TreeSet<String>();
for (c = 0; c < str.length(); c++) {
for (i = 1; i <= str.length() - c; i++) {
String sub = str.substring(c, c + i);
set.add(sub);
}
}
//TreeSet already orders by the String comparator
StringBuilder sb = new StringBuilder();
for (String temp : set) {
sb.append(temp);
if(sb.length()>k){
break;
}
}
String s = sb.toString();
System.out.println(s.charAt(k - 1));
}
publicstaticvoidgen(stringstr,intk){
int i,c;
//直接添加到集合中可以防止出现更大的列表,因为您删除了重复项
Set=新树集();
对于(c=0;c
[EDIT]增加了小的性能提升。试试看它是否更快,我没有看StringBuilder.length()的性能查看它是否会改善或减少。内存不足。可以通过使用-Xms256m-Xmx1024启动JVM来增加JVM正在使用的内存,并且可以尝试一些优化
public static void gen(String str, int k) {
int i, c;
//Adding directly to the Set prevents a larger list because you remove the duplicates
Set<String> set = new TreeSet<String>();
for (c = 0; c < str.length(); c++) {
for (i = 1; i <= str.length() - c; i++) {
String sub = str.substring(c, c + i);
set.add(sub);
}
}
//TreeSet already orders by the String comparator
StringBuilder sb = new StringBuilder();
for (String temp : set) {
sb.append(temp);
if(sb.length()>k){
break;
}
}
String s = sb.toString();
System.out.println(s.charAt(k - 1));
}
publicstaticvoidgen(stringstr,intk){
int i,c;
//直接添加到集合中可以防止出现更大的列表,因为您删除了重复项
Set=新树集();
对于(c=0;c
[EDIT]增加了小的性能提升。试试看它是否更快,我没有看StringBuilder.length()的性能查看它是否会改善或减少。内存不足。可以通过使用-Xms256m-Xmx1024启动JVM来增加JVM正在使用的内存,并且可以尝试一些优化
public static void gen(String str, int k) {
int i, c;
//Adding directly to the Set prevents a larger list because you remove the duplicates
Set<String> set = new TreeSet<String>();
for (c = 0; c < str.length(); c++) {
for (i = 1; i <= str.length() - c; i++) {
String sub = str.substring(c, c + i);
set.add(sub);
}
}
//TreeSet already orders by the String comparator
StringBuilder sb = new StringBuilder();
for (String temp : set) {
sb.append(temp);
if(sb.length()>k){
break;
}
}
String s = sb.toString();
System.out.println(s.charAt(k - 1));
}
publicstaticvoidgen(stringstr,intk){
int i,c;
//直接添加到集合中可以防止出现更大的列表,因为您删除了重复项
Set=新树集();
对于(c=0;c
[编辑]增加了小的性能提升。试试看它是否会更快,我没有查看StringBuilder.length()的性能,看它是否会提高或降低。根据给定的限制(最多105个字符),您不应该出现内存不足问题。也许您是在测试非常大的字符串
如果你有,这里有一些地方你在浪费内存:
- 填充集合后,将其复制到列表中。这意味着子字符串集合的两个副本,而您将不再使用集合
- 将列表复制到数组后,现在子字符串集合有三个副本,尽管不再使用该列表
- 现在您创建了一个
StringBuilder
,并将所有子字符串放入其中。但了解整个连接字符串并不是很有趣。我们只需要其中的一个字符,那么为什么还要将连接放在内存中呢?此外,在上面所有浪费的副本中,至少您没有复制子字符串本身。但是现在如果您将它们附加到StringBuilder
,您将创建它们的副本。这将是一个非常长的字符串
- 然后使用
toString()
将StringBuilder
的内容复制到一个新字符串中。这将创建一个非常大的连接字符串的副本(我们已经说过我们实际上不需要)
您已经得到了一个很好的建议,即使用树集
并直接填充它,而不是创建列表、集合和排序列表。下一步是从该集合中提取正确的字符,而不实际保留连接的字符串
因此,假设您的集合被称为set
:
Iterator<String> iter = set.iterator();
int lengthSoFar = 0;
String str = null;
while ( lengthSoFar < k && iter.hasNext() ) {
str = iter.next(); // Got the next substring;
lengthSoFar += str.length();
}
// At this point we have the substring where we expect the k'th
// character to be.
System.out.println( str.charAt( k - lengthSoFar + str.length() - 1 );
Iterator iter=set.Iterator();
int lengthSoFar=0;
字符串str=null;
while(长度小于k&&iter.hasNext()){
str=iter.next();//获取下一个子字符串;
长度等于长度();
}
//在这一点上,我们有一个子串