C++ 統計單詞數

我信你个鬼!發表於2024-09-10

說明:本題目源自叮噹碼校園,如有侵權,請聯絡作者刪除。

題目:

一般的文字編輯器都有查詢單詞的功能,該功能可以快速定位特定單詞在文章中的位置,有的還能統計出特定單詞在文章中出現的次數。現在,請你程式設計實現這一功能,具體要求是:給定一個單詞,請你輸出它在給定的文章中出現的次數和第一次出現的位置。注意:匹配單詞時,不區分大小寫,但要求完全匹配,即給定單詞必須與文章中的某一獨立單詞在不區分大小寫的情況下完全相同,如果給定單詞僅是文章中某一單詞的一部分則不算匹配。.
【輸入】
第1行為一個字串,其中只含字母,表示給定單詞:
第2行為一個字串,其中只可能包含字母和空格,表示給定的文章。
【輸出】
只有一行,如果在文章中找到給定單詞則輸出兩個整數,兩個整數之間用一個空格隔開,分別是單詞在文章中出現的次數和第一次出現的位置(即在文章中第一次出現時,單詞首字母在文章中的位置,位置從0開始):如果單詞在文章中沒有出現,則直接輸出一個整數-1。

輸入:
To
to be or not to be is a question

輸出:
2 0

#include <bits/stdc++.h>
using namespace std;

int main()
{
	// str1儲存要查詢的單詞
	string str1;
	// str2儲存輸入的句子
	string str2;
	// count代表單詞出現的次數
	int count = 0;
	// index代表第一個單詞出現的下標
	int index = -1;

	// 資料的獲取
	getline(cin,str1);
	getline(cin,str2);
	
	// 分別確認單詞的長度和句子的長度
	int len1 = str1.length();
	int len2 = str2.length();
	
	// 迴圈遍歷句子的沒給字元,遍歷的長度需要減去單詞的長度,後面不夠一個單詞的長度就沒必要繼續遍歷了
	for(int i=0; i<len2-len1; i++)
	{
		/*
		一個新單詞的開始:
		1、下標剛好是開頭0或者當前字元的前一個字元是空白符
		2、當前字元轉大寫後是A~Z中的某一個字母
		以上兩個條件應同時滿足
		*/
		if((i==0 || str2[i-1]==' ') && (toupper(str2[i])>='A' && toupper(str2[i])<='Z'))
		{
			// 設定一個標記,假設我們會比對成功找到單詞
			bool flag = true;
			
			// 迴圈遍歷單詞的長度,從單詞0下標和句子的i位置開始逐一取出轉大寫的字元進行比較
			for(int j=0;j<len1;j++)
			{
				/*
				此處str2下標使用i++:
				++在後,所以會先使用i的值作為str2下標和str1[j]進行比較
				比較完成後i才會執行++操作,也就意味著我們str2句子中下標會同時往前進1
				本條判斷作用:
				如果字元不相同,則flag標記為false,也即否定了我們剛才的假設,同時結束繼續往下比較的必要
				*/
				if(toupper(str2[i++]) != toupper(str1[j]))
				{
					flag = false;
					break;
				}
			}
			
			/*
			單詞比較完成
			找到指定單詞的條件:
			1、flag仍然為true,也即我們的假設成立
			2、我們在句子中所找到的這個單詞後面應該為一個空格或者是句子的末尾
			以上兩個條件應同時滿足
			關於這裡的i:經過上方的for迴圈,句子中的i下標已經向右移動到了完成比較的字元的後一個位置
			*/
			if(flag && (str2[i] ==' ' || i == len2))
			{
				// 找到單詞後對統計值+1
				count++;
				// index賦值,此處注意i應該減去單詞的長度以使下標回到單詞的開頭
				if(index == -1) index = i-len1;
			}
			// 沒找到單詞,i應該減,因為for結構體完成後會執行括號中的i++導致句子中的i下標再次右移
			else i--;
		}
	}
	
	// 統計到了單詞,輸出正常的結果
	if(count != 0)
		cout << count << " " << index;
	// 沒統計到單詞,按要求輸出-1
	else cout << "-1";
	
	return 0;
}

  

相關文章