字符串習題

單詞個數統計

原作:

輸入: 一行字符串。僅有空格和英文字母構成。

輸出:

英文字母個數letter_num

單詞個數word_num

出現最多的字母max_letter

出現最多的字母的出現次數max_letter_frequ

處理:

  1. 統計并輸出此句子英文字母的個數;

  2. 統計并輸出此句子中單詞的個數;

  3. 查找此句子中出現次數最多的字母(不區分大小寫,大小寫字母是相同的)及次數。當出現最多的字母不止一個時,全部找到,并輸出找到的所有字母及次數。(輸出順序按字母順序,且輸出時字母全部小寫)

int main() {//輸入:一行字符串。僅有空格和英文字母構成。 char arr[1024];string s;fgets(arr, sizeof(arr), stdin);s = arr;//英文字母個數int letter_num = 0;//單詞的個數int word_num = 0;map<char,int> myMap;//處理//統計并輸出此句子英文字母的個數for (int i = 0; i < s.size(); i++) {if (s[i] != ' ') {letter_num++;//將s[i]統一轉成小寫if (s[i] >= 'A' && s[i] <= 'Z') {s[i] += 32;}myMap[s[i]]++;if (s[i] == ' ' && s[i + 1] != ' ') {word_num++;}}}//輸出:英文字母的個數printf("%d\n", letter_num);//輸出:單詞的個數printf("%d\n", word_num);//輸出:出現次數最多的字母map<char,int>::iterator it;
?//找到字母出現的最多次數int max = 0;for (it=myMap.begin(); it != myMap.end(); it++) {if (it->second > max) {max = it->second;}}//找到值為max的所有鍵vector<char>max_letters;for (it = myMap.begin(); it != myMap.end(); it++) {if (it->second == max) {max_letters.push_back(it->first);}}//打印輸出max_letters數組中的值for (int i = 0; i < max_letters.size(); i++) {printf("%d ", max_letters[i]);}printf("\n");return 0;
}

代碼分析

上述代碼存在幾處的錯誤,我們來解釋一下:

1.輸入語句發生錯誤:

scanf("%s", arr);

%s 讀取遇到空格就結束了,所以無法讀入整行句子。句子有空格的話,后面的內容根本讀不到。

應改為:

fgets(arr, sizeof(arr), stdin);

2.英文字母個數,單詞個數統計錯誤:

按照上面的寫法, 會把非空格的字符都算進去,但題目要求只統計英文字母個數。 即 如果 s[i] 是換行符 \n,也會被統計進去。

正確的改法應該是:

if ( (s[i] >= 'A' && s[i] <= 'Z') || (s[i] >= 'a' && s[i] <= 'z') ) {letter_num++;
}

或者用 isalpha(s[i])。 isalpha() 是標準C庫函數,作用是判斷字符是否為英文字母(A-Z,a-z)。

對于統計單詞個數:你要使用上述的這個語句來統計單詞個數,得先去掉開頭和結尾的空格。

或者推薦使用下列的做法:

bool in_word = false;
for (int i = 0; i < s.size(); i++) {if (isalpha(s[i])) {if (!in_word) {word_num++;in_word = true;}} else if (s[i] == ' ') {in_word = false;}
}
?

正確代碼

#define  _CRT_SECURE_NO_WARNINGS
#include<cstdio>
#include <stdio.h>
#include<string>
#include<vector>
#include<map>
?
using namespace std;
?
int main() {//輸入:一行字符串。僅有空格和英文字母構成。 char arr[1024];string s;fgets(arr, sizeof(arr), stdin);s = arr;//英文字母個數int letter_num = 0;//單詞的個數int word_num = 0;map<char,int> myMap;//處理//統計并輸出此句子英文字母,單詞的個數bool in_word = false;//標記是否在單詞中for (int i = 0; i < s.size(); i++) {if (isalpha(s[i])) {letter_num++;//統一轉成小寫,再加入myMapchar ch = tolower(s[i]);myMap[ch]++;//再統計單詞if (!in_word) {word_num++;in_word = true;}}else if (s[i] == ' ') {in_word = false;//遇到空格說明單詞結束}}//輸出:英文字母的個數printf("%d\n", letter_num);//輸出:單詞的個數printf("%d\n", word_num);//輸出:出現次數最多的字母map<char,int>::iterator it;
?//找到字母出現的最多次數int max = 0;for (it=myMap.begin(); it != myMap.end(); it++) {if (it->second > max) {max = it->second;}}//找到值為max的所有鍵vector<char>max_letters;for (it = myMap.begin(); it != myMap.end(); it++) {if (it->second == max) {max_letters.push_back(it->first);}}//打印輸出max_letters數組中的值for (int i = 0; i < max_letters.size(); i++) {printf("%c ", max_letters[i]);}printf("\n");//打印輸出出現最多的字母的出現次數printf("%d\n", max);return 0;
}

