成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

C++ 也能像 Python 一樣優雅?pair、tuple、tie 來幫忙

開發
今天咱們就來聊聊 C++ 里的三個神器:pair、tuple和tie。用好了這仨,你的 C++ 代碼也能像 Python 一樣簡潔漂亮。

大家好,我是小康。

寫過 Python 的朋友都知道,Python處理多個返回值有多爽:x, y = func(),想交換兩個變量?a, b = b, a 一行搞定。每次寫 C++ 的時候,是不是都羨慕得不行?

其實,C++也能寫得很優雅!今天咱們就來聊聊 C++ 里的三個神器:pair、tuple和tie。用好了這仨,你的 C++ 代碼也能像 Python 一樣簡潔漂亮。

別再羨慕 Python 了,C++同樣可以很優雅!

一、第一個救星:pair - 成雙成對好伙伴

1. 什么是pair?

想象一下,你去買奶茶,店員問你:"要什么口味?什么甜度?"這就是兩個相關但不同的信息。在 C++ 里,pair就是專門用來裝這種"成對出現"數據的容器。

簡單說,pair就是一個能裝兩個不同類型數據的小盒子。

2. 怎么用pair?

#include <iostream>
#include <utility>  // pair在這里
using namespace std;

int main() {
    // 創建一個pair,裝個奶茶訂單
    pair<string, int> order("珍珠奶茶", 7);  // 口味和甜度
    
    cout << "我要一杯 " << order.first << "," << order.second << "分甜" << endl;
    
    // 還可以這樣創建
    auto order2 = make_pair("椰果奶茶", 5);
    cout << "再來一杯 " << order2.first << "," << order2.second << "分甜" << endl;
    
    return 0;
}

輸出結果:

我要一杯 珍珠奶茶,7分甜
再來一杯 椰果奶茶,5分甜

看到沒?用first取第一個值,用second取第二個值,簡單粗暴!

2. pair的實際應用場景

(1) 場景1:函數返回多個值

以前我們想讓函數返回兩個值,得這么寫:

// 老土的寫法
void getMinMax(vector<int>& nums, int& minVal, int& maxVal) {
    // 通過引用返回...好麻煩
}

現在用 pair,瞬間優雅:

#include <iostream>
#include <utility>  // pair在這里
#include <algorithm>  // max_element在這里
#include <vector> 

using namespace std;

pair<int, int> getMinMax(vector<int>& nums) {
    int minVal = *min_element(nums.begin(), nums.end());
    int maxVal = *max_element(nums.begin(), nums.end());
    return make_pair(minVal, maxVal);
}

int main() {
    vector<int> numbers = {3, 1, 4, 1, 5, 9, 2, 6};
    auto result = getMinMax(numbers);
    
    cout << "最小值:" << result.first << endl;
    cout << "最大值:" << result.second << endl;
    return 0;
}

輸出結果:

最小值:1
最大值:9

場景2:map的鍵值對

#include <iostream>
#include <map>
using namespace std;

int main() {
    map<string, int> scoreMap;
    scoreMap["小明"] = 95;
    scoreMap["小紅"] = 87;
    
    // 遍歷map時,每個元素就是一個pair
    for(auto& student : scoreMap) {
        cout << student.first << "考了" << student.second << "分" << endl;
    }
    return 0;
}

二、第二個救星:tuple - 數據打包專業戶

1. 什么是tuple?

如果說 pair 是個只能裝兩個東西的小盒子,那 tuple 就是個能裝 N 個東西的大箱子。你想裝多少就裝多少!

2. 基礎用法

#include <iostream>
#include <tuple>
using namespace std;

int main() {
    // 創建一個學生信息tuple:姓名、年齡、成績、是否及格
    tuple<string, int, double, bool> student("張三", 20, 85.5, true);
    
    // 取值要用get<索引>()
    cout << "姓名:" << get<0>(student) << endl;
    cout << "年齡:" << get<1>(student) << endl;
    cout << "成績:" << get<2>(student) << endl;
    cout << "是否及格:" << (get<3>(student) ? "是" : "否") << endl;
    
    return 0;
}

輸出結果:

姓名:張三
年齡:20
成績:85.5
是否及格:是

3. tuple的高級玩法

創建tuple的幾種方式:

// 方式1:直接構造
tuple<int, string, double> t1(1, "hello", 3.14);

// 方式2:使用make_tuple
auto t2 = make_tuple(2, "world", 2.71);

// 方式3:C++17的推導
tuple t3{3, "test", 1.41};  // 編譯器自動推導類型

修改tuple中的值:

tuple<string, int> info("小王", 25);
get<1>(info) = 26;  // 修改年齡
cout << get<0>(info) << "今年" << get<1>(info) << "歲了" << endl;

