【藍橋杯】[算法提高VIP] 去註釋

題目

原題鏈接

分析

這是一道非常不錯的字符串的練習題。雖然說不涉及什麼算法,但如果需要一點點小思維,否則可能會覺得很亂無從下手。

邊讀入邊輸出,不好判斷,難度比較大。所以可以所有字符一次性讀入一個足夠大的字符數組中。然後再遍歷進行處理,由於有了下標,處理起來方便很多。

設置開關變量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);
		
	}
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章