interviewstreet.com - 字符串相似度

时间:2012-07-13 22:49:55

标签: java

我正在尝试在interviewstreet.com上解决字符串相似性问题。我的代码适用于7/10个案例(超过了其他3个案例的时间限制)。

这是我的代码 -

public class Solution {

    public static void main(String[] args) {

        Scanner user_input = new Scanner(System.in);

        String v1 = user_input.next();
        int number_cases = Integer.parseInt(v1);

        String[] cases = new String[number_cases];
        for(int i=0;i<number_cases;i++)
            cases[i] = user_input.next();

        for(int k=0;k<number_cases;k++){
            int similarity = solve(cases[k]);   
            System.out.println(similarity);
        }
    }

    static int solve(String sample){

        int len=sample.length();
        int sim=0;
        for(int i=0;i<len;i++){
            for(int j=i;j<len;j++){
                if(sample.charAt(j-i)==sample.charAt(j))
                    sim++;
                else
                    break;
            }
        }
        return sim;
    }
}

这是问题 -

对于两个字符串A和B,我们将字符串的相似性定义为两个字符串共有的最长前缀的长度。例如,字符串“abc”和“abd”的相似性为2,而字符串“aaa”和“aaab”的相似度为3。

计算字符串S与每个后缀的相似之和。

输入:
第一行包含测试用例T的数量。下一个T行中的每一行都包含一个字符串。

输出:
输出T行包含相应测试用例的答案。

约束:
1&lt; = T&lt; = 10
每个字符串的长度最多为100000,仅包含小写字符。

示例输入:
2
ababaa
AA

示例输出:
11个
3

解释
对于第一种情况,字符串的后缀是“ababaa”,“babaa”,“abaa”,“baa”,“aa”和“a”。每个字符串与字符串“ababaa”的相似性分别为6,0,3,0,1,1。因此答案是6 + 0 + 3 + 0 + 1 + 1 = 11.

对于第二种情况,答案是2 + 1 = 3.

如何提高代码的运行速度。由于网站没有提供它使用的测试用例列表,因此变得更加困难。

5 个答案:

答案 0 :(得分:3)

我使用char []而不是字符串。它将运行时间从5.3秒减少到4.7秒,对于测试用例而言也是如此。这是代码 -

static int solve(String sample){    
        int len=sample.length();
        char[] letters = sample.toCharArray();
        int sim=0;
        for(int i=0;i<len;i++){
            for(int j=i;j<len;j++){
                if(letters[j-i]==letters[j])
                    sim++;
                else
                    break;
            }
        }
    return sim;
}

答案 1 :(得分:3)

使用了不同的算法。运行n次循环,其中n等于主字符串的长度。对于每个循环,生成从第i个字符串开始的字符串的所有后缀,并将其与第二个字符串匹配。当你找到无法匹配的字符时,循环将j的值加到计数器整数c上。

import java.io.BufferedReader;
import java.io.InputStreamReader;

class Solution {

    public static void main(String args[]) throws Exception {
    BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    int T = Integer.parseInt(in.readLine());
    for (int i = 0; i < T; i++) {
        String line = in.readLine();
        System.out.println(count(line));
    }
    }

    private static int count(String input) {
    int c = 0, j;
    char[] array = input.toCharArray();
    int n = array.length;
    for (int i = 0; i < n; i++) {
        for (j = 0; j < n - i && i + j < n; j++)
        if (array[i + j] != array[j])
            break;
        c+=j;
    }
    return c;
    }
}

答案 2 :(得分:1)

我花了一些时间来解决这个问题,这是我的代码示例(它适用于我,并通过所有测试用例):

static long stringSimilarity(String a) {
        int len=a.length();
        char[] letters = a.toCharArray();
        char localChar = letters[0];
        long sim=0;
        int sameCharsRow = 0;
        boolean isFirstTime = true;
        for(int i=0;i<len;i++){
            if (localChar == letters[i]) {
                for(int j = i + sameCharsRow;j<len;j++){
                    if (isFirstTime && letters[j] == localChar) {
                        sameCharsRow++;
                    } else {
                        isFirstTime = false;
                    }
                    if(letters[j-i]==letters[j])
                        sim++;
                    else
                        break;
                }
                if (sameCharsRow > 0) {
                    sameCharsRow--;
                    sim += sameCharsRow;
                }
                isFirstTime = true;
            }
        }
        return sim;
}

关键是我们需要加速具有相同内容的字符串,然后我们将在测试用例10和11中获得更好的性能。

答案 3 :(得分:0)

使用样本字符串的长度初始化sim并以1开始外部循环,因为我们现在提前将样本字符串与其自身的比较将其自己的长度值添加到结果中。

答案 4 :(得分:0)

import java.util.Scanner;

public class StringSimilarity 
{
public static void main(String args[])
 {
  Scanner user_input = new Scanner(System.in);
  int count = Integer.parseInt(user_input.next());
  char[] nextLine = user_input.next().toCharArray();
    try 
     {
       while(nextLine!= null )
       {
  int length = nextLine.length;
  int suffixCount =length;
  for(int i=1;i<length;i++)
  {
          int j =0;
          int k=i;
          for(;k<length && nextLine[k++] == nextLine[j++];  suffixCount++);
  }
       System.out.println(suffixCount);
      if(--count < 0)
      {
      System.exit(0);
      }
    nextLine = user_input.next().toCharArray();
     }
   }
   catch (Exception e) 
   {
   // TODO Auto-generated catch block
   e.printStackTrace();
   }
  }
}