ホームページ > バックエンド開発 > C++ > C++ を使用して効率的なデータ圧縮とデータ ストレージを行うにはどうすればよいですか?

C++ を使用して効率的なデータ圧縮とデータ ストレージを行うにはどうすればよいですか?

王林
リリース: 2023-08-25 10:24:32
オリジナル
2360 人が閲覧しました

C++ を使用して効率的なデータ圧縮とデータ ストレージを行うにはどうすればよいですか?

C を使用して効率的なデータ圧縮とデータ ストレージを行うにはどうすればよいですか?

はじめに:
データ量が増加するにつれて、データ圧縮とデータストレージの重要性がますます高まっています。 C では、効率的なデータ圧縮と保存を実現する方法が数多くあります。この記事では、C での一般的なデータ圧縮アルゴリズムとデータ ストレージ技術をいくつか紹介し、対応するコード例を示します。

1. データ圧縮アルゴリズム

1.1 ハフマン符号化に基づく圧縮アルゴリズム
ハフマン符号化は、可変長符号化に基づくデータ圧縮アルゴリズムです。周波数の高い文字 (またはデータ ブロック) には短いコードを割り当て、周波数の低い文字 (またはデータ ブロック) には長いコードを割り当てることでデータを圧縮します。以下は、C を使用してハフマン コーディングを実装するためのサンプル コードです。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

#include <iostream>

#include <unordered_map>

#include <queue>

#include <string>

 

struct TreeNode {

    char data;

    int freq;

    TreeNode* left;

    TreeNode* right;

     

    TreeNode(char data, int freq) : data(data), freq(freq), left(nullptr), right(nullptr) {}

};

 

struct compare {

    bool operator()(TreeNode* a, TreeNode* b) {

        return a->freq > b->freq;

    }

};

 

void generateCodes(TreeNode* root, std::string code, std::unordered_map<char, std::string>& codes) {

    if (root->left == nullptr && root->right == nullptr) {

        codes[root->data] = code;

        return;

    }

    generateCodes(root->left, code + "0", codes);

    generateCodes(root->right, code + "1", codes);

}

 

void huffmanCompression(std::string input) {

    std::unordered_map<char, int> freqMap;

    for (char c : input) {

        freqMap[c]++;

    }

 

    std::priority_queue<TreeNode*, std::vector<TreeNode*>, compare> minHeap;

    for (auto& entry : freqMap) {

        minHeap.push(new TreeNode(entry.first, entry.second));

    }

 

    while (minHeap.size() > 1) {

        TreeNode* left = minHeap.top();

        minHeap.pop();

        TreeNode* right = minHeap.top();

        minHeap.pop();

         

        TreeNode* parent = new TreeNode('', left->freq + right->freq);

        parent->left = left;

        parent->right = right;

        minHeap.push(parent);

    }

 

    TreeNode* root = minHeap.top();

    std::unordered_map<char, std::string> codes;

    generateCodes(root, "", codes);

 

    std::string compressed;

    for (char c : input) {

        compressed += codes[c];

    }

 

    std::cout << "Compressed: " << compressed << std::endl;

    std::cout << "Uncompressed: " << input << std::endl;

    std::cout << "Compression ratio: " << (double)compressed.size() / input.size() << std::endl;

 

    // 清理内存

    delete root;

}

 

int main() {

    std::string input = "abracadabra";

    huffmanCompression(input);

    return 0;

}

ログイン後にコピー

1.2 Lempel-Ziv-Welch (LZW) アルゴリズム
LZW アルゴリズムは、GIF 画像形式で一般的に使用される可逆データ圧縮アルゴリズムです。辞書を使用して既存の文字列を保存し、辞書を継続的に拡張することで圧縮文字列の長さを削減します。以下は、C を使用して LZW アルゴリズムを実装するサンプル コードです:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

#include <iostream>

#include <unordered_map>

#include <string>

 

void lzwCompression(std::string input) {

    std::unordered_map<std::string, int> dictionary;

    for (int i = 0; i < 256; i++) {

        dictionary[std::string(1, i)] = i;

    }

 

    std::string output;

    std::string current;

    for (char c : input) {

        std::string temp = current + c;

        if (dictionary.find(temp) != dictionary.end()) {

            current = temp;

        } else {

            output += std::to_string(dictionary[current]) + " ";

            dictionary[temp] = dictionary.size();

            current = std::string(1, c);

        }

    }

 

    if (!current.empty()) {

        output += std::to_string(dictionary[current]) + " ";

    }

 

    std::cout << "Compressed: " << output << std::endl;

    std::cout << "Uncompressed: " << input << std::endl;

    std::cout << "Compression ratio: " << (double)output.size() / input.size() << std::endl;

}

 

