【C語言16天強化訓練】從基礎入門到進階:Day 10


?🔥個人主頁:艾莉絲努力練劍

?專欄傳送門:《C語言》、《數據結構與算法》、C語言刷題12天IO強訓、LeetCode代碼強化刷題、洛谷刷題、C/C++基礎知識知識強化補充、C/C++干貨分享&學習過程記錄

🍉學習方向:C/C++方向學習者

??人生格言:為天地立心,為生民立命,為往圣繼絕學,為萬世開太平

前言:距離我們學完C語言已經過去一段時間了,在學習了初階的數據結構之后,博主還要更新的內容就是【C語言16天強化訓練】,之前博主更新過一個【C語言刷題12天IO強訓】的專欄,那個只是從入門到進階的IO模式真題的訓練。【C語言16天強化訓練】既有IO型,也有接口型。和前面一樣,今天依然是訓練五道選擇題和兩道編程算法題,希望大家能夠有所收獲!



目錄

一、五道選擇題

1.1? 題目1

1.2? 題目2

1.3? 題目3

1.4? 題目4

1.5? 題目5

二、兩道算法題

2.1??不用加減乘除做加法

2.1.1 題目理解

2.1.2 思路

2.2? 找到所有數組中消失的數字

2.2.1 題目理解

2.2.2 思路

2.2.3? 為什么選擇負號標記法?

2.2.4? 負號標記法的巧妙之處

2.2.5? 與其他方法的對比

結尾


一、五道選擇題

1.1? 題目1

題干:求函數返回值,傳入 -1 ,則在64位機器上函數返回( )

