Java 这两种基于字符串的算法的复杂性是什么?

Java 这两种基于字符串的算法的复杂性是什么?,java,performance,algorithm,big-o,time-complexity,Java,Performance,Algorithm,Big O,Time Complexity,我编写了这两个算法来检查字符串中的重复字符(ABBC,AAAC)。第一种方法使用hashset数据结构,而第二种方法完全依赖于迭代 算法1 String s = "abcdefghijklmnopqrstuvwxxyz"; public boolean isUnique(String s) { Set<Character> charSet = new HashSet<Character>(); for(int i=0; i<s.

我编写了这两个算法来检查字符串中的重复字符(ABBC,AAAC)。第一种方法使用hashset数据结构,而第二种方法完全依赖于迭代

算法1

String s = "abcdefghijklmnopqrstuvwxxyz";

public boolean isUnique(String s) {

        Set<Character> charSet = new HashSet<Character>();

        for(int i=0; i<s.length(); i++) {
            if(charSet.contains(s.charAt(i))) {
                return false;   
            } 
            charSet.add(s.charAt(i));
        }   
        return true;
}
String s=“abcdefghijklmnopqrstuvxxyz”;
公共布尔值是唯一的(字符串s){
Set charSet=new HashSet();

对于(int i=0;i假设charAt方法在O(1)时间内运行,第一个算法是O(N),第二个是O(N^2)。对于所有输入,线性时间算法不应比二次算法快。在一定的N(可能是数百万)后,它将比二次算法快

例如:

void funcA(int n){
    for (int i = 0; i < n; i++){
        for (int j = 0; j < 10000; j++){
            int k = i + j;
        }
    }
}


void funcB(int n){
    for (int i = 0; i < n; i++){
        for (int j = 0; j < n; j++){
            int k = i + j;
        }
    }
}
void funcA(int n){
对于(int i=0;i

尽管funcA是线性的,funcB是二次的,但很容易看出,在n<10000的情况下,funcB比funcA快。在您的情况下,哈希集需要时间来计算哈希,因此对于特定大小的输入可能会慢一些。

假设charAt方法在O(1)时间内运行,第一个算法是O(n),第二个算法是O(n^2)。对于所有输入,线性时间算法不应比二次算法快。在一定的N(可能是数百万)后,它将比二次算法快

例如:

void funcA(int n){
    for (int i = 0; i < n; i++){
        for (int j = 0; j < 10000; j++){
            int k = i + j;
        }
    }
}


void funcB(int n){
    for (int i = 0; i < n; i++){
        for (int j = 0; j < n; j++){
            int k = i + j;
        }
    }
}
void funcA(int n){
对于(int i=0;i
尽管funcA是线性的,funcB是二次的,但很容易看出,在n<10000的情况下,funcB将比funcA快。在您的情况下,哈希集需要时间来计算哈希,因此对于特定大小的输入可能会慢一些。

当使用O()表示法时,您会忽略常量,这意味着O(n)==(10^10*n)。因此,当O(n^2)>O(n)渐近为真,对于较小的n值不一定为真。 在您的例子中,想象一下,调整哈希集后面的数组的大小可能比迭代输入更耗时。

当使用O()表示法时,您忽略常量,这意味着O(n)==(10^10*n)。因此,虽然O(n^2)>O(n)渐近为真,但对于较小的n值,它不一定为真。
在您的情况下,想象一下,调整哈希集后面的数组的大小可能比迭代输入更耗时。

例如,如果您将自己限制为英语字符(a-z),则测试数据会出现问题,如果字符串长度>26,则保证有重复的字符串。在特定示例中,您提供了字符串
“abcdefghijklmnopqrstuvwxxyz”
被排序,重复的元素
x
在末尾被找到。因此,迭代数组查找速度更快,因为在继续解析字符串时,在构建
哈希集时会有开销

更好的测试方法是使用随机生成的大尺寸整数序列和大的最大值(例如
Long.max\u值

下面是一个测试,它反驳了您关于数组搜索速度更快的断言。请运行几次并亲自查看。或者您可以从1000次运行中取平均值,以此类推:

public class FindDuplicatesTest {

  public static final String s = generateRandomString(100000);

  private static String generateRandomString(int numChars) {
    Random random = new Random();
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < numChars; i++) {
      int codePoint = random.nextInt(65536);
      sb.append(Character.toChars(codePoint));
    }
    return sb.toString();
  }

  public boolean isUnique(String s) {

    Set<Character> charSet = new HashSet<Character>();

    for (int i = 0; i < s.length(); i++) {
      if (charSet.contains(s.charAt(i))) {
        return false;
      }
      charSet.add(s.charAt(i));
    }
    return true;
  }

  public boolean isUnique2(String s) {

    for (int i = 0; i < s.length() - 1; i++) {
      for (int j = i + 1; j < s.length(); j++) {
        if (s.charAt(i) == s.charAt(j)) {
          return false;
        }
      }
    }
    return true;
  }

  public static void main(String[] args) {
    FindDuplicatesTest app = new FindDuplicatesTest();

    long start = System.nanoTime();
    boolean result = app.isUnique(s);
    long stop = System.nanoTime();
    System.out.println(result);

    System.out.println("HashSet Search Time: " + (stop - start));

    start = System.nanoTime();
    result = app.isUnique2(s);
    stop = System.nanoTime();
    System.out.println(result);

    System.out.println("Array Search Time: " + (stop - start));

  }
}
公共类FindDuplicatesTest{
公共静态最终字符串s=GeneratorDomainString(100000);
专用静态字符串生成器动态字符串(int numChars){
随机=新随机();
StringBuilder sb=新的StringBuilder();
对于(int i=0;i
您的测试数据有问题,例如,如果您将自己限制为英语字符(a-z),则如果字符串长度>26,则保证有重复的字符串。在特定示例中,您提供了字符串
“abcdefghijklmnopqrstuvxxyz”
被排序,重复的元素
x
在末尾被找到。因此,迭代数组查找速度更快,因为在继续解析字符串时,在构建
哈希集时会有开销

更好的测试方法是使用随机生成的大尺寸整数序列和大的最大值(例如
Long.max\u值

下面是一个测试,它反驳了您关于数组搜索速度更快的断言。请运行几次并亲自查看。或者您可以从1000次运行中取平均值,以此类推:

public class FindDuplicatesTest {

  public static final String s = generateRandomString(100000);

  private static String generateRandomString(int numChars) {
    Random random = new Random();
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < numChars; i++) {
      int codePoint = random.nextInt(65536);
      sb.append(Character.toChars(codePoint));
    }
    return sb.toString();
  }

  public boolean isUnique(String s) {

    Set<Character> charSet = new HashSet<Character>();

    for (int i = 0; i < s.length(); i++) {
      if (charSet.contains(s.charAt(i))) {
        return false;
      }
      charSet.add(s.charAt(i));
    }
    return true;
  }

  public boolean isUnique2(String s) {

    for (int i = 0; i < s.length() - 1; i++) {
      for (int j = i + 1; j < s.length(); j++) {
        if (s.charAt(i) == s.charAt(j)) {
          return false;
        }
      }
    }
    return true;
  }

  public static void main(String[] args) {
    FindDuplicatesTest app = new FindDuplicatesTest();

    long start = System.nanoTime();
    boolean result = app.isUnique(s);
    long stop = System.nanoTime();
    System.out.println(result);

    System.out.println("HashSet Search Time: " + (stop - start));

    start = System.nanoTime();
    result = app.isUnique2(s);
    stop = System.nanoTime();
    System.out.println(result);

    System.out.println("Array Search Time: " + (stop - start));

  }
}
公共类FindDuplicatesTest{
公共静态最终字符串s=GeneratorDomainString(100000);
专用静态字符串生成器动态字符串(int numChars){
随机=新兰德