C++獲取字符串最后一個單詞長度的多種方法
問題描述
給定一個由多個單詞組成的句子,每個單詞由大小寫字母混合構(gòu)成,單詞間使用單個空格分隔。要求輸出最后一個單詞的長度。
約束條件:
- 每個單詞非空
- 總字符長度不超過 103103
- 單詞間使用單個空格分隔
示例:
輸入:HelloNowcoder 輸出:13 輸入:A B C D 輸出:1
解法一:從后向前遍歷法(推薦)
#include <iostream>
#include <string>
using namespace std;
int main() {
string str;
getline(cin, str);
int len = 0;
int i = str.size() - 1;
// 跳過末尾可能的空格(雖然題目說沒有,但增加魯棒性)
while (i >= 0 && str[i] == ' ') i--;
// 計算最后一個單詞的長度
while (i >= 0 && str[i] != ' ') {
len++;
i--;
}
cout << len << endl;
return 0;
}算法分析
時間復(fù)雜度: O(n)
最壞情況下需要遍歷整個字符串
空間復(fù)雜度: O(1)
只使用了常數(shù)個額外變量
優(yōu)點:
- 高效:只需要一次遍歷
- 節(jié)省空間:不需要額外存儲
- 魯棒性好:能處理末尾有空格的情況
解法二:使用rfind方法
#include <iostream>
#include <string>
using namespace std;
int main() {
string str;
getline(cin, str);
// 從后向前查找最后一個空格的位置
size_t pos = str.rfind(' ');
if (pos == string::npos) {
// 沒有空格,整個字符串就是一個單詞
cout << str.size() << endl;
} else {
// 計算最后一個單詞的長度
cout << str.size() - pos - 1 << endl;
}
return 0;
}關(guān)鍵點說明
rfind(' '): 從字符串末尾開始查找空格string::npos: 表示未找到,值為-1(但類型為size_t,所以是最大無符號數(shù))- 注意處理只有一個單詞的情況
解法三:使用stringstream分割
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main() {
string str;
getline(cin, str);
stringstream ss(str);
string word, last_word;
// 讀取所有單詞,最后一個存儲在last_word中
while (ss >> word) {
last_word = word;
}
cout << last_word.size() << endl;
return 0;
}算法特點
優(yōu)點:
- 代碼簡潔易讀
- 自動處理多余空格
- 容易擴展(如需要處理所有單詞)
缺點:
- 需要額外的字符串拷貝
- 使用stringstream有額外開銷
- 需要存儲最后一個單詞的完整副本
解法四:雙指針法
#include <iostream>
#include <string>
using namespace std;
int main() {
string str;
getline(cin, str);
int right = str.size() - 1;
// 右指針:跳過末尾空格
while (right >= 0 && str[right] == ' ') right--;
int left = right;
// 左指針:找到單詞開頭
while (left >= 0 && str[left] != ' ') left--;
// 計算長度
cout << right - left << endl;
return 0;
}算法性能對比
| 方法 | 時間復(fù)雜度 | 空間復(fù)雜度 | 優(yōu)點 | 缺點 |
|---|---|---|---|---|
| 從后向前遍歷 | O(n) | O(1) | 效率高,內(nèi)存少 | 需要手動處理邊界 |
| rfind方法 | O(n) | O(1) | 代碼簡潔 | 需要處理npos |
| stringstream | O(n) | O(n) | 自動處理空格 | 額外開銷大 |
| 雙指針法 | O(n) | O(1) | 思路清晰 | 需要兩個指針 |
邊界條件處理
1. 空字符串
// 在從后向前遍歷法中
if (str.empty()) {
cout << 0 << endl;
return 0;
}2. 全是空格
// 在從后向前遍歷法中,第一個while循環(huán)后i可能為-1
if (i < 0) {
cout << 0 << endl;
return 0;
}3. 末尾有多個空格
// 所有方法都應(yīng)該處理這種情況 // 解法一和四已經(jīng)通過while循環(huán)處理
擴展問題
1. 獲取倒數(shù)第二個單詞的長度
#include <iostream>
#include <string>
using namespace std;
int main() {
string str;
getline(cin, str);
int count = 0;
int i = str.size() - 1;
// 跳過末尾空格
while (i >= 0 && str[i] == ' ') i--;
// 找倒數(shù)第一個單詞
while (i >= 0 && str[i] != ' ') i--;
// 跳過單詞間的空格
while (i >= 0 && str[i] == ' ') i--;
// 找倒數(shù)第二個單詞的末尾
int end = i;
while (i >= 0 && str[i] != ' ') i--;
cout << end - i << endl;
return 0;
}2. 統(tǒng)計句子中單詞的數(shù)量
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main() {
string str;
getline(cin, str);
stringstream ss(str);
string word;
int count = 0;
while (ss >> word) {
count++;
}
cout << count << endl;
return 0;
}3. 獲取最長的單詞
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main() {
string str;
getline(cin, str);
stringstream ss(str);
string word, longest_word;
int max_len = 0;
while (ss >> word) {
if (word.size() > max_len) {
max_len = word.size();
longest_word = word;
}
}
cout << "最長單詞: " << longest_word << ", 長度: " << max_len << endl;
return 0;
}實際應(yīng)用場景
1. 命令行工具
// 實現(xiàn)類似Linux的wc命令,統(tǒng)計單詞數(shù) // 可以擴展為獲取最后一行或最后一個單詞
2. 文本編輯器
// 在代碼編輯器中,獲取光標(biāo)所在單詞的長度 // 用于自動補全或語法高亮
3. 日志分析
// 分析日志文件的最后一個狀態(tài)碼或錯誤信息
4. 自然語言處理
// 在NLP預(yù)處理中,獲取句子的最后一個詞 // 用于語言模型訓(xùn)練或情感分析
測試用例
void test() {
// 測試用例集合
vector<pair<string, int>> test_cases = {
{"HelloNowcoder", 13},
{"A B C D", 1},
{"Hello World", 5},
{"a", 1},
{" ", 0}, // 全是空格
{"hello ", 5}, // 末尾有空格
{" hello", 5}, // 開頭有空格
{"multiple spaces between", 7}, // 多個空格
{"", 0}, // 空字符串
{"12345 67890", 5},
{"The quick brown fox jumps over the lazy dog", 3}
};
for (auto& test_case : test_cases) {
// 測試各個算法
cout << "輸入: \"" << test_case.first << "\", 期望: " << test_case.second << endl;
}
}優(yōu)化技巧
1. 使用引用避免拷貝
// 在處理大字符串時,使用const引用
void processString(const string& str) {
// 處理邏輯
}2. 預(yù)分配內(nèi)存
// 如果知道最大長度,可以預(yù)分配 str.reserve(1000); // 根據(jù)題目約束
3. 使用C風(fēng)格字符串
// 在性能關(guān)鍵場景,可以使用C風(fēng)格字符串
int getLastWordLength(const char* str) {
int len = 0;
int i = strlen(str) - 1;
while (i >= 0 && str[i] == ' ') i--;
while (i >= 0 && str[i] != ' ') {
len++;
i--;
}
return len;
}常見錯誤
1. 忘記處理npos
// 錯誤示例
size_t pos = str.rfind(' ');
int length = str.size() - pos - 1; // 當(dāng)pos為npos時,計算錯誤2. 未考慮末尾空格
// 錯誤示例
int pos = str.rfind(' ');
if (pos != -1) {
cout << str.size() - pos - 1 << endl; // 如果末尾有空格,結(jié)果錯誤
}3. 越界訪問
// 錯誤示例 int i = str.size() - 1; while (str[i] == ' ') i--; // 如果字符串為空,i為-1,訪問越界
總結(jié)
獲取字符串最后一個單詞的長度是一個基礎(chǔ)的字符串處理問題,但它涉及了許多重要的編程概念:
- 字符串遍歷技巧:從后向前遍歷是解決此類問題的關(guān)鍵
- 邊界條件處理:空字符串、空格、單個單詞等情況都需要考慮
- 算法選擇:根據(jù)具體需求選擇最合適的算法
- 代碼魯棒性:處理各種異常輸入情況
推薦方法:從后向前遍歷法
- 效率高,空間復(fù)雜度低
- 代碼清晰,易于理解
- 魯棒性好,能處理各種邊界情況
掌握這個問題的解法不僅能幫助解決類似問題,還能提高字符串處理的基本功。在實際開發(fā)中,根據(jù)具體場景選擇最合適的方法才是最重要的。
以上就是C++獲取字符串最后一個單詞長度的多種方法的詳細內(nèi)容,更多關(guān)于C++獲取字符串最后單詞長度的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C語言詳解結(jié)構(gòu)體的內(nèi)存對齊與大小計算
C 數(shù)組允許定義可存儲相同類型數(shù)據(jù)項的變量,結(jié)構(gòu)是 C 編程中另一種用戶自定義的可用的數(shù)據(jù)類型,它允許你存儲不同類型的數(shù)據(jù)項,本篇讓我們來了解C 的結(jié)構(gòu)體內(nèi)存對齊與計算大小2022-04-04
64位linux 編譯c提示gnu/stubs-32.h:No such file or directory的解決方法
這篇文章主要介紹了64位linux 編譯c提示gnu/stubs-32.h:No such file or directory的解決方法,需要的朋友可以參考下2020-03-03

