# String Manipulation# State Machine# Greedy

a217 - caps lock的災難

🔗 前往 ZeroJudge 原題

題目描述

題目要求將輸入的句子轉換為正確的大小寫格式,即句子的第一個字母大寫,以及單獨的 "i" 也要大寫。輸入的句子只包含小寫字母、空格和標點符號 ., ,, ?, !

解題思路

這題的核心是模擬 caps lock 鍵壞掉的情況,並將小寫字母轉換為大寫字母。程式使用一個布林變數 b 作為狀態機,用於追蹤是否應該將下一個字母轉換為大寫。

  • 初始化 btrue,表示下一個字母應該大寫。
  • 遍歷輸入字串的每個字元:
    • 如果 btrue 且當前字元是小寫字母,則將其轉換為大寫,並將 b 設定為 false
    • 如果當前字元是標點符號 ?, !, 或 .,則將 b 設定為 true,表示下一個字母應該大寫。
    • 如果當前字元是 i 且其後面的字元不是字母,或者當前字元是 i 且前一個字元不是字母或數字,則將其轉換為大寫。
    • 將字元輸出到螢幕。

複雜度分析

  • 時間複雜度: O(n),其中 n 是輸入字串的長度。程式需要遍歷輸入字串一次。
  • 空間複雜度: O(1),程式只使用了常數額外的空間。

程式碼

#include <iostream>
#include <string>
using namespace std;
int main(){
	string a;
	while(getline(cin,a)){
		bool b=1;
		a+='\n';
		for(int i=0,al=a.length();i<al;i++){
			if(b==1&&a[i]>='a'&&a[i]<='z'){
				a[i]-=32;
				b=0;
			}
			else if(a[i]=='?'||a[i]=='!'||a[i]=='.')
				b=1;
			else if(a[i]=='i'&&(a[i+1]>'z'||a[i+1]<'a')){
				if(i==0)
					a[i]-=32;
				else if((a[i-1]>'z'||a[i-1]<'a')&&(a[i-1]>'Z'||a[i-1]<'A'))
					a[i]-=32;
			}
			cout << a[i];
		}
	}
}

Discussion