您好,感谢您的阅读。我正在做家庭作业。我创建了一个方法来比较字符串,看看是否是另一个字符串的子字符串。我知道已经有一个内置的方法来做到这一点。作业不允许我使用它们。无论如何,下面的代码正在运行。
我必须使用Big-O表示法分析算法的复杂性。从我所看到的外部循环以线性时间运行,因为它只运行字符串长度的次数。因此:O(n)
内循环是不同的,它可能会或可能不会发生,如果它发生,它可能在第二个字符串的长度之前完成,这是它的输入。因此:O(logn)
所以在我看来,复杂性是O(n * logn)。这是否简化为O(n)还是保持其当前形式?或者我错了内循环为O(logn)?
import java.util.Scanner;
public class HW3q6 {
public static void main(String[] args) {
Scanner userInput = new Scanner( System.in );
System.out.println("Please enter the first string: ");
char[] charArray1 = userInput.nextLine().toUpperCase().toCharArray();
System.out.println("Please enter the second string: ");
char[] charArray2 = userInput.nextLine().toUpperCase().toCharArray();
System.out.println("The second string is a substring of the first: " + subString(charArray1, charArray2));
}
private static boolean subString(char[] charArray1, char[] charArray2) {
int counter = 0;
for (int i = 0; i < (charArray1.length + 1) - charArray2.length ; i++) {
if (charArray1[i] == charArray2[0]) {
for (int n = 0; n < charArray2.length; n++) {
if (charArray1[i+n] == charArray2[n]) {
counter++;
}
}
if (counter == charArray2.length) {
return true;
} else
counter = 0;
}
}
return false;
}
}
答案 0 :(得分:2)
内部循环不是logN。 Big O衡量最坏情况的复杂性。据我所知,你的代码中,内部循环可以运行N(字符串2的长度)次。说明如下:
假设你有两个字符串,例如aaaaaaa和aaac,外部循环将匹配第一个字符,你将进入内部循环,检查每个字符,然后实现错误。然后外部循环将再次匹配第二个字符串的开头与第一个字符串的第二个字符,然后您将再次检查第二个字符串中的所有字符实现false。这将是第一个字符串的M个字符,以及第二个字符串的N个字符,产生O(MN)算法,其中O(N ^ 2)考虑M = c * N,其中c是常数。 / p>
希望这会有所帮助。
答案 1 :(得分:2)
我看到你已经接受了答案。但您的时间复杂度实际上是O(m*(n-m+1))
,其中m
是较小的文本,n
是较大的文本。要看到这种区别很重要,只需为m和n选择一些数字并进行计算。如果论证是关于Big-O表示法,那么O(mn)
和O(m*(n-m+1))
之间的O(mn) > O(m*(n-m+1))
之间没有太大区别,那么你可以说复杂性是O(n^2)
,因为O(n^2) > O(mn) > O(m*(n-m+1))
。此外,您的代码未进行正确的错误检查,请参阅Geekviewpoint.com on string matching for some hints.
答案 2 :(得分:1)
O(NlogN)
不等同于O(N)
但是,您认为内循环为O(logN)
的原因是错误的。它“可能发生或可能不发生”的事实并不一定使它成为O(logN)
。例如,如果内环发生“平均大约一半的时间”,那么贡献可能是C * 1/2 N
;即O(N)
。
我现在没有时间详细分析代码,但似乎需要查看最佳,平均和最差的案例复杂性。
(例如,快速排序算法的经典形式,平均O(NlogN)
,但最差情况复杂度为O(N^2)
。)
答案 3 :(得分:1)
正如mellamokb指出的那样,内循环仍在线性时间内运行。因此,您的算法整体将为O(mn),其中m和n是两个字符串的长度。