題目
分析
這是一道非常不錯的字符串的練習題。雖然說不涉及什麼算法,但如果需要一點點小思維,否則可能會覺得很亂無從下手。
邊讀入邊輸出,不好判斷,難度比較大。所以可以所有字符一次性讀入一個足夠大的字符數組中。然後再遍歷進行處理,由於有了下標,處理起來方便很多。
設置開關變量flag,是解決本題一個很關鍵的思想。flag=1:表示不是註釋,可以輸出,相當於水龍頭處於打開的狀態;flag=0:表示是註釋,不用輸出,相當於水龍頭處於關閉的狀態。
什麼時候改變開關變量flag的狀態呢?首先很容易理解,要開水龍頭,那水龍頭此時肯定是關着的,你才能開。同理,要關水龍頭,那水龍頭此時肯定是開着的,你才能關。註釋 "/*...*/" 有很明顯的開始和結束的標誌, 但註釋 "//" 卻無特殊的結束標誌,故另外需要添加一個特殊標記。詳情見代碼,代碼中已給出註釋,代碼還算簡潔。
代碼
- C/C++
#include<iostream>
#include<cstdio>
using namespace std;
char s[10005];
int main()
{
char c;
int k=0;
while((c=getchar())!=EOF)
s[k++]=c;
s[k]='\0'; //這個不要忘了
int flag=1; //開關變量。flag=1:不是註釋,可以輸出。相當於水龍頭處於打開狀態
int mark=0; //特殊標記。由於//這種註釋沒有特殊的結尾標識,故需要特殊標記
for(int i=0;s[i]!='\0';i++)
{
//重開水龍頭
if(!flag && s[i-1]=='/' && s[i-2]=='*') //水龍頭一開始處於關的狀態才能開,故須!flag。且碰到註釋的結束標誌"*/"
flag=1;
if(!flag && mark && s[i]=='\n')//"//"這種註釋結束的位置有個換行符,但"/**/"裏面同樣也可以有換行符,故需要特殊標誌
{
flag=1;
mark=0; //重置特殊標記
}
//關水龍頭
if(flag && s[i]=='/' && (s[i+1]=='*'||s[i+1]=='/' ))
{ //水龍頭是處於開的狀態才能關,故須flag=1,且碰到註釋的開始標誌"/*"或者"//"
flag=0;
if(s[i+1]=='/') //如果是"//"這種註釋,就添加特殊註釋
mark=1;
}
if(flag)
putchar(s[i]);
}
return 0;
}
- Java
//package LanQiaoBei;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(System.in);
String cppStr="";
while (sc.hasNext())
{
String s=sc.nextLine();
cppStr=cppStr+s+"\n";
}
String regex1="/\\*{1,2}[\\s\\S]*?\\*/";
String regex2="//[\\s\\S]*?\\n"; //注意避免貪婪匹配
String s1=cppStr.replaceAll(regex1, "");
String s2=s1.replaceAll(regex2, "\n");
System.out.print(s2);
}
}