成人免费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

2013-12-17 09:02:03

Python調試

2013-12-31 09:19:23

Python調試

2023-05-23 13:59:41

RustPython程序

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

2020-11-17 15:31:23

Java微服務Go

2022-12-21 15:56:23

代碼文檔工具

2024-08-29 08:07:59

GoAPI開發

2014-09-22 09:27:57

Python

2020-08-25 08:56:55

Pythonawk字符串

2013-08-22 10:17:51

Google大數據業務價值

2015-03-16 12:50:44

2015-02-05 13:27:02

移動開發模塊SDK

2012-06-08 13:47:32

Wndows 8Vista

2011-01-18 10:45:16

喬布斯
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产福利在线 | 国产成人精品一区二 | 日本久久久久久 | 精品美女在线观看视频在线观看 | www久| 国产乱码精品一区二区三区五月婷 | 日本一级淫片免费啪啪3 | 国产91视频播放 | 欧美日韩国产在线观看 | 成人免费观看男女羞羞视频 | 福利视频一区 | 在线视频一区二区 | 日韩羞羞 | 日本视频免费 | 亚洲一一在线 | 中文字幕一区二区三区精彩视频 | 欧美精品久久久 | 久久成人国产精品 | 亚洲高清在线 | 一区二区三区四区不卡视频 | 九九热精品在线 | 欧美一区二区久久 | av中文字幕在线播放 | 日韩网站免费观看 | 国产精品成人一区二区 | 欧美成年视频 | 日韩在线不卡视频 | 一级电影免费看 | 古装三级在线播放 | 亚洲一区二区三区在线 | 日韩成人在线播放 | 中文字幕日本一区二区 | 中文字幕精品一区二区三区精品 | 一区二区三区成人 | 狠狠色狠狠色综合日日92 | 亚洲一区二区三区四区五区中文 | 一级片av | 91视频在线看 | 亚洲福利在线观看 | 亚洲色图综合 | 涩爱av一区二区三区 |