Java 查找字符串的所有不同子字符串
大家好,我有一个家庭作业问题,它要求我找到一个字符串的所有不同的子字符串。 我已经实现了一个方法,它将告诉您字符串的所有子字符串,但我需要一个帮助,以弄清楚如何不将一个已经被计算过一次的子字符串计算为子字符串,因为赋值是为了找到不同的子字符串Java 查找字符串的所有不同子字符串,java,string,substring,Java,String,Substring,大家好,我有一个家庭作业问题,它要求我找到一个字符串的所有不同的子字符串。 我已经实现了一个方法,它将告诉您字符串的所有子字符串,但我需要一个帮助,以弄清楚如何不将一个已经被计算过一次的子字符串计算为子字符串,因为赋值是为了找到不同的子字符串 public int printSubstrings1(int length) { for(int i=0; i<text.length()-length+1;i++) { String sub = text.sub
public int printSubstrings1(int length)
{
for(int i=0; i<text.length()-length+1;i++)
{
String sub = text.substring(i,length+i);
counter++;
}
return counter;
}
public int-printSubstrings1(int-length)
{
对于(int i=0;i在数组中插入任何新的子字符串,并检查它是否已经可用,不要将其添加到数组中,否则执行。完成后,循环遍历数组并打印出不同的子字符串
要检查数组中是否存在元素,请创建一个以数组和值为参数的函数。如果找到,它将在数组中循环查找该值返回true。循环外返回false
e、 g
publicstaticboolean(字符串目标,字符串[]arr)
{
对于(int i=0;i
下面是一个带有
public int-printSubstrings1(int-length){
Set=newhashset();
对于(int i=0;i
公共数组列表getAllUniqueSubset(字符串str){
ArrayList集合=新的ArrayList();
对于(int i=0;i
此算法仅使用Z函数/Z算法
对于单词的每个前缀i,将其反转并在其上执行z_函数。
以i
结尾的新的不同子字符串的数量是(前缀的长度)-(z_函数数组中的最大值)
。
伪代码如下所示:
string s; cin >> s;
int sol = 0
foreach i to s.size()-1
string x = s.substr( 0 , i+1 );
reverse( x.begin() , x.end() );
vector<int> z = z_function( x );
//this works too
//vector<int> z = prefix_functionx(x);
int mx = 0;
foreach j to x.size()-1
mx = max( mx , z[j] );
sol += (i+1) - mx;
cout << sol;
字符串s;cin>>s;
int sol=0
foreach i至s.尺寸()-1
字符串x=s.substr(0,i+1);
相反(x.开始(),x.结束());
向量z=z_函数(x);
//这也行
//向量z=前缀函数x(x);
int mx=0;
foreach j到x.尺寸()-1
mx=最大值(mx,z[j]);
溶胶+=(i+1)-mx;
cout我遵循了这一点。确认了quora中类似答案的内容
解决方案包括构造后缀数组,然后根据最长的公共前缀查找不同子字符串的数量
这里的一个关键观察是:
如果您查看字符串的每个后缀的前缀,您已经覆盖了该字符串的所有子字符串
让我们举一个例子:香蕉
后缀是:0)香蕉1)安娜2)娜娜3)安娜4)娜娜5)A
如果我们对上面的后缀集进行排序,那么检查前缀会容易得多,因为我们可以很容易地跳过重复的前缀
排序后的后缀集:5)A 3)ANA 1)ANANA 0)BANANA 4)NA 2)NANA
从现在起,
LCP=两个字符串的最长公共前缀
初始化
ans=长度(第一个后缀)=长度(“A”)=1
现在考虑连续的一对后缀,即[a,aN],[ANA,ANANA ],[ANANA,香蕉]等。
我们可以看到,LCP(“A”,“ANA”)=“A”
所有不属于公共前缀的字符都构成一个不同的子字符串。在上述情况下,它们是“N”和“a”。因此应将它们添加到ans中
所以我们有,12个ans+=长度(,ANA”)-LCP(,A,ANA)ans=ans+3-1=ans+2=3
对下一对连续后缀执行相同操作:[“ANA”,“ANANA”]
1 2 3 4 LCP(“ANA”,“ANANA”)=“ANA”。ans+=长度(“ANANA”)-长度(LCP)=>ans=ans+5-3=>ans=3+2=5
同样,我们有:
1 2 LCP(“ANANA”,“BANANA”)=0 ans=ans+长度(“BANANA”)-0=11
1 2 LCP(“香蕉”、“NA”)=0 ans=ans+长度(“NA”)-0=13
1 2 LCP(“NA”,“NANA”)=2 ans=ans+长度(“NANA”)-2=15
因此字符串“BANANA”的不同子字符串的数量等于15。有两种方法可以做到这一点,不确定您的老师是否允许,但我将使用哈希集来实现唯一性
不使用“substring()”:
void uniquesubstring(字符串测试){
HashSetsubstring=newlinkedhashset();
char[]a=test.toCharArray();
对于(int i=0;i 对于(int k=i;k)将它们放在一个“集合是不包含重复元素的集合”好主意,谢谢你说的set是指数组。那么我该如何检查字符串是否已经存在。因为数组在它的类中没有.contains方法。你能提供set的示例吗。例如,java.util.HashSet
。如果你的数组有未初始化的单元格,这将抛出一个NullPointerException
你的答案如果你能添加一些评论,会更有帮助
public int printSubstrings1(int length) {
Set<String> set = new HashSet<String>();
for(int i=0; i < text.length() - length + 1; i++) {
String sub = text.substring(i,length+i);
set.add(sub);
}
for (String str : set) {
System.out.println(str);
}
return set.size();
}
public ArrayList<String> getAllUniqueSubset(String str) {
ArrayList<String> set = new ArrayList<String>();
for (int i = 0; i < str.length(); i++) {
for (int j = 0; j < str.length() - i; j++) {
String elem = str.substring(j, j + (i+1));
if (!set.contains(elem)) {
set.add(elem);
}
}
}
return set;
}
string s; cin >> s;
int sol = 0
foreach i to s.size()-1
string x = s.substr( 0 , i+1 );
reverse( x.begin() , x.end() );
vector<int> z = z_function( x );
//this works too
//vector<int> z = prefix_functionx(x);
int mx = 0;
foreach j to x.size()-1
mx = max( mx , z[j] );
sol += (i+1) - mx;
cout << sol;
void uniqueSubStrings(String test) {
HashSet < String > substrings = new LinkedHashSet();
char[] a = test.toCharArray();
for (int i = 0; i < test.length(); i++) {
substrings.add(a[i] + "");
for (int j = i + 1; j < test.length(); j++) {
StringBuilder sb = new StringBuilder();
for (int k = i; k <= j; k++) {
sb.append(a[k]);
}
substrings.add(sb.toString());
}
}
System.out.println(substrings);
void uniqueSubStringsWithBuiltIn(String test) {
HashSet<String> substrings = new LinkedHashSet();
for(int i=0; i<test.length();i++) {
for(int j=i+1;j<test.length()+1;j++) {
substrings.add(test.substring(i, j));
}
}
System.out.println(substrings);}