如何改进此Java代码以在字符串中查找子字符串?

zen*_*ngr 10 java string algorithm

我最近被要求提交一份解决问题的解决方案.

问题:在字符串中查找子字符串.

Input: "Little star's deep dish pizza sure is fantastic."  
Search: "deep dish pizza"  
Output: "Little star's [[HIGHLIGHT]]deep dish pizza[[ENDHIGHLIGHT]] sure is fantastic."
Run Code Online (Sandbox Code Playgroud)

请注意,荧光笔在此示例中不必具有完全相同的结果,因为正在定义一个好的代码段并返回最相关的代码段,并突出显示查询字词.

最重要的要求是编写它,因为我会编写一个生产代码.

我的解决方案未被接受.我怎么能改进它?我知道,我本可以使用:

  1. Knuth-Morris-Pratt算法
  2. 正则表达式(我可以吗?)

我的问题:

  1. 科技公司在审查工作代码时会考虑什么.我在同一天提交了代码,这有什么帮助吗?

  2. 在其中一条评论中,它指出,它看起来像学校代码而不是生产代码.怎么样?有什么建议?

我的解决方案:
FindSubString.java

/**
 * FindSubString.java: Find sub-string in a given query
 * 
 * @author zengr
 * @version 1.0
 */

public class FindSubstring {
    private static final String startHighlight = "[[HIGHLIGHT]]";
    private static final String endHighlight = "[[ENDHIGHLIGHT]]";

    /**
     * Find sub-string in a given query
     * 
     * @param inputQuery: A string data type (input Query)
     * @param highlightDoc: A string data type (pattern to match)
     * @return inputQuery: A String data type.
     */
    public String findSubstringInQuery(String inputQuery, String highlightDoc) {
        try {

            highlightDoc = highlightDoc.trim();

            if (inputQuery.toLowerCase().indexOf(highlightDoc.toLowerCase()) >= 0) {
                // update query if exact doc exists
                inputQuery = updateString(inputQuery, highlightDoc);
            }

            else {
                // If exact doc is not in the query then break it up
                String[] docArray = highlightDoc.split(" ");

                for (int i = 0; i < docArray.length; i++) {
                    if (inputQuery.toLowerCase().indexOf(docArray[i].toLowerCase()) > 0) {
                        inputQuery = updateString(inputQuery, docArray[i]);
                    }
                }
            }
        } catch (NullPointerException ex) {
            // Ideally log this exception
            System.out.println("Null pointer exception caught: " + ex.toString());
        }

        return inputQuery;
    }

    /**
     * Update the query with the highlighted doc
     * 
     * @param inputQuery: A String data type (Query to update)
     * @param highlightDoc: A String data type (pattern around which to update)
     * @return inputQuery: A String data type.
     */
    private String updateString(String inputQuery, String highlightDoc) {
        int startIndex = 0;
        int endIndex = 0;

        String lowerCaseDoc = highlightDoc.toLowerCase();
        String lowerCaseQuery = inputQuery.toLowerCase();

        // get index of the words to highlight
        startIndex = lowerCaseQuery.indexOf(lowerCaseDoc);
        endIndex = lowerCaseDoc.length() + startIndex;

        // Get the highlighted doc
        String resultHighlightDoc = highlightString(highlightDoc);

        // Update the original query
        return inputQuery = inputQuery.substring(0, startIndex - 1) + resultHighlightDoc + inputQuery.substring(endIndex, inputQuery.length());
    }

    /**
     * Highlight the doc
     * 
     * @param inputString: A string data type (value to be highlighted)
     * @return highlightedString: A String data type.
     */
    private String highlightString(String inputString) {
        String highlightedString = null;

        highlightedString = " " + startHighlight + inputString + endHighlight;

        return highlightedString;
    }
}
Run Code Online (Sandbox Code Playgroud)

TestClass.java

/**
 * TestClass.java: jUnit test class to test FindSubString.java
 * 
 * @author zengr
 * @version 1.0
 */

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