int func(int x)
{int count = 0;while (x){count++;x = x&(x - 1);//與運算} return count;
}

A. 死循環? ? ?B. 64? ? ?C. 32? ? ?D. 16

解析:正確答案就是B選項。

函數?func?的作用是計算整數?x?的二進制表示中1的個數(即漢明重量)。通過循環?x = x & (x - 1)?每次會消除二進制表示中最右邊的1,直到?x?變為0。

傳入?-1:在64位機器上,-1?的二進制表示是所有位都是1(即64個1)。因此,循環會執行64次(每次消除一個1),最后返回?count = 64

1.2? 題目2

題干:讀代碼選結果( )

int count = 0;
int x = -1;
while(x)
{count++;x = x >> 1;
}
printf("%d",count)

A. 1? ? ?B. 2? ? ?C. 32? ? ?D. 死循環,沒結果

解析:正確答案就是D選項。

這里?x?是帶符號整數(默認是 signed int),初始為?-1(二進制所有位為1)。執行右移操作?x = x >> 1?是算術右移(對于負數,高位補1)。因此,無論右移多少次,x?始終不會變為0(因為高位一直補1,保持所有位為1,即始終為-1)。所以循環條件?x?永遠為非0,導致死循環。

1.3? 題目3

題干:下述賦值語句錯誤的是( )

A. a = (b = (c = 2 , d = 3))? ? ?B. i++? ? ?C. a / b = 2? ? ?D. a = a < a + 1

解析:正確答案就是C選項。

A.?正確,逗號表達式返回最后一個值(d=3),然后賦值給b,再賦值給a;
B.?正確,自增操作;
C. 錯誤,a/b是一個表達式(值),不能作為左值被賦值;
D.?正確,先計算a < a+1(恒為真,即1),然后賦值給a。

1.4? 題目4

題干:若有 int w=1, x=2, y=3, z=4; 則條件表達 w < x ? w : y < z ? y : z 的值是( )

A. 1? ? ? B. 2? ? ? C. 3? ? ? D. 4

解析:正確答案就是A選項。

題干所給表達式:w < x ? w : y < z ? y : z
結合性:從右到左(條件運算符是右結合),所以等價于:w < x ? w : (y < z ? y : z)

計算:w=1, x=2 -> w<x 為真(1),所以返回 w(即1)
因此w < x ? w : y < z ? y : z的值為1。

1.5? 題目5

題干:以下程序運行后的輸出結果是( )

int main()
{int a=1,b=2,m=0,n=0,k;k=(n=b<a)&&(m=a);printf("%d,%d\n",k,m);return 0;
}

A.?0,0? ? ?B. 0,1? ? ?C. 1,0? ? ?D. 1,1

解析:正確答案就是A選項。

(1)先計算 n = b<a(即n=2<1,為假,所以n=0);

(2)由于 && 短路:第一個操作數 (n=b<a) 結果為0(假),所以第二個表達式 (m=a) 不會執行(m保持原值0);

(3)k 為整個邏輯與的結果(0)。

因此輸出:k=0, m=0。

選擇題答案如下:

1.1? B

1.2? D

1.3? C

1.4? A

1.5? A

校對一下,大家都做對了嗎?


二、兩道算法題

2.1??不用加減乘除做加法

牛客鏈接:JZ65 不用加減乘除做加法

題目描述:

2.1.1 題目理解

為了解決這個問題,我們需要在不使用加減乘除運算符的情況下實現兩個整數的加法。我們可以利用位運算來模擬加法過程。

這道題是接口型的,下面是C語言的模版(如果是IO型就可以不用管它們了)——

2.1.2 思路

C語言思路:

1、算法原理:使用位運算模擬二進制加法。

(1)異或運算(~):得到不考慮進位的和;

(2)與運算 + 左移(& + << 1):得到進位值。

2、迭代過程

(1)每次循環計算當前位的和(不考慮進位)和進位值;

(2)將和賦值給?num1,進位賦值給?num2;

(3)重復直到進位為0。

3、處理負數:由于C語言中使用補碼表示負數,該算法同樣適用于負數加法。

4、時間復雜度:O(1),因為整數位數固定(通常是32位),最多循環32次。

代碼演示:

//C語言實現
/*** 代碼中的類名、方法名、參數名已經指定,請勿修改,直接返回方法規定的值即可*** @param num1 int整型* @param num2 int整型* @return int整型*/
int Add(int num1, int num2) 
{while (num2 != 0){int sum = num1 ^ num2;int carry = (num1 & num2) << 1;num1 = sum;num2 = carry;}return num1;
}

時間復雜度O(1)

空間復雜度O(1)

博主這里再展示一下完整的C語言代碼,包含了測試用例——

代碼演示:

//完整C語言代碼
#include <stdio.h>int Add(int num1, int num2) 
{while (num2 != 0) {int sum = num1 ^ num2;int carry = (num1 & num2) << 1;num1 = sum;num2 = carry;}return num1;
}int main() 
{// 測試用例printf("1 + 2 = %d\n", Add(1, 2));      // 輸出: 3printf("0 + 0 = %d\n", Add(0, 0));      // 輸出: 0printf("5 + 7 = %d\n", Add(5, 7));      // 輸出: 12printf("-1 + 1 = %d\n", Add(-1, 1));    // 輸出: 0printf("10 + -5 = %d\n", Add(10, -5));  // 輸出: 5return 0;
}

時間復雜度O(1)

空間復雜度O(1)

我們學習了C++之后也可以嘗試用C++來實現一下,看看自己前段時間C++學得怎么樣——

C++思路:

1、問題分析:題目要求不使用四則運算符號實現加法。我們可以使用位運算來模擬加法的過程。

2、關鍵觀察:二進制加法的每一位可以分解為:

(1)非進位和:使用異或運算(^)得到,即?num1 ^ num2

(2)進位:使用與運算(&)并左移一位得到,即?(num1 & num2) << 1

3、迭代過程:將非進位和與進位相加,直到進位為0。每次迭代都更新非進位和和進位,直到沒有進位為止。

代碼演示:

//C++實現
class Solution {
public:int Add(int num1, int num2){while (num2 != 0){int sum = num1 ^ num2;int carry = (num1 & num2) << 1;num1 = sum;num2 = carry;}return num1;}
};

時間復雜度:O(1),空間復雜度:O(1)

1、循環條件:當進位(num2)不為0時,繼續循環。

2、計算非進位和:使用異或運算?num1 ^ num2?得到當前位的和,不考慮進位。

3、計算進位:使用與運算?num1 & num2?并左移一位得到進位。

4、更新變量:將非進位和賦值給?num1,進位賦值給?num2,進行下一次迭代。

5、返回結果:當進位為0時,num1?即為最終的和,返回?num1

使用位運算模擬二進制加法通過位運算高效地模擬了加法過程,避免了使用四則運算符號。

我們目前要寫出來C++的寫法是非常考驗前面C++的學習情況好不好的,大家可以嘗試去寫一寫,優先掌握C語言的寫法,博主還沒有介紹C++的算法題,之后會涉及的,敬請期待!

2.2? 找到所有數組中消失的數字

力扣鏈接:448. 找到所有數組中消失的數字

力扣題解鏈接:負號標記法解決【找到所有數組中消失的數字】問題

題目描述:

2.2.1 題目理解

題目的本質是:在一個長度為?n?的數組中,所有數字理論上都應該在?[1, n]?范圍內,但由于某些數字可能重復出現,導致其他數字缺失。我們需要找出所有缺失的數字。

本題中關鍵的約束條件——

1、數組長度 = n;

2、數字范圍 = [1, n];

3、可能有重復數字;

4、需要找出所有缺失的數字。

2.2.2 思路

我們使用負號標記法,時間復雜度為 O(n),空間復雜度為 O(1)(不考慮輸出數組):

1、第一次遍歷:對于每個數字?nums[i],我們將?nums[abs(nums[i])-1]?標記為負數;

2、第二次遍歷:所有仍然為正數的位置?i?表示數字?i+1?在原始數組中不存在。

這道題是接口型的,下面是C語言的模版(如果是IO型就可以不用管它們了)——

代碼演示:

//C語言實現——負號標記法
/*** Note: The returned array must be malloced, assume caller calls free().*/
int* findDisappearedNumbers(int* nums, int numsSize, int* returnSize) {// 第一次遍歷:使用負號標記法for (int i = 0; i < numsSize; i++) {int index = abs(nums[i]) - 1; // 獲取對應的索引位置if (nums[index] > 0) {nums[index] = -nums[index]; // 標記為負數表示該數字存在}}// 統計缺失的數字數量int count = 0;for (int i = 0; i < numsSize; i++) {if (nums[i] > 0) {count++;}}// 分配結果數組int* result = (int*)malloc(count * sizeof(int));*returnSize = count;// 第二次遍歷:收集缺失的數字int j = 0;for (int i = 0; i < numsSize; i++) {if (nums[i] > 0) {result[j++] = i + 1; // 索引+1就是缺失的數字}}return result;
}

時間復雜度O(n)

空間復雜度O(1)

我們學習了C++之后也可以嘗試用C++來實現一下,看看自己前段時間C++學得怎么樣——

代碼演示:

//C++實現——負號標記法
class Solution {
public:vector<int> findDisappearedNumbers(vector<int>& nums) {int n = nums.size();// 使用負號標記法for (int i = 0; i < n; i++) {int index = abs(nums[i]) - 1; // 獲取對應的索引位置if (nums[index] > 0) {nums[index] = -nums[index]; // 標記為負數表示該數字存在}}vector<int> result;// 收集缺失的數字for (int i = 0; i < n; i++) {if (nums[i] > 0) {result.push_back(i + 1); // 索引+1就是缺失的數字}}return result;}
};

時間復雜度:O(n),空間復雜度:O(1)

我們目前要寫出來C++的寫法是非常考驗前面C++的學習情況好不好的,大家可以嘗試去寫一寫,優先掌握C語言的寫法,博主還沒有介紹C++的算法題,之后會涉及的,敬請期待!

我們可以用幾個示例來驗證一下——

對于輸入?[4, 3, 2, 7, 8, 2, 3, 1]

(1)第一次遍歷后數組變為:[-4, -3, -2, -7, 8, 2, -3, -1];

(2)位置4和5(索引從0開始)的值仍為正數,所以缺失的數字是5和6。

負號標記法這種方法高效且不需要額外的空間(除了輸出數組),非常適合處理大規模數據。

2.2.3? 為什么選擇負號標記法?

1、空間效率: 題目要求 O(1) 額外空間(不包括輸出數組);

2、時間效率: 需要 O(n) 時間復雜度;

3、利用現有數組: 既然數字范圍是 [1, n],我們可以用數組索引本身來記錄信息。

2.2.4? 負號標記法的巧妙之處

核心思想:用數組的索引位置來記錄數字是否存在。

具體操作:

(1)對于數字?x,我們去查看位置?x-1;

(2)如果該位置的值為正,我們就將其標記為負;

(3)這樣,最后仍然為正數的位置?i?就表示數字?i+1?不存在。

為什么這樣可行?

(1)因為數組索引從 0 到 n-1,正好對應數字 1 到 n;

(2)負號標記不會改變絕對值,所以不影響后續的判斷。

2.2.5? 與其他方法的對比

方法1:使用哈希表(不適用)

// 需要 O(n) 額外空間,不符合要求
unordered_set<int> seen;
for (int num : nums) seen.insert(num);
for (int i = 1; i <= n; i++) 
{if (!seen.count(i)) result.push_back(i);
}

方法2:排序后遍歷(不最優)

// 時間復雜度 O(n log n),空間復雜度 O(1) 但修改了原數組
sort(nums.begin(), nums.end());
// 然后遍歷檢查缺失數字

方法3:負號標記法(最優)

1、時間復雜度: O(n) - 兩次遍歷;

2、空間復雜度: O(1) - 原地修改,無需額外空間;

3、保持信息: 通過負號標記,既記錄了存在性,又保留了原始值的絕對值。


結尾

本文內容到這里就全部結束了,希望大家練習一下這幾道題目,這些基礎題最好完全掌握!

往期回顧:

【C語言16天強化訓練】從基礎入門到進階:Day 9

【C語言16天強化訓練】從基礎入門到進階:Day 8

【C語言16天強化訓練】從基礎入門到進階:Day 7

【C語言16天強化訓練】從基礎入門到進階:Day 6

【C語言16天強化訓練】從基礎入門到進階:Day 5

【C語言16天強化訓練】從基礎入門到進階:Day 4

【C語言16天強化訓練】從基礎入門到進階:Day 3

【C語言16天強化訓練】從基礎入門到進階:Day 2

【C語言16天強化訓練】從基礎入門到進階:Day 1

結語:感謝大家的閱讀,記得給博主“一鍵四連”,感謝友友們的支持和鼓勵!

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

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

相關文章

云計算與云原生技術探索

&#x1f31f; Hello&#xff0c;我是蔣星熠Jaxonic&#xff01; &#x1f308; 在浩瀚無垠的技術宇宙中&#xff0c;我是一名執著的星際旅人&#xff0c;用代碼繪制探索的軌跡。 &#x1f680; 每一個算法都是我點燃的推進器&#xff0c;每一行代碼都是我航行的星圖。 &#x…

STM32之ADC詳解

一、ADC概述 ADC&#xff08;模擬量轉數字量轉換器&#xff09;&#xff0c;在 STM32 開發中&#xff0c;利用 ADC 端口的電壓數據&#xff0c;轉換為對應的具體數字量數據內容。可通過 ADC 方式獲取常用數據內容有&#xff1a; 光敏電阻、電池電量、油箱油量 ADC 轉換…

深入理解計算機網絡:從基礎到應用的全面解析

標題&#xff1a;深入理解計算機網絡&#xff1a;從基礎到應用的全面解析 引言 計算機網絡已經滲透到我們生活的方方面面。從家庭Wi-Fi到全球互聯網&#xff0c;我們每天都在通過各種設備進行數據交換。本文將帶領你走進計算機網絡的世界&#xff0c;深入探討網絡的基礎知識、常…

以結構/序列/功能之間的關系重新定義蛋白質語言模型的分類:李明辰博士詳解蛋白質語言模型

上海交通大學第三屆「AI for Bioengineering 暑期學校」于 2025 年 8 月 8—10 日正式開啟。本次暑期學校匯聚了自全球 70 余所高校、 10 余所科研機構及 10 余家行業領軍企業的 200 余位青年才俊、科研學者和產業代表&#xff0c;共同聚焦于人工智能&#xff08;AI&#xff09…

【大語言模型 15】因果掩碼與注意力掩碼實現:深度學習中的信息流控制藝術

【大語言模型 15】因果掩碼與注意力掩碼實現&#xff1a;深度學習中的信息流控制藝術 關鍵詞&#xff1a;因果掩碼、注意力掩碼、下三角掩碼、Padding掩碼、序列建模、GPT解碼器、BERT編碼器、批量處理優化、自回歸語言模型、信息流控制 摘要&#xff1a;在Transformer架構中&a…

大型電動化工程機械設備智能施工試驗場的網絡設計方案

隨著工程機械設備逐步邁向智能化、電動化和無人化&#xff0c;傳統施工試驗場已經難以滿足現代化施工設備的研發、測試和驗證需求。為了適應這一趨勢&#xff0c;建設一個基于高性能網絡架構的大型智能施工試驗場成為關鍵。本文將從網絡架構、設備選型和功能實現等方面&#xf…

SPMI總線協議(一)

1、簡單說明 系統電源管理接口( System Power Management Interface簡稱SPMI)是一種雙線串行接口,用于連接片上系統(SoC)處理器系統的集成電源控制器(PC)與一個或多個電源管理集成電路(PMIC)電壓調節系統。SPMI 使系統能夠使用單個 SPMI 總線動態調整 SoC 內部電壓域的…

數據存儲的思考——從RocketMQ和Mysql的架構入手

數據存儲是后臺服務系統永遠繞不開的知識 筆者希望能夠從宏觀的角度出發&#xff0c;思考數據存儲系統的共性和設計方案&#xff0c;嘗試從Mysql和RocketMQ的角度去思考談談系統存儲架構的設計哲學 前置的知識 什么是RocketMQ、什么是Mysql&#xff0c;他們對于后端系統的主用…

MySQL 面試題系列(二)

目錄1: SQL 中常見的 JOIN 類型有哪些&#xff1f;請分別說明其連接邏輯和適用場景。2: UNION 和 UNION ALL 有什么區別&#xff1f;它們各自的適用場景是什么&#xff1f;3: 什么是視圖 (View)&#xff1f;它的作用和優缺點是什么&#xff1f;4: 什么是索引 (Index)&#xff1…

PostgreSQL診斷系列(2/6):鎖問題排查全攻略——揪出“阻塞元兇”

&#x1f517; 接上一篇《PostgreSQL全方位體檢指南》&#xff0c;今天我們深入數據庫的“神經系統”——鎖機制&#xff0c;解決最令人頭疼的“卡頓”問題。 你是否經歷過&#xff1a; 某個SQL執行著就不動了&#xff1f;應用界面卡在“加載中”&#xff1f;UPDATE 語句遲遲不…

crc16是什么算法

核心概念?CRC16? 是一種循環冗余校驗算法&#xff0c;屬于哈希函數的一種。它的核心目的是檢測數據的錯誤&#xff0c;通常用于數字網絡和存儲設備中&#xff0c;來驗證數據在傳輸或存儲后是否依然完整、無誤。你可以把它想象成一個數據的“指紋”或“摘要”。發送方計算出一…

Day8--HOT100--160. 相交鏈表,206. 反轉鏈表,234. 回文鏈表,876. 鏈表的中間結點

Day8–HOT100–160. 相交鏈表&#xff0c;206. 反轉鏈表&#xff0c;234. 回文鏈表&#xff0c;876. 鏈表的中間結點 每日刷題系列。今天的題目是力扣HOT100題單。 鏈表題目。 160. 相交鏈表 思路【我】&#xff1a; 1&#xff0c;計算鏈表長度 2&#xff0c;令A為較短鏈&am…

Rust面試題及詳細答案120道(58-65)-- 集合類型

《前后端面試題》專欄集合了前后端各個知識模塊的面試題&#xff0c;包括html&#xff0c;javascript&#xff0c;css&#xff0c;vue&#xff0c;react&#xff0c;java&#xff0c;Openlayers&#xff0c;leaflet&#xff0c;cesium&#xff0c;mapboxGL&#xff0c;threejs&…

Horse3D游戲引擎研發筆記(八):在QtOpenGL環境下,按需加載彩虹四邊形的頂點屬性 (Unity、Unreal Engine、Three.js與Godot)

在上一篇博客中&#xff0c;我們探討了如何在QtOpenGL環境下使用改進的Uniform變量管理方式繪制多彩四邊形。本文將延續這一主題&#xff0c;深入探討如何在QtOpenGL環境下按需加載彩虹四邊形的頂點屬性。這一功能是Horse3D引擎渲染系統的重要組成部分&#xff0c;旨在實現靈活…

模塊化設計+微米級精度,GelSight Modulus 觸覺型3D輪廓儀深入檢測“盲區”

當航空航天工程師在精密艙體中搜尋微米級缺陷&#xff0c;汽車檢查員在車間復雜結構里排查隱患&#xff0c;能源領域創新者嘗試突破檢測邊界時&#xff0c;深耕視觸覺 3D 顯微技術的企業——GelSight&#xff0c;正以全新研發的GelSight Modulus觸覺型3D輪廓儀&#xff08;簡稱…

Pytorch安裝詳細步驟

第一步&#xff1a;檢查顯卡支持的的CUDA版本 1.打開NVIDIA控制面板 首先鼠標右擊桌面-顯示更多選項-NVIDIA控制面板-點擊彈出界面右上角的(系統信息)-點擊彈出界面的(組件) 2.查看驅動版本 打開系統信息 點擊組件,查看 以觀測到紅色方框內的信息可以看到(NVIDIA CUDA 13.0.…

2025職場進階:低門檻技能實用手冊

每到年初&#xff0c;都會有人問&#xff1a;如果只能投入有限的時間與預算&#xff0c;先考哪一兩本證書更劃算&#xff1f;本文把近兩年的崗位需求、學習可獲得性與花費周期做了綜合權衡&#xff0c;給出一個以“先提升通用能力&#xff0c;再疊加行業資質”為主線的組合方案…

SDC命令詳解:使用set_timing_derate命令進行約束

相關閱讀 SDC命令詳解https://blog.csdn.net/weixin_45791458/category_12931432.html?spm1001.2014.3001.5482 目錄 指定降額比例 指定降額對象列表/集合 指定沿 指定最大、最小條件 指定早、晚條件 指定路徑的類型 指定降額類型 指定約束 指定增量 寫在最后 由于制造…

C++語言程序設計——03 進制ASCII碼

目錄一、進制表示與轉換&#xff08;一&#xff09;不同進制表示&#xff08;二&#xff09;進制轉換方法二、ASCII 碼&#xff08;一&#xff09;ASCII 碼表&#xff08;二&#xff09;ASCII 碼轉換&#xff08;三&#xff09;大小寫英文字母轉換【總結&#xff1a;如何記憶AS…

AtCoder Beginner Contest 420-Toggle Maze

題目描述 有一個 H行 W 列的網格。用 (i,j) 表示位于第 i 行&#xff08;從上往下數&#xff09;第 j 列&#xff08;從左往右數&#xff09;的格子。每個格子的狀態用字符 Ai,j表示&#xff0c;含義如下&#xff1a; . &#xff1a;空格子。 #’ &#xff1a;障礙格子。 S &am…