(Phone Interview) remove comments from source code


  • 1
    D

    Given a file path represented as string, take this input string and remove all the comments in the file, print this file or save this to a new txt file by your choice.

    cases to consider:
    // comment
    /*

    • comment
      */
      foo(); // comment

  • 1
    S

    My Normal OC Solution

    //ARC
    typedef enum{
        ProcessStateCommentEnd,
        ProcessStatePotentialCommentStart,
        ProcessStateCommentLine,
        ProcessStateCommentBlock,
        ProcessStatePotentialCommentBlockEnd
    }ProcessState;
    
    - (NSString *)removeComment:(NSString *)path{
        NSError *error = nil;
        NSString *originalText = [[NSString alloc] initWithContentsOfFile:path
                                                                 encoding:NSUTF8StringEncoding
                                                                    error:&error];
        if (error){
            return nil;
        }
        
        NSMutableString *newText = [NSMutableString string];
        
        ProcessState state = ProcessStateCommentEnd;
        
        for (int i = 0; i < originalText.length; i++){
            char c = [originalText characterAtIndex:i];
            if (state == ProcessStateCommentEnd){
                if (c == '/'){
                    state = ProcessStatePotentialCommentStart;
                }
                [newText appendFormat:@"%c",c];
            }
            else if (state == ProcessStatePotentialCommentStart){
                if (c == '/'){
                    state =  ProcessStateCommentLine;
                    [newText deleteCharactersInRange:NSMakeRange(newText.length-1,1)];
                }
                else if (c == '*'){
                    state =  ProcessStateCommentBlock;
                    [newText deleteCharactersInRange:NSMakeRange(newText.length-1,1)];
                }
                else{
                    state = ProcessStateCommentEnd;
                }
            }
            else if (state == ProcessStateCommentLine){
                if (c == '\n'){
                    state = ProcessStateCommentEnd;
                }
            }
            else if (state == ProcessStateCommentBlock){
                if (c == '*'){
                    state = ProcessStatePotentialCommentBlockEnd;
                }
            }
            else if (state == ProcessStatePotentialCommentBlockEnd){
                if (c == '/'){
                    state = ProcessStateCommentEnd;
                }  
            }  
        }
        
        return newText;
    }
    
    

  • 0
    A

    @daniel-w-1 Did you ask the interviewer if you could use regular expression?


  • 0
    A
             public static void replaceComments(String codeStr) {
    		String regex = "(/\\*(.|[\\n\\r])*?\\*/)|(\\s{1,}?//.*)";
    		Pattern p = Pattern.compile(regex);
    		Matcher matcher = p.matcher(codeStr);
    		System.out.println(codeStr.replaceAll(regex, ""));		
    	}
    

  • 2

  • 1
    W

    For this question, there are a lot of corner cases that must be considered, for example

    • Case1: string contains "//", "/../", we cannot remove them.
      If string literal contains nested string literals, we must find the second " that is not escaped by a backslash.
      Every time when we meet a backslash, we skip the next character.

    • Case2: a single quotation character, we must ignore it.

    • Case3: /../ contains nested /../
      For the nested /.. /..*/.. /, we need to simulate a stack to find the correct /, otherwise, we might stop removing the comments too early.
      If /
      ..
      / contains the ", we cannot consider it as the start of a string literal.

    • In short, we just print every thing between the first /* and the last */ . For //, if it is not in a string literal, we just print everything after it until the end of the line.


  • 0
    D

    @avigit as an interviewer who regularly uses this question, I allow regex, with the warning that I have yet to see a correct solution. Usually candidates are far better off just writing code.

    Just eyeballing your proposed regex, I think you match /*/ as a multi-line comment, but I could be wrong :-)


  • 0
    D

    @wangxinbo comments don't nest (at least, not in any language I'm aware of - would be interested to hear a counter example). So you don't need case 3.


  • 0
    P

    Enjoy this solution

    def removeComments(inputFile, outputFile):
            with open(inputFile) as fp:
                    with (open(outputFile, "w") as fw:
                            for line in fp:
                                    c = 0
                                    block_comment = False
                                    while c < len(line):
                                            if line[c] == "/" and c< len(line) - 1 and line[c+1]=="/":
                                                    break
                                            if block_comment:
                                                    if line[c] == "*" and c < len(line) - 1  and line[c+1] == "/":
                                                            block_comment = False
                                                            c = c + 2
                                                            continue
                                                    else:
                                                            c = c + 1
                                                            continue
                                            else:
                                                    if line[c] = "/" and c < len(line) and line[c+1] == "*":
                                                            block_comment = True
                                                            c = c + 2
                                                            continue
                                                    else:
                                                            fwrite(c, fw)   
                                                            c = c + 1
    
    

Log in to reply
 

Looks like your connection to LeetCode Discuss was lost, please wait while we try to reconnect.