浮點數加法

原作:

輸入:有2行,分別表示兩個加數num1 num2

輸出: 一個小數部分不為0的浮點數

處理: 求2個浮點數相加的和

思路:

我們要運算的數已經超過了浮點數精度,稱此類問題為高精度計算。

此題給的兩個數都超過了float和double的精度,所以我們可以把他們表示為兩個字符串,進行運算。

我們要做的實際上就是用字符串模擬小學時學的豎式計算。

1)對齊:把小數點的位置對齊

2)先計算右邊的小數,即進行小數運算

3)再進行左邊的整數,即進行整數運算

對于運算的過程:從右往左算,且計算的是a+b+進位(carry)%10

對于整數的運算,因為兩個加數的位數可能不一樣,所以我們要實現i,j分別指向兩個加數,我們運算的結束條件是,a沒訪問完或者b沒訪問完或者carry==1(即可能存在兩個都訪問完了,但還有進位的情況,例如11+99,在11和99的崗位都訪問完了,還要向前再加一位)

#define  _CRT_SECURE_NO_WARNINGS
#include<cstdio>
#include <stdio.h>
#include<string>
using namespace std;
/*
參數:一個字符串a
返回值:a的整數部分
處理:提取a的整數部分
*/
string GetInteger(string a) {return a.substr(0, a.find('.'));
}
//提取a的小數部分
string GetFraction(string a) {return a.substr(a.find('.') + 1);
}
?
/*
處理:獲取小數計算的結果,已經最終的進位
因為返回值只能返回一個,我們要兩個結果,故我們都使用引用進行傳遞。
*/
void FractionPlus(string& res, int& carry, string fa, string fb) {
?int size = max(fa.size(), fb.size());while (fa.size() < fb.size()) {fa.push_back('0');}while (fb.size() < fa.size()) {fb.push_back('0');}//開始運算res.resize(size);//給res申請內存空間carry = 0;for (int i = size - 1; i >= 0; i--) {//'0'='0'//'3'='0'+'3'if (fa[i] + fb[i] + carry - '0' > '9') {res[i] = fa[i] + fb[i] +carry- '0' - 10;carry = 1;}else {res[i] = fa[i] + fb[i] + carry - '0';carry = 0;}}return;
}
/*
進行整數運算,整數加法運算不需要修改進位值,只需要獲取小數運算得到的
進位值
*/
void IntegerPlus(string& res, int carry, string ia,string ib) {res.clear();for (int i = ia.size() - 1, j = ib.size() - 1; i >= 0 || j >= 0 || carry == 1; --i, --j) {//a,b都還沒訪問完if (i >= 0 && j >= 0) {if (ia[i] + ib[j] + carry - '0' > '9') {//結果要插入到上一個結果的前面res.insert(res.begin(), ia[i] + ib[j] + carry - '0' - 10);carry = 1;}else {res.insert(res.begin(), ia[i] + ib[j] + carry - '0');carry = 0;}//只有a的情況 ? ? ? ? ? }else if (i >= 0 &&j < 0) {if (ia[i] + carry > '9') {//結果要插入到上一個結果的前面res.insert(res.begin(), ia[i] + carry - 10);carry = 1;}else {res.insert(res.begin(), ia[i] + carry);carry = 0;}}else if (i < 0 && j >= 0) {//只有b的情況 if (ib[j] + carry > '9') {//結果要插入到上一個結果的前面res.insert(res.begin(), ib[j] + carry - 10);carry = 1;}else {res.insert(res.begin(), ib[j] + carry);carry = 0;}}else { //只有進位res.insert(res.begin(), '1');carry = 0;}}}
?
?
int main() {string a;string b;char arr1[1024];char arr2[1024];while (scanf("%s%s", arr1, arr2) != EOF) {a = arr1;b = arr2;string ia = GetInteger(a);string ib = GetInteger(b);string fa = GetFraction(a);string fb = GetFraction(b);string fres;int carry;FractionPlus(fres, carry, fa, fb);string ires;IntegerPlus(ires, carry, ia, ib);string result = ires + '.' + fres;printf("%s\n", result.c_str());}return 0;
}

代碼分析

以上代碼有一些語法值得我們再次復習。

1.字符串操作

a.find('.');//找到字符串中第一次出現 . 的位置,返回下標。如果找不到,返回 string::npos
a.substr(0, pos)//從下標 0 開始,截取 pos 長度的子串

2.max() 是 C++ 標準庫 <algorithm > 中的函數,用來返回兩個值中的較大值。

知識點

將大寫字母轉為小寫字母的方式

用tolower() 或者使用ASCII碼

tolower() 是 C 標準庫 里的函數

#include <cctype>
?
char lower = tolower('A'); // 結果是 'a'
?

在 ASCII 表中:

  • 大寫字母 'A''Z' 的值是 65 ~ 90

  • 小寫字母 'a''z' 的值是 97 ~ 122

  • 大小寫之間的差值是 32

if (ch >= 'A' && ch <= 'Z') {ch += 32;
}

字符形式進行十進制運算的原理

現在我們想以字符形式進行十進制運算。

字符 '0' ~ '9' 在 ASCII 表中對應十進制數值 48~57。故 '3' + '6' = 51 + 54 = 105;在十進制運算中3 + 6 = 9;顯然,9的ASCII碼不是105,故我們不能簡單的將兩個字符相加來實現。那該怎么辦?

==》因為字符和十進制數字的關系有字符 - '0' = 對應的十進制數字

如果你要對兩個字符表示的數字相加(模擬豎式加法),你需要先把它們轉換成數字再相加:

('3' - '0') + ('6' - '0') = 3 + 6 = 9

在上面的案例中,你可以看作 fa[i] - '0' 得到數字,fb[i] - '0' 得到數字,

然后數字相加,最后 + '0' 變回字符存進 res[i]

所以我們可以直接合并表示為fa[i] + fb[i] + carry - '0'

另外為什么可以與'9'表示,因為fa[i] + fb[i] + carry - '0' 這個結果是字符形式的,而在字符表示下:最大個位數字是 '9'(ASCII 57),如果 這個結果大于'9',也就對應了數字運算中的結果大于9,也就是豎式加法里的“要進位”條件。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/72970.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/72970.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/72970.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

解決火絨啟動時,報安全服務異常,無法保障計算機安全

1.找到控制面板-安全和維護-更改用戶賬戶控制設置 重啟啟動電腦解決。

python總結(1)

數據結構是以某種方式(如通過編號)組合起來的數據元素(如數、字符乃至其他數據結構)集合。在Python中&#xff0c;最基本的數據結構為序列(sequence)。序列中的每個元素都有編號&#xff0c;即其位置或索引&#xff0c;其中第一個元素的索引為0&#xff0c;第二個元素的索引為1…

NAT NAPT

NAT NAT&#xff08;Network Address Translation&#xff0c;網絡地址轉換&#xff09; 主要用于在不同網絡&#xff08;如私有網絡和公共互聯網&#xff09;之間進行 IP 地址轉換&#xff0c;解決IP 地址短缺問題&#xff0c;并提供一定的安全性。 IPv4 地址是 32 位&#xf…

快速排序(二叉樹的前序遞歸遍歷思想)

思路 之前我們從選擇排序&#xff0c;到選擇排序的穩定性優化&#xff0c;到冒泡排序&#xff0c;到插入排序&#xff0c;到插入排序的提前截止時間&#xff0c;到希爾排序&#xff0c;雖然逐步一直都在優化&#xff0c;但是時間復雜度還是N得平方&#xff0c;力扣提交的結果一…

Redis 面試篇

Redis相關面試題 緩存三劍客 面試官&#xff1a;什么是緩存穿透 ? 怎么解決 ? 緩存穿透是指查詢一個一定不存在的數據&#xff0c;如果從存儲層查不到數據則不寫入緩存&#xff0c;這將導致這個不存在的數據每次請求都要到 DB 去查詢&#xff0c;可能導致 DB 掛掉。這種情況…

群暉DS223 Docker搭建為知筆記

群暉DS223 Docker搭建為知筆記&#xff0c;打造你的專屬知識寶庫 一、引言 在數字化信息爆炸的時代&#xff0c;筆記軟件成為了我們管理知識、記錄靈感的得力助手。為知筆記&#xff0c;作為一款專注于工作筆記和團隊協作的云筆記產品&#xff0c;以其豐富的功能和便捷的使用體…

Linux網絡之數據鏈路層協議

目錄 數據鏈路層 MAC地址與IP地址 數據幀 ARP協議 NAT技術 代理服務器 正向代理 反向代理 上期我們學習了網絡層中的相關協議&#xff0c;為IP協議。IP協議通過報頭中的目的IP地址告知了數據最終要傳送的目的主機的IP地址&#xff0c;從而指引了數據在網絡中的一步…

分類評價指標

基礎概念解釋 TP、TN、FP、FN 這里T是True&#xff0c;F是False&#xff0c;P為Positive&#xff0c;N為Negative TP&#xff1a;被模型正確地預測為正樣本&#xff08;原本為正樣本&#xff0c;預測為正樣本&#xff09; TN&#xff1a;被模型正確地預測為負樣本&#xff0…

LeetCode 哈希章節

簡單 1. 兩數之和 給定一個整數數組 nums 和一個整數目標值 target&#xff0c;請你在該數組中找出 和為目標值 target 的那 兩個 整數&#xff0c;并返回它們的數組下標。 你可以假設每種輸入只會對應一個答案&#xff0c;并且你不能使用兩次相同的元素。 你可以按任意順序返…

WLAN(無線局域網)安全

WLAN安全涉及到保護無線局域網免受各種威脅和攻擊&#xff0c;以確保數據的保密性、完整性和可用性。以下是關于WLAN安全的多方面介紹&#xff1a; 一、主要安全威脅 竊聽&#xff1a;攻擊者利用特殊設備監聽無線信號&#xff0c;獲取傳輸中的數據&#xff0c;如用戶的賬號密…

江科大51單片機筆記【11】AT24C02(I2C總線)

一、存儲器 1.介紹 RAM的特點是存儲速度特別快&#xff0c;但是掉電會丟失&#xff1b;ROM的特點是存儲速度特別慢&#xff0c;但是掉電不會丟失 SRAM是所有存儲器最快的&#xff0c;一般用于電腦的CPU高速緩存&#xff0c;容量相對較少&#xff0c;成本較高&#xff1b;DRAM…

【C++指南】一文總結C++類和對象【中】

&#x1f31f; 各位看官好&#xff0c;我是egoist2023&#xff01; &#x1f30d; 種一棵樹最好是十年前&#xff0c;其次是現在&#xff01; &#x1f680; 今天來學習C類和對象的語法知識。注意&#xff1a;在本章節中&#xff0c;小編會以Date類舉例 &#x1f44d; 如果覺得…

PgSql 操作技巧

1、查詢數據導出csv數據 \COPY (SELECT w.* from t_sys_warn w ) TO /home/cuadmin/warn_output.csv WITH CSV HEADER;2、導出sql Insert語句 pg_dump -U 用戶名 -h 主機名 -p 端口號 -d 數據庫名 --inserts -t 表名 > 導出文件.sqlpg_dump -U username -d dbname -t tabl…

Unity ES3保存類的問題

有以下一個物品類 public class Item_Base//基礎物品 { public string ID; private Attribute_Data Item_attribute new(); } 當使用ES3保存這個類時&#xff0c;Item_attribute的數據不會被保存&#xff0c;因為它是私有private ES3保存類時&#xff0c;只會保存…

react基本功

useLayoutEffect useLayoutEffect 用于在瀏覽器重新繪制屏幕之前同步執行代碼。它與 useEffect 相同,但執行時機不同。 主要特點 執行時機:useLayoutEffect 在 DOM 更新完成后同步執行,但在瀏覽器繪制之前。這使得它可以在瀏覽器渲染之前讀取和修改 DOM,避免視覺上的閃爍…

Spring Boot筆記(上)

01 概要 Spring Boot 是 Java 領域最流行的 快速開發框架&#xff0c;專為簡化 Spring 應用的初始搭建和開發而設計。 一、Spring Boot 解決了什么問題&#xff1f; 傳統 Spring 痛點 ? 繁瑣的 XML 配置 ? 需要手動管理依賴版本 ? 部署依賴外部 Web 服務器&#xff08;如 …

目標檢測YOLO實戰應用案例100講-基于毫米波雷達的多目標檢測 (續)

目錄 3.2 改進的CFAR目標檢測算法 3.3 算法步驟描述 3.4 實驗結果與分析 基于VGG16-Net的毫米波雷達目標檢測算法 4.1 VGG16-Net網絡模型 4.2 改進VGG16-Net網絡的目標檢測算法 4.3 算法步驟描述 4.4 實驗結果與分析 知識拓展 基于毫米波雷達的多目標檢測:使…

gitsubtree怎么添加新的子倉庫

要使用 git subtree 添加一個新的子倉庫&#xff0c;可以按照以下步驟操作&#xff1a; 1. 添加子倉庫 使用 git subtree add 命令將子倉庫的內容添加到主倉庫的指定目錄中。命令格式如下&#xff1a; git subtree add --prefix<子目錄路徑> <子倉庫地址> <子…

文本轉語音-音畫適時推送rtsp并播放

文本語音 rtsp適時播放叫號系統的底層邏輯 發布Linux, unix socket 和window win32做為音頻源的 python10下的(ffmpeg version 7.1) 可運行版本. 這兩天在弄這個&#xff0c;前2篇是通過虛擬聲卡&#xff0c;達到了最簡單的一個邏輯&#xff0c;播放文本就從聲卡發聲&#xff0…

從0開始的操作系統手搓教程33:掛載我們的文件系統

目錄 代碼實現 添加到初始化上 上電看現象 掛載分區可能是一些朋友不理解的——實際上掛載就是將我們的文件系統封裝好了的設備&#xff08;硬盤啊&#xff0c;SD卡啊&#xff0c;U盤啊等等&#xff09;&#xff0c;掛到我們的默認分區路徑下。這樣我們就能訪問到了&#xff…