Java 如何比较两个字符串以找到公共子字符串
我在编译时由于超时错误而被终止。请帮帮我 给定两个字符串,确定它们是否共享一个公共子字符串。子字符串可以小到一个字符 例如,单词“a”、“and”、“art”共享公共子字符串“a”。单词“be”和“cat”不共享子字符串 输入格式 第一行包含一个整数,即测试用例数 以下几对线如下所示: 第一行包含字符串s1。 第二行包含字符串s2 输出格式 对于每对字符串,返回YES或NO 我的java代码Java 如何比较两个字符串以找到公共子字符串,java,string,Java,String,我在编译时由于超时错误而被终止。请帮帮我 给定两个字符串,确定它们是否共享一个公共子字符串。子字符串可以小到一个字符 例如,单词“a”、“and”、“art”共享公共子字符串“a”。单词“be”和“cat”不共享子字符串 输入格式 第一行包含一个整数,即测试用例数 以下几对线如下所示: 第一行包含字符串s1。 第二行包含字符串s2 输出格式 对于每对字符串,返回YES或NO 我的java代码 public static void main(String args[]) { String
public static void main(String args[])
{
String s1,s2;
int n;
Scanner s= new Scanner(System.in);
n=s.nextInt();
while(n>0)
{
int flag = 0;
s1=s.next();
s2=s.next();
for(int i=0;i<s1.length();i++)
{
for(int j=i;j<s2.length();j++)
{
if(s1.charAt(i)==s2.charAt(j))
{
flag=1;
}
}
}
if(flag==1)
{
System.out.println("YES");
}
else
{
System.out.println("NO");
}
n--;
}
}
publicstaticvoidmain(字符串参数[])
{
字符串s1、s2;
int n;
扫描仪s=新的扫描仪(System.in);
n=s.nextInt();
而(n>0)
{
int标志=0;
s1=s.next();
s2=s.next();
对于(int i=0;i,解决这个问题涉及两个概念。
-理解单个字符是有效的子字符串。
-推断我们只需要知道这两个字符串有一个公共的子字符串-我们不需要知道这个子字符串是什么
因此,解决这个问题的关键是确定两个字符串是否共享一个公共字符
为此,我们创建了两个集合a和b,其中每个集合都包含其命名的字符串中出现的唯一字符
因为集合26不存储重复的值,所以我们知道集合的大小永远不会超过英文字母表中的字母
此外,这些集合的小尺寸使得查找交点非常快
如果两个集合的交集为空,则在新行上打印“否”;如果两个集合的交集不为空,则我们知道字符串和共享一个或多个公共字符,并在新行上打印“是”
在代码中,它可能看起来像这样
import java.util.*;
公共类解决方案{
静态设置a;
静态组b;
公共静态void main(字符串[]args){
扫描仪扫描=新扫描仪(System.in);
int n=scan.nextInt();
对于(int i=0;i
超时的原因可能是:要比较两个长度分别为1.000.000个字符的字符串,代码始终需要进行1.000.000*1.000.000的比较
有一种更快的算法,只需要2*1.000.000个比较。您应该使用更快的算法。其基本思想是:
- 对于s1中的每个字符:将字符添加到集合中(这是第一个百万)
- 对于s2中的每个字符:测试步骤1中的集合是否包含该字符,如果包含,则立即返回“是”(这是第二个百万)
Java已经提供了满足所有需要的位集数据类型。它的使用方式如下:
BitSet seenInS1 = new BitSet();
seenInS1.set('x');
seenInS1.get('x');
由于您担心执行时间,如果它们给您一个预期的字符范围(例如'a'
到'z'
),您可以像这样非常有效地解决它:
BitSet seenInS1 = new BitSet();
seenInS1.set('x');
seenInS1.get('x');
导入java.util.array;
导入java.util.Scanner;
公务舱{
final static char HIGHEST_char='z';//如果不确定,请使用Character.MAX_值。
公共静态void main(最终字符串[]args){
最终扫描仪=新扫描仪(System.in);
最终布尔值[]字符SEEN=新布尔值[最高字符+1];
主回路:
for(int-word=Integer.parseInt(scanner.nextLine());word>0;word--){
数组。填充(characterSeen,false);
最后一个字符串word1=scanner.nextLine();
for(int i=0;i
它使用快速数组而不是较慢的集合,并且在整个程序运行过程中只创建一个非字符串
对象(而不是扫描器
)。它也以O(n)时间而不是O(n²)时间运行
唯一比数组快的可能是
如果您想完全过火,您还可以通过以下方式加快速度:
- 通过直接与可重用的
字节[]
缓冲区一起使用,跳过创建扫描仪
和所有那些字符串
对象
- 通过创建自己的非常快速的
int
解析器,跳过必须花费时间检查并正确处理第一行上的负数和无效输入的标准过程,该解析器仅假设它获取有效的非负数int
的数字,然后是换行
解决这个问题有不同的方法,但在线性时间内解决这个问题有点棘手。
不过,这个问题可以在线性时间内解决。只需以更巧妙的方式应用KMP算法即可
假设您有2个字符串。首先找到两个字符串的长度。假设字符串1
的长度大于字符串2
。将字符串1
作为您的文本,将字符串2
作为您的模式。如果字符串的长度为n
,则将
public String twoStrings(String sOne, String sTwo) {
if (sOne.equals(sTwo)) {
return "YES";
}
Set<Character> charSetOne = new HashSet<Character>();
for (Character c : sOne.toCharArray())
charSetOne.add(c);
Set<Character> charSetTwo = new HashSet<Character>();
for (Character c : sTwo.toCharArray())
charSetTwo.add(c);
charSetOne.retainAll(charSetTwo);
if (charSetOne.size() > 0) {
return "YES";
}
return "NO";
}
def twoStrings(s1, s2):
flag = False
for x in s1:
if x in s2:
flag = True
if flag == True:
return "YES"
else:
return "NO"
if __name__ == '__main__':
q = 2
text = [("hello","world"), ("hi","world")]
for q_itr in range(q):
s1 = text[q_itr][0]
s2 = text[q_itr][1]
result = twoStrings(s1, s2)
print(result)
static String twoStrings(String s1, String s2) {
for (Character ch : s1.toCharArray()) {
if (s2.indexOf(ch) > -1)
return "YES";
}
return "NO";
}
static String twoStrings(String s1, String s2) {
String result="NO";
Set<Character> set1 = new HashSet<Character>();
for (char s : s1.toCharArray()){
set1.add(s);
}
for(int i=0;i<s2.length();i++){
if(set1.contains(s2.charAt(i))){
result = "YES";
break;
}
}
return result;
}