public class TestClass extends TestCase
{
    private FindSubstring simpleObj = null;
    private String originalQuery = "I like fish. Little star's deep dish pizza sure is fantastic. Dogs are funny.";

    public TestClass(String name) {
        super(name);
    }

    public void setUp() { 
        simpleObj = new FindSubstring();
    }

    public static Test suite(){

        TestSuite suite = new TestSuite();
        suite.addTest(new TestClass("findSubstringtNameCorrect1Test"));
        suite.addTest(new TestClass("findSubstringtNameCorrect2Test"));
        suite.addTest(new TestClass("findSubstringtNameCorrect3Test"));
        suite.addTest(new TestClass("findSubstringtNameIncorrect1Test"));
        suite.addTest(new TestClass("findSubstringtNameNullTest"));

        return suite;
    }

    public void findSubstringtNameCorrect1Test() throws Exception
    {
        String expectedOutput = "I like fish. Little star's deep [[HIGHLIGHT]]dish pizza[[ENDHIGHLIGHT]] sure is fantastic. Dogs are funny.";
        assertEquals(expectedOutput, simpleObj.findSubstringInQuery(originalQuery, "dish pizza"));
    }

    public void findSubstringtNameCorrect2Test() throws Exception 
    {
        String expectedOutput = "I like fish. Little star's [[HIGHLIGHT]]deep dish pizza[[ENDHIGHLIGHT]] sure is fantastic. Dogs are funny.";
        assertEquals(expectedOutput, simpleObj.findSubstringInQuery(originalQuery, "deep dish pizza"));
    }

    public void findSubstringtNameCorrect3Test() throws Exception 
    {
        String expectedOutput = "Hello [[HIGHLIGHT]]how[[ENDHIGHLIGHT]] are [[HIGHLIGHT]]you[[ENDHIGHLIGHT]]r?";
        assertEquals(expectedOutput, simpleObj.findSubstringInQuery("Hello how are your?", "how you"));
    }

    public void findSubstringtNameIncorrect1Test() throws Exception 
    {
        String expectedOutput = "I like fish. Little star's deep dish pizza sure is fantastic. Dogs are funny.";
        assertEquals(expectedOutput, simpleObj.findSubstringInQuery(originalQuery, "I love Ruby too"));
    }

    public void findSubstringtNameNullTest() throws Exception
    {
        String expectedOutput = "I like fish. Little star's deep dish pizza sure is fantastic. Dogs are funny.";
        assertEquals(expectedOutput, simpleObj.findSubstringInQuery(originalQuery, null));

    }
}
Run Code Online (Sandbox Code Playgroud)

Qwe*_*rky 8

一些评论;

  • 您只需突出显示搜索字符串的第一次出现.
  • 你假设小写匹配是好的.除非将此指定为要求,否则最好提供两种方法,一种是尊重案例,另一种是忽略案例.
  • 我可能会检查给定的参数并抛出一个NPE,如果其中任何一个为null.这将是我的方法做的第一件事.我会在javadoc中清楚地记录这种行为.
  • 你的方法是糟糕的; findSubstringInQuery我们的主要任务不是找到,而是突出而且inQuery部分是超级的.只需调用方法,highlight或者highlightIgnoreCase如果您打算highlight尊重这种情况.
  • 您的方法参数名称不正确.我已经查看了你的方法签名10次,仍然需要查看方法体,以提醒自己哪个arg是搜索词,哪个是要搜索的文本.给他们打电话searchTermtext.
  • 生产代码不使用默认包.
  • 生产代码不使用System.out.println().
  • 你的javadoc需要改进,它需要告诉用户他们需要知道的关于代码的一切.
  • 我会考虑对没有类变量的类使用静态方法.
  • 我还会考虑允许用户指定自己的开始和结束突出显示标记(如果我这样做,我不会使用静态方法).
  • trim()除非将此指定为要求,否则我不会.如果我这样做,那么显然这种行为将记录在javadoc中.

我不担心用于搜索的算法,Knuth-Morris-Pratt看起来不错,但他们不应该指望你知道它并实现它,除非工作规范明确要求字符串搜索的经验/专业知识.