C++ Transform – 詳解

一、transform是什麼:

在C++標準庫中,transform函數是一個非常實用的演算法。它可以將一個給定的範圍(一個或多個容器)的每個元素應用到一個函數,並將該函數的結果存儲在另一容器中,或者覆蓋當前範圍。 代碼如下:

template 
OutputIterator transform (InputIterator first1, InputIterator last1, OutputIterator result, UnaryOperator op);

其中,first1和last1構成了一個區間,稱為源區間,表示一個向量或數組。result指向存儲器中的目標序列,是另一個向量或數組。op是轉換操作函數的對象。此函數的任務是將[first1,last1]內的每個元素轉換為op(*i),其中i是[first1,last1]所覆蓋區間的指向成員的迭代器。

二、transform與lambda表達式:

在應用transform函數時,我們可以使用lambda表達式作為操作函數。 Lambda表達式是一種C++的函數表示方式,它可以定義小型匿名函數。即變數可以在lambda函數中定義,在不用命名這些變數的情況下,可以給它們附加一個函數(或操作符)來作為匿名函數體。 例如:

std::vector from{1,2,3,4,5};
std::vector to(from.size());
std::transform(from.begin(), from.end(), to.begin(), [](int i){ return i * 2 ; });

這個例子中,lambda表達式[](int i) { return i * 2;}作為transform的第三個參數被傳遞。transform函數會取from序列中的每個元素,將它們傳遞給lambda表達式,並把返回結果賦值給to序列中相應位置的元素。在這個例子中,最終的結果將是to = [2,4,6,8,10]。這證明了,通過transform函數,我們可以輕鬆地使用lambda表達式對向量進行操作。

三、transform與自定義函數:

在使用transform函數時,我們還可以使用用戶自定義的函數作為操作函數。在使用自定義函數時,需要實現相應的轉換操作,以及確定第三個參數(目標序列存儲器)的類型。以下是一個將浮點數圓整為整數的示例:

#include 
#include 
#include 
#include 

int round_to_int(double x) 
{
    return static_cast(std::round(x));
}

int main()
{
    std::vector v{1.0, 2.2, 3.5, 4.7, 9.0};
    std::vector result(v.size());
    std::transform(v.begin(), v.end(), result.begin(), round_to_int);
    // result: [1, 2, 4, 5, 9];

    for(auto i : result)
    {
        std::cout << i << " ";
    }
    std::cout<<std::endl;

    return 0;
}

在本例中,我們向transform函數傳遞了一個指向轉換函數round_to_int的指針。函數round_to_int接收一個浮點數,將其四捨五入,返回相應的整數。函數指針作為操作函數的參數。元素被取自v序列,存儲在result序列中。 根據操作的特點以及需要的結果類型,我們選擇了使用int類型的序列作為結果序列存儲器。

四、transform與多個容器:

最後,transform函數可以處理多個容器。如果提供了多個源和目標序列,則在指定操作函數時應該使用並置二元函數。此時傳遞的函數接受兩個參數,分別是容器中的對應元素,而不是像unary_function接受的單個值。 下面是一個使用二進位函數操作兩個向量的簡單示例:

#include 
#include 
#include 

int sum(int x, int y)
{
    return x + y;
}

int main()
{
    std::vector v1 { 1, 2, 3, 4, 5 };
    std::vector v2 { 1, 1, 2, 2, 3 };
    std::vector result(v2.size());

    std::transform(v1.begin(), v1.end(), v2.begin(), result.begin(), sum);

    for(auto i : result)
    {
        std::cout << i << " ";
    }
    std::cout<<std::endl;

    return 0;
}

在這個例子中,我們有兩個容器v1和v2分別包含整數的元素,在transform函數中傳遞了一個求和函數,將結果存儲在相應位置的另一個容器中。在函數sum中,我們將兩個相對應的參數相加並返回結果。最後的結果是result = [2, 3, 5, 6, 8]。

總結:

本文介紹了C++標準庫中的一個非常實用的演算法——transform函數。我們詳細討論了transform函數的相關應用,包括使用lambda表達式和自定義函數完成轉換任務,以及如何操作多個容器。 類似於lambda表達式的功能,transform函數使代碼變得更短、更清晰,可讀性更高。通過更深入地學習及實踐,transform函數可以幫助開發者提高工作效率,使代碼量更少但實現同樣的功能。

原創文章,作者:FBEUT,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/370244.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
FBEUT的頭像FBEUT
上一篇 2025-04-18 13:40
下一篇 2025-04-18 13:40

相關推薦

  • 神經網路代碼詳解

    神經網路作為一種人工智慧技術,被廣泛應用於語音識別、圖像識別、自然語言處理等領域。而神經網路的模型編寫,離不開代碼。本文將從多個方面詳細闡述神經網路模型編寫的代碼技術。 一、神經網…

    編程 2025-04-25
  • Linux sync詳解

    一、sync概述 sync是Linux中一個非常重要的命令,它可以將文件系統緩存中的內容,強制寫入磁碟中。在執行sync之前,所有的文件系統更新將不會立即寫入磁碟,而是先緩存在內存…

    編程 2025-04-25
  • Python安裝OS庫詳解

    一、OS簡介 OS庫是Python標準庫的一部分,它提供了跨平台的操作系統功能,使得Python可以進行文件操作、進程管理、環境變數讀取等系統級操作。 OS庫中包含了大量的文件和目…

    編程 2025-04-25
  • git config user.name的詳解

    一、為什麼要使用git config user.name? git是一個非常流行的分散式版本控制系統,很多程序員都會用到它。在使用git commit提交代碼時,需要記錄commi…

    編程 2025-04-25
  • MPU6050工作原理詳解

    一、什麼是MPU6050 MPU6050是一種六軸慣性感測器,能夠同時測量加速度和角速度。它由三個感測器組成:一個三軸加速度計和一個三軸陀螺儀。這個組合提供了非常精細的姿態解算,其…

    編程 2025-04-25
  • nginx與apache應用開發詳解

    一、概述 nginx和apache都是常見的web伺服器。nginx是一個高性能的反向代理web伺服器,將負載均衡和緩存集成在了一起,可以動靜分離。apache是一個可擴展的web…

    編程 2025-04-25
  • Java BigDecimal 精度詳解

    一、基礎概念 Java BigDecimal 是一個用於高精度計算的類。普通的 double 或 float 類型只能精確表示有限的數字,而對於需要高精度計算的場景,BigDeci…

    編程 2025-04-25
  • 詳解eclipse設置

    一、安裝與基礎設置 1、下載eclipse並進行安裝。 2、打開eclipse,選擇對應的工作空間路徑。 File -> Switch Workspace -> [選擇…

    編程 2025-04-25
  • Python輸入輸出詳解

    一、文件讀寫 Python中文件的讀寫操作是必不可少的基本技能之一。讀寫文件分別使用open()函數中的’r’和’w’參數,讀取文件…

    編程 2025-04-25
  • Linux修改文件名命令詳解

    在Linux系統中,修改文件名是一個很常見的操作。Linux提供了多種方式來修改文件名,這篇文章將介紹Linux修改文件名的詳細操作。 一、mv命令 mv命令是Linux下的常用命…

    編程 2025-04-25

發表回復

登錄後才能評論