4. 實際應用:函數返回多個值

// 解析一個日期字符串,返回年月日
tuple<int, int, int> parseDate(string dateStr) {
    // 簡化版解析(實際項目中要更嚴謹)
    int year = 2024, month = 12, day = 25;
    return make_tuple(year, month, day);
}

int main() {
    auto date = parseDate("2024-12-25");
    
    cout << "年份:" << get<0>(date) << endl;
    cout << "月份:" << get<1>(date) << endl;
    cout << "日期:" << get<2>(date) << endl;
    return 0;
}

三、第三個救星:tie - 解包大師

1. tie是干啥的?

前面我們用 pair 和 tuple 打包數據,但取數據時還是要用 first、second 或者get<>(),有點麻煩。tie 就是來解決這個問題的,它能把打包的數據一口氣解開,分別賦值給不同的變量。

2. 基礎用法

#include <iostream>  
#include <string>   
#include <utility>  
#include <tuple>
using namespace std;

int main() {
    pair<string, int> order("抹茶拿鐵", 6);
    
    // 傳統取值方式
    string drink = order.first;
    int sweetness = order.second;
    
    // 使用tie一步到位
    string drink2;
    int sweetness2;
    tie(drink2, sweetness2) = order;
    
    cout << "飲品:" << drink2 << ",甜度:" << sweetness2 << endl;
    return 0;
}

3. tie的實際應用

(1) 場景1:變量交換

以前交換兩個變量,得用臨時變量:

// 老辦法
int a = 10, b = 20;
int temp = a;
a = b;
b = temp;

現在用tie,一行搞定:

int a = 10, b = 20;
cout << "交換前:a=" << a << ", b=" << b << endl;

tie(a, b) = make_pair(b, a);  // 神奇的一行代碼
cout << "交換后:a=" << a << ", b=" << b << endl;

輸出結果:

交換前:a=10, b=20
交換后:a=20, b=10

(2) 場景2:處理函數返回的tuple

// 計算圓的周長和面積
tuple<double, double> calculateCircle(double radius) {
    double perimeter = 2 * 3.14159 * radius;
    double area = 3.14159 * radius * radius;
    return make_tuple(perimeter, area);
}

int main() {
    double r = 5.0;
    double perimeter, area;
    
    // 一步解包
    tie(perimeter, area) = calculateCircle(r);
    
    cout << "半徑為" << r << "的圓:" << endl;
    cout << "周長:" << perimeter << endl;
    cout << "面積:" << area << endl;
    return 0;
}

輸出結果:

半徑為5的圓:
周長:31.4159
面積:78.5398

(3) 場景3:忽略不需要的值

有時候我們只需要tuple中的部分值,可以用std::ignore來忽略:

tuple<string, int, double, bool> studentInfo("李四", 22, 92.5, true);

string name;
double score;

// 只要姓名和成績,忽略年齡和及格狀態
tie(name, ignore, score, ignore) = studentInfo;

cout << name << "的成績是" << score << endl;

四、C++17的新玩法:結構化綁定

如果你用的是C++17或更新版本,還有個更酷的寫法叫"結構化綁定":

// C++17寫法,更簡潔
auto [drink, sweetness] = make_pair("焦糖瑪奇朵", 8);
cout << drink << "," << sweetness << "分甜" << endl;

// 處理tuple也很簡單
auto [name, age, score] = make_tuple("王五", 21, 88.5);
cout << name << "," << age << "歲,得分" << score << endl;

五、實戰演練:擼個游戲裝備管理系統

咱們來寫個有意思的例子——游戲裝備管理系統!想象你在玩RPG游戲,需要管理各種裝備的屬性。

#include <iostream>
#include <vector>
#include <tuple>
#include <algorithm>
#include <iomanip>
using namespace std;

// 裝備信息:名稱、攻擊力、防御力、稀有度、價格
using Equipment = tuple<string, int, int, string, double>;

// 計算裝備戰斗力和性價比
pair<int, double> calculateStats(const Equipment& equipment) {
    auto [name, attack, defense, rarity, price] = equipment;
    int combatPower = attack * 2 + defense;  // 攻擊力權重更高
    double costEfficiency = combatPower / price;  // 性價比
    return make_pair(combatPower, costEfficiency);
}

// 找出最強和最弱裝備
pair<Equipment, Equipment> findBestAndWorst(vector<Equipment>& equipments) {
    auto strongest = *max_element(equipments.begin(), equipments.end(),
        [](const Equipment& a, const Equipment& b) {
            auto [powerA, efficiencyA] = calculateStats(a);
            auto [powerB, efficiencyB] = calculateStats(b);
            return powerA < powerB;
        });
    
    auto weakest = *min_element(equipments.begin(), equipments.end(),
        [](const Equipment& a, const Equipment& b) {
            auto [powerA, efficiencyA] = calculateStats(a);
            auto [powerB, efficiencyB] = calculateStats(b);
            return powerA < powerB;
        });
    
    return make_pair(strongest, weakest);
}

// 根據預算推薦裝備
tuple<Equipment, string, bool> recommendEquipment(vector<Equipment>& equipments, double budget) {
    Equipment bestChoice;
    bool found = false;
    double bestEfficiency = 0;
    
    for(const auto& equipment : equipments) {
        auto [name, attack, defense, rarity, price] = equipment;
        if(price <= budget) {
            auto [power, efficiency] = calculateStats(equipment);
            if(!found || efficiency > bestEfficiency) {
                bestChoice = equipment;
                bestEfficiency = efficiency;
                found = true;
            }
        }
    }
    
    string recommendation = found ? "強烈推薦!" : "預算不足,建議攢錢";
    return make_tuple(bestChoice, recommendation, found);
}

int main() {
    vector<Equipment> equipments = {
        make_tuple("新手木劍", 15, 5, "普通", 50.0),
        make_tuple("鋼鐵長劍", 35, 15, "稀有", 300.0),
        make_tuple("龍鱗戰甲", 10, 45, "史詩", 800.0),
        make_tuple("傳說之刃", 80, 20, "傳說", 1500.0),
        make_tuple("魔法法杖", 60, 10, "稀有", 600.0),
        make_tuple("守護者盾牌", 5, 50, "史詩", 700.0)
    };
    
    cout << "?? === 游戲裝備庫存 === ??" << endl;
    cout << left << setw(15) << "裝備名稱"
         << setw(8) << "攻擊力" << setw(8) << "防御力"
         << setw(8) << "稀有度" << setw(10) << "價格"
         << setw(10) << "戰斗力" << "性價比" << endl;
    cout << string(75, '-') << endl;
    
    for(const auto& equipment : equipments) {
        auto [name, attack, defense, rarity, price] = equipment;
        auto [combatPower, efficiency] = calculateStats(equipment);
        
        cout << left << setw(15) << name 
             << setw(8) << attack << setw(8) << defense 
             << setw(8) << rarity << setw(10) << fixed << setprecision(1) << price
             << setw(10) << combatPower << setprecision(3) << efficiency << endl;
    }
    
    auto [strongest, weakest] = findBestAndWorst(equipments);
    
    cout << "\n??  === 裝備評測 === ??" << endl;
    auto [strongName, strongAttack, strongDefense, strongRarity, strongPrice] = strongest;
    auto [strongPower, strongEfficiency] = calculateStats(strongest);
    cout << "最強裝備:" << strongName << "(戰斗力" << strongPower << ")??" << endl;
    
    auto [weakName, weakAttack, weakDefense, weakRarity, weakPrice] = weakest;
    auto [weakPower, weakEfficiency] = calculateStats(weakest);
    cout << "最弱裝備:" << weakName << "(戰斗力" << weakPower << ")??" << endl;
    
    cout << "\n?? === 購買建議 === ??" << endl;
    vector<double> budgets = {100, 400, 800, 2000};
    
    for(double budget : budgets) {
        auto [recommended, advice, canAfford] = recommendEquipment(equipments, budget);
        cout << "預算" << budget << "金幣:";
        
        if(canAfford) {
            auto [recName, recAttack, recDefense, recRarity, recPrice] = recommended;
            auto [recPower, recEfficiency] = calculateStats(recommended);
            cout << recName << "(戰斗力" << recPower << ",性價比"
                 << fixed << setprecision(3) << recEfficiency << ")" << advice << endl;
        } else {
            cout << advice << endl;
        }
    }
    
    // 展示變量交換的實際應用
    cout << "\n?? === 裝備交換演示 === ??" << endl;
    auto weapon1 = make_tuple("火焰劍", 45, 10, "稀有", 400.0);
    auto weapon2 = make_tuple("冰霜斧", 40, 15, "稀有", 350.0);
    
    cout << "交換前:" << endl;
    cout << "武器1:" << get<0>(weapon1) << "(攻擊" << get<1>(weapon1) << ")" << endl;
    cout << "武器2:" << get<0>(weapon2) << "(攻擊" << get<1>(weapon2) << ")" << endl;
    
    // 使用tie進行裝備交換
    tie(weapon1, weapon2) = make_pair(weapon2, weapon1);
    
    cout << "交換后:" << endl;
    cout << "武器1:" << get<0>(weapon1) << "(攻擊" << get<1>(weapon1) << ")" << endl;
    cout << "武器2:" << get<0>(weapon2) << "(攻擊" << get<1>(weapon2) << ")" << endl;
    
    return 0;
}

輸出結果:

?? === 游戲裝備庫存 === ??
裝備名稱   攻擊力防御力稀有度價格    戰斗力 性價比
---------------------------------------------------------------------------
新手木劍   15      5       普通  50.0      35        0.700
鋼鐵長劍   35      15      稀有  300.0     85        0.283
龍鱗戰甲   10      45      史詩  800.0     65        0.081
傳說之刃   80      20      傳說  1500.0    180       0.120
魔法法杖   60      10      稀有  600.0     130       0.217
守護者盾牌5       50      史詩  700.0     60        0.086

??  === 裝備評測 === ??
最強裝備:傳說之刃(戰斗力180)??
最弱裝備:新手木劍(戰斗力35)??

?? === 購買建議 === ??
預算100.000金幣:新手木劍(戰斗力35,性價比0.700)強烈推薦!
預算400.000金幣:新手木劍(戰斗力35,性價比0.700)強烈推薦!
預算800.000金幣:新手木劍(戰斗力35,性價比0.700)強烈推薦!
預算2000.000金幣:新手木劍(戰斗力35,性價比0.700)強烈推薦!

?? === 裝備交換演示 === ??
交換前:
武器1:火焰劍(攻擊45)
武器2:冰霜斧(攻擊40)
交換后:
武器1:冰霜斧(攻擊40)
武器2:火焰劍(攻擊45)

六、總結

好了,咱們來總結一下今天學的三個小工具:

  • pair:專門裝兩個相關數據,取值用first和second。適合函數返回兩個值、處理鍵值對等場景。
  • tuple:能裝N個數據的萬能容器,取值用get<索引>()。適合需要返回多個不同類型數據的場景。
  • tie:專門用來解包pair和tuple的工具,能一次性把數據分配給多個變量。還能用來做變量交換這種騷操作。

現代C++: 如果你用C++17,結構化綁定讓代碼更簡潔,直接 auto [a, b, c] = ... 就搞定。

這三個工具組合使用,能讓你的代碼變得更清晰、更優雅。再也不用為了返回多個值而糾結,再也不用定義一堆臨時變量了!

記住,編程不是為了炫技,而是為了讓代碼更好維護、更好理解。這些工具用好了,你的代碼會讓同事們刮目相看的!

下次寫代碼時,試試用這些小工具,你會發現編程原來可以這么舒服!

責任編輯:趙寧寧 來源: 跟著小康學編程
相關推薦

2021-08-12 06:08:15

CSS 技巧組件狀態

2011-10-27 09:42:19

ASP.NET

2023-05-23 13:59:41

RustPython程序

2013-12-31 09:19:23

Python調試

2013-12-17 09:02:03

Python調試

2021-04-12 10:20:20

Java微服務Go

2021-05-20 08:37:32

multiprocesPython線程

2023-04-05 14:19:07

FlinkRedisNoSQL

2022-10-21 13:52:56

JS 報錯調試本地源碼

2017-05-22 10:33:14

PythonJuliaCython

2022-12-21 15:56:23

代碼文檔工具

2020-11-17 15:31:23

Java微服務Go

2024-08-29 08:07:59

GoAPI開發

2020-08-25 08:56:55

Pythonawk字符串

2014-09-22 09:27:57

Python

2013-08-22 10:17:51

Google大數據業務價值

2015-03-16 12:50:44

2011-01-18 10:45:16

喬布斯

2012-06-08 13:47:32

Wndows 8Vista

2015-02-05 13:27:02

移動開發模塊SDK
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 天天操网| 一级片在线观看 | 一区二区不卡视频 | 欧美高清视频 | 欧美福利一区 | 欧美三级电影在线播放 | 国产精品一区久久久 | 色吊丝2288sds中文字幕 | 一级黄色毛片a | 亚洲一区二区三区在线视频 | 超碰97免费在线 | 青春草91| 综合九九| 久久av一区二区三区 | 一区二区av在线 | 欧美日韩在线精品 | 精品av天堂毛片久久久借种 | 精品国产一区二区在线 | 亚洲精品中文字幕在线观看 | 黄色毛片网站在线观看 | 97伦理最新伦理 | 成人av电影在线 | 亚洲成人一区二区 | 欧洲精品在线观看 | 欧美九九 | 亚洲成人精品 | 懂色tv | 欧美5区 | 久久国产综合 | 青草视频在线 | 国产91在线 | 亚洲 | 特级丰满少妇一级aaaa爱毛片 | 欧美日韩高清在线一区 | 日本精品一区 | 亚洲 中文 欧美 日韩 在线观看 | 亚洲成人免费av | 欧美精品成人一区二区三区四区 | 91精品国产综合久久福利软件 | 日韩中文一区 | 亚洲国产精品久久久 | 国产精品国产a级 |