int main() {

    std::string input = "abracadabra";

    lzwCompression(input);

    return 0;

}

ログイン後にコピー

2. データ ストレージ テクノロジー

2.1 バイナリ ファイル ストレージ
バイナリ ファイル ストレージは、データをファイルに書き込む方法です。バイナリ形式のメソッド。テキスト ファイル ストレージと比較して、バイナリ ファイル ストレージはストレージ領域を節約し、読み取りと書き込みを高速化できます。以下は、C を使用してバイナリ ファイル ストレージを実装するためのサンプル コードです。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

#include <iostream>

#include <fstream>

 

struct Data {

    int i;

    double d;

    char c;

};

 

void binaryFileStorage(Data data) {

    std::ofstream outfile("data.bin", std::ios::binary);

    outfile.write(reinterpret_cast<char*>(&data), sizeof(data));

    outfile.close();

 

    std::ifstream infile("data.bin", std::ios::binary);

    Data readData;

    infile.read(reinterpret_cast<char*>(&readData), sizeof(readData));

    infile.close();

 

    std::cout << "Original: " << data.i << ", " << data.d << ", " << data.c << std::endl;

    std::cout << "Read from file: " << readData.i << ", " << readData.d << ", " << readData.c << std::endl;

}

 

int main() {

    Data data {42, 3.14, 'A'};

    binaryFileStorage(data);

    return 0;

}

ログイン後にコピー

2.2 圧縮ファイル ストレージ
圧縮ファイル ストレージは、データを圧縮形式でファイルに書き込む方法です。圧縮ファイルストレージはストレージスペースを節約できますが、読み取りと書き込みの速度は遅くなります。以下は、C を使用した圧縮ファイル ストレージのサンプル コードです。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

#include <iostream>

#include <fstream>

#include <sstream>

#include <iomanip>

#include <zlib.h>

 

void compressFileStorage(std::string input) {

    std::ostringstream compressedStream;

    z_stream defStream;

    defStream.zalloc = Z_NULL;

    defStream.zfree = Z_NULL;

    defStream.opaque = Z_NULL;

    defStream.avail_in = input.size();

    defStream.next_in = (Bytef*)input.c_str();

    defStream.avail_out = input.size() + (input.size() / 100) + 12;

    defStream.next_out = (Bytef*)compressedStream.str().c_str();

 

    deflateInit(&defStream, Z_DEFAULT_COMPRESSION);

    deflate(&defStream, Z_FINISH);

    deflateEnd(&defStream);

 

    std::string compressed = compressedStream.str();

 

    std::ofstream outfile("compressed.txt", std::ios::binary);

    outfile.write(compressed.c_str(), compressed.size());

    outfile.close();

 

    std::ifstream infile("compressed.txt", std::ios::binary);

    std::ostringstream decompressedStream;

    z_stream infStream;

    infStream.zalloc = Z_NULL;

    infStream.zfree = Z_NULL;

    infStream.opaque = Z_NULL;

    infStream.avail_in = compressed.size();

    infStream.next_in = (Bytef*)compressed.c_str();

    infStream.avail_out = compressed.size() * 10;

    infStream.next_out = (Bytef*)decompressedStream.str().c_str();

 

    inflateInit(&infStream);

    inflate(&infStream, Z_NO_FLUSH);

    inflateEnd(&infStream);

 

    std::string decompressed = decompressedStream.str();

 

    std::cout << "Original: " << input << std::endl;

    std::cout << "Compressed: " << compressed << std::endl;

    std::cout << "Decompressed: " << decompressed << std::endl;

}

 

int main() {

    std::string input = "abracadabra";

    compressFileStorage(input);

    return 0;

}

ログイン後にコピー

結論:
この記事では、C でのいくつかの一般的なデータ圧縮アルゴリズムとデータ ストレージ テクノロジを紹介し、対応するコード例を示します。適切なデータ圧縮アルゴリズムとストレージ テクノロジを選択することで、効率的なデータ圧縮とストレージを実現できます。実際のアプリケーションでは、データの特性とニーズに基づいて最適な方法を選択できます。

以上がC++ を使用して効率的なデータ圧縮とデータ ストレージを行うにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート