【发布时间】:2013-01-30 22:40:02
【问题描述】:
您好,感谢您的阅读。我正在做家庭作业。我创建了一种与字符串进行比较的方法,以查看一个是否是另一个的子字符串。我知道已经有一个内置的方法可以做到这一点。作业不允许我使用它们。无论如何,下面的代码是有效的。
我必须使用 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;
}
}
【问题讨论】:
-
如果一个循环可能提前退出,它仍然是
O(n)。它不会变成O(log n)。复杂性O(log n)专门指将集合大小重复减小某个因素,即搜索二叉树,或在排序数组中进行二分搜索。 -
啊,因为我们正在考虑最坏的情况,对吧?来自用户的第二个输入可能和第一个一样长,因此它被认为与 n 一样大。
-
是的,它是关于可证明的上限。即使您知道在实践中每次迭代的内部循环运行次数可能远少于
n次,但您通常只能证明它在最坏的情况下是n。 -
wlog,假设字符串长度为 m,n 和 m
-
感谢您的所有回答。它似乎是 O(n^2) 但是我仍然有一个犹豫。如果用户输入与第一个字符串一样长的第二个字符串(要比较的子字符串),则外部循环将只运行一次。如果用户不输入任何内容,则内部循环根本不会运行。编辑:我看到这意味着 O(mn) 是答案。这是有道理的,但教科书中没有 m*n 的例子。 Edit2:Rivu 指出这简化为 O(n^2)
标签: java algorithm data-structures big-o