Манипуляции с массивами и строками в C++

C++C++Beginner
Практиковаться сейчас

💡 Этот учебник переведен с английского с помощью ИИ. Чтобы просмотреть оригинал, вы можете перейти на английский оригинал

Введение

В этом практическом занятии (лабораторной работе) вы научитесь работать с массивами и строками на языке C++. В рамках практики рассматриваются различные темы, такие как создание и инициализация одномерных массивов, доступ к элементам массива и их изменение, работа с двумерными массивами, использование строк в стиле C и класса String, сортировка элементов массива, выполнение линейного поиска и обработка ввода строк с использованием функции getline(). В результате выполнения этих практических упражнений вы получите тщательное понимание основных операций с массивами и строками в программировании на C++.

Создание и инициализация одномерных массивов

На этом этапе вы узнаете, как создавать и инициализировать одномерные массивы на языке C++. Массивы - это фундаментальные структуры данных, которые позволяют хранить несколько элементов одного типа в последовательных ячейках памяти.

Откройте WebIDE и создайте новый файл с именем arrays_intro.cpp в директории ~/project. Мы рассмотрим различные способы инициализации массивов.

touch ~/project/arrays_intro.cpp

Добавьте следующий код в файл arrays_intro.cpp:

#include <iostream>

int main() {
    // Method 1: Declare and initialize an array with specific size
    int numbers[5] = {10, 20, 30, 40, 50};

    // Method 2: Let compiler determine array size
    int scores[] = {85, 92, 78, 95, 88};

    // Method 3: Initialize array with default value zero
    int zeros[6] = {0};

    // Method 4: Create an array and initialize later
    int temperatures[4];
    temperatures[0] = 72;
    temperatures[1] = 68;
    temperatures[2] = 75;
    temperatures[3] = 80;

    // Print array elements
    std::cout << "First method - numbers array:" << std::endl;
    for (int i = 0; i < 5; i++) {
        std::cout << "Element " << i << ": " << numbers[i] << std::endl;
    }

    return 0;
}

Разберём инициализацию массивов:

  1. int numbers[5] = {10, 20, 30, 40, 50};: Явно определяем размер массива и инициализируем все элементы.
  2. int scores[] = {85, 92, 78, 95, 88};: Размер массива определяется компилятором.
  3. int zeros[6] = {0};: Инициализируем все элементы нулём.
  4. Вручную присваиваем значения с использованием индекса temperatures[index] = value.

Скомпилируйте и запустите программу:

g++ arrays_intro.cpp -o arrays_intro
./arrays_intro

Пример вывода:

First method - numbers array:
Element 0: 10
Element 1: 20
Element 2: 30
Element 3: 40
Element 4: 50

Основные моменты о массивах:

  • Размер массива фиксирован после объявления.
  • Индексация массивов начинается с 0.
  • Массивы можно инициализировать различными способами.
  • Всегда убедитесь, что не выходите за границы массива.

Доступ и изменение элементов массива по индексу

На этом этапе вы узнаете, как получить доступ к элементам массива и изменить их, используя их индексы в языке C++. Построив на предыдущем этапе инициализации массива, мы рассмотрим, как взаимодействовать с отдельными элементами массива.

Откройте WebIDE и создайте новый файл с именем array_indexing.cpp в директории ~/project:

touch ~/project/array_indexing.cpp

Добавьте следующий код в файл array_indexing.cpp:

#include <iostream>

int main() {
    // Create an array of student scores
    int scores[5] = {85, 92, 78, 95, 88};

    // Accessing array elements by index
    std::cout << "First student's score: " << scores[0] << std::endl;
    std::cout << "Third student's score: " << scores[2] << std::endl;

    // Modifying array elements
    std::cout << "Original second student's score: " << scores[1] << std::endl;
    scores[1] = 96; // Update the second student's score
    std::cout << "Updated second student's score: " << scores[1] << std::endl;

    // Calculating array element sum
    int total_score = 0;
    for (int i = 0; i < 5; i++) {
        total_score += scores[i];
    }
    std::cout << "Total class score: " << total_score << std::endl;

    // Average score calculation
    double average_score = static_cast<double>(total_score) / 5;
    std::cout << "Average class score: " << average_score << std::endl;

    return 0;
}

Основные моменты о индексации массивов:

  • Индексация массивов начинается с 0.
  • Используйте квадратные скобки [] для доступа к элементам.
  • Вы можете читать и изменять элементы, используя их индексы.
  • Будьте осторожны, чтобы не обращаться к индексам за пределами массива.

Скомпилируйте и запустите программу:

g++ array_indexing.cpp -o array_indexing
./array_indexing

Пример вывода:

First student's score: 85
Third student's score: 78
Original second student's score: 92
Updated second student's score: 96
Total class score: 442
Average class score: 88.4

Важные правила индексации:

  • Первый элемент имеет индекс 0.
  • Последний элемент имеет индекс (размер массива - 1).
  • Обращение к индексу за пределами диапазона массива приводит к неопределенному поведению.

Реализация двумерных массивов для матриц

На этом этапе вы узнаете, как создавать и работать с двумерными массивами на языке C++. Двумерные массивы похожи на таблицы или матрицы с строками и столбцами, что позволяет хранить и обрабатывать данные в структуре, похожей на сетку.

Откройте WebIDE и создайте новый файл с именем matrix_arrays.cpp в директории ~/project:

touch ~/project/matrix_arrays.cpp

Добавьте следующий код в файл matrix_arrays.cpp:

#include <iostream>

int main() {
    // Method 1: Declare and initialize a 3x3 matrix
    int matrix[3][3] = {
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9}
    };

    // Method 2: Declare matrix and initialize later
    int grades[2][4];
    grades[0][0] = 85;
    grades[0][1] = 92;
    grades[0][2] = 78;
    grades[0][3] = 95;
    grades[1][0] = 88;
    grades[1][1] = 90;
    grades[1][2] = 82;
    grades[1][3] = 87;

    // Print the first matrix
    std::cout << "First Matrix:" << std::endl;
    for (int row = 0; row < 3; row++) {
        for (int col = 0; col < 3; col++) {
            std::cout << matrix[row][col] << " ";
        }
        std::cout << std::endl;
    }

    // Print the grades matrix
    std::cout << "\nGrades Matrix:" << std::endl;
    for (int row = 0; row < 2; row++) {
        for (int col = 0; col < 4; col++) {
            std::cout << grades[row][col] << " ";
        }
        std::cout << std::endl;
    }

    return 0;
}

Основные моменты о двумерных массивах:

  • Используйте два индекса для доступа к элементам: array[row][column].
  • Первый индекс представляет строку, второй индекс представляет столбец.
  • Можно инициализировать различными способами.
  • Обычно используются вложенные циклы для перебора строк и столбцов.

Скомпилируйте и запустите программу:

g++ matrix_arrays.cpp -o matrix_arrays
./matrix_arrays

Пример вывода:

First Matrix:
1 2 3
4 5 6
7 8 9

Grades Matrix:
85 92 78 95
88 90 82 87

Важные концепции двумерных массивов:

  • Массивы могут иметь более двух размерностей.
  • Каждая строка может иметь разное количество столбцов.
  • Всегда будьте осторожны с границами массива, чтобы избежать ошибок.

Инициализация строк в стиле C с нулевым терминатором

На этом этапе вы узнаете о строках в стиле C и важности нулевого терминатора в языке C++. Строки в стиле C представляют собой массивы символов, которые заканчиваются специальным символом '\0', обозначающим конец строки.

Откройте WebIDE и создайте новый файл с именем c_style_strings.cpp в директории ~/project:

touch ~/project/c_style_strings.cpp

Добавьте следующий код в файл c_style_strings.cpp:

#include <iostream>
#include <cstring>

int main() {
    // Method 1: Initialize string with explicit null terminator
    char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
    std::cout << "Greeting: " << greeting << std::endl;

    // Method 2: Initialize as a string literal (automatically adds null terminator)
    char name[] = "John Doe";
    std::cout << "Name: " << name << std::endl;

    // Method 3: Declare with fixed size and initialize
    char message[20] = "Welcome to C++!";
    std::cout << "Message: " << message << std::endl;

    // Demonstrate string length
    std::cout << "Length of name: " << strlen(name) << std::endl;

    // Manual string length calculation
    int length = 0;
    while (name[length]!= '\0') {
        length++;
    }
    std::cout << "Manual length of name: " << length << std::endl;

    return 0;
}

Основные моменты о строках в стиле C:

  • Нулевой терминатор '\0' обозначает конец строки.
  • Всегда выделяйте на один символ больше для нулевого терминатора.
  • Строковые литералы автоматически добавляют нулевой терминатор.
  • Функция strlen() подсчитывает количество символов до нулевого терминатора.

Скомпилируйте и запустите программу:

g++ c_style_strings.cpp -o c_style_strings
./c_style_strings

Пример вывода:

Greeting: Hello
Name: John Doe
Message: Welcome to C++!
Length of name: 8
Manual length of name: 8

Важные концепции инициализации строк:

  • Нулевой терминатор является важной частью операций с строками.
  • Всегда убедитесь, что есть достаточно места для нулевого терминатора.
  • Будьте осторожны с размерами буферов строк, чтобы избежать переполнения.

Использование методов класса string (length, substr, find)

На этом этапе вы узнаете о мощных методах класса string в языке C++, которые упрощают и делают более интуитивным манипулирование строками. Мы рассмотрим ключевые методы, такие как length(), substr() и find().

Откройте WebIDE и создайте новый файл с именем string_methods.cpp в директории ~/project:

touch ~/project/string_methods.cpp

Добавьте следующий код в файл string_methods.cpp:

#include <iostream>
#include <string>

int main() {
    // Create a string
    std::string message = "Hello, C++ Programming!";

    // Using length() method
    std::cout << "String length: " << message.length() << std::endl;

    // Using substr() method
    std::cout << "First 5 characters: " << message.substr(0, 5) << std::endl;
    std::cout << "Substring from index 7: " << message.substr(7) << std::endl;

    // Using find() method
    std::string search_word = "Programming";
    size_t position = message.find(search_word);

    if (position!= std::string::npos) {
        std::cout << "'" << search_word << "' found at index: " << position << std::endl;
    } else {
        std::cout << "Word not found" << std::endl;
    }

    // Additional find() example
    std::string email = "[email protected]";
    size_t at_symbol = email.find('@');
    size_t dot_symbol = email.find('.');

    std::cout << "Username: " << email.substr(0, at_symbol) << std::endl;
    std::cout << "Domain: " << email.substr(at_symbol + 1, dot_symbol - at_symbol - 1) << std::endl;

    return 0;
}

Основные моменты о методах класса string:

  • length(): Возвращает количество символов в строке.
  • substr(): Извлекает часть строки.
    • Первый аргумент - индекс начала.
    • Второй аргумент (необязательный) - длина подстроки.
  • find(): Ищет подстроку или символ.
    • Возвращает индекс первого вхождения.
    • Возвращает std::string::npos, если не найдено.

Скомпилируйте и запустите программу:

g++ string_methods.cpp -o string_methods
./string_methods

Пример вывода:

String length: 23
First 5 characters: Hello
Substring from index 7: C++ Programming!
'Programming' found at index: 11
Username: user
Domain: example

Важные концепции методов строк:

  • Методы строк обеспечивают мощное манипулирование текстом.
  • Индексация начинается с 0.
  • Всегда проверяйте возвращаемые значения, чтобы обрабатывать возможные ошибки.

Преобразование между строками в стиле C и классом string

На этом этапе вы узнаете, как преобразовывать строки в стиле C в объекты класса string C++ и наоборот. Эти преобразования важны при работе с разными представлениями строк в C++.

Откройте WebIDE и создайте новый файл с именем string_conversion.cpp в директории ~/project:

touch ~/project/string_conversion.cpp

Добавьте следующий код в файл string_conversion.cpp:

#include <iostream>
#include <string>
#include <cstring>

int main() {
    // C-style string to C++ string
    const char* c_style_str = "Hello, C++ World!";
    std::string cpp_string(c_style_str);
    std::cout << "C++ String: " << cpp_string << std::endl;

    // C++ string to C-style string
    std::string message = "Converting strings";
    const char* c_str = message.c_str();
    std::cout << "C-style String: " << c_str << std::endl;

    // Manual conversion using strcpy
    char buffer[50];
    strcpy(buffer, message.c_str());
    std::cout << "Copied to buffer: " << buffer << std::endl;

    // String length comparison
    std::cout << "C++ string length: " << message.length() << std::endl;
    std::cout << "C-style string length: " << strlen(c_str) << std::endl;

    return 0;
}

Основные методы преобразования:

  • std::string(c_style_str): Преобразование строки в стиле C в строку C++.
  • .c_str(): Преобразование строки C++ в строку в стиле C.
  • strcpy(): Ручное копирование строки в символьный массив.

Скомпилируйте и запустите программу:

g++ string_conversion.cpp -o string_conversion
./string_conversion

Пример вывода:

C++ String: Hello, C++ World!
C-style String: Converting strings
Copied to buffer: Converting strings
C++ string length: 18
C-style string length: 18

Важные концепции преобразования:

  • Используйте .c_str(), чтобы получить const char* из строки C++.
  • Будьте осторожны с размерами буферов при преобразовании.
  • strlen() работает с строками в стиле C.
  • .length() работает с строками C++.

Сортировка элементов массива с использованием пузырьковой сортировки

На этом этапе вы узнаете, как реализовать алгоритм пузырьковой сортировки для сортировки элементов массива на языке C++. Пузырьковая сортировка - это простой метод сортировки, который многократно проходит по списку, сравнивает соседние элементы и меняет их местами, если они расположены в неправильном порядке.

Откройте WebIDE и создайте новый файл с именем bubble_sort.cpp в директории ~/project:

touch ~/project/bubble_sort.cpp

Добавьте следующий код в файл bubble_sort.cpp:

#include <iostream>

int main() {
    // Initialize an unsorted array
    int numbers[5] = {64, 34, 25, 12, 22};
    int size = 5;

    // Print original array
    std::cout << "Original Array: ";
    for (int i = 0; i < size; i++) {
        std::cout << numbers[i] << " ";
    }
    std::cout << std::endl;

    // Bubble Sort implementation
    for (int i = 0; i < size - 1; i++) {
        for (int j = 0; j < size - i - 1; j++) {
            // Compare adjacent elements
            if (numbers[j] > numbers[j + 1]) {
                // Swap elements
                int temp = numbers[j];
                numbers[j] = numbers[j + 1];
                numbers[j + 1] = temp;
            }
        }
    }

    // Print sorted array
    std::cout << "Sorted Array: ";
    for (int i = 0; i < size; i++) {
        std::cout << numbers[i] << " ";
    }
    std::cout << std::endl;

    return 0;
}

Основные концепции пузырьковой сортировки:

  • Сравнивает соседние элементы.
  • Меняет местами элементы, если они расположены в неправильном порядке.
  • Повторяет проходы по массиву до тех пор, пока он не будет отсортирован.
  • Временная сложность: O(n²).

Скомпилируйте и запустите программу:

g++ bubble_sort.cpp -o bubble_sort
./bubble_sort

Пример вывода:

Original Array: 64 34 25 12 22
Sorted Array: 12 22 25 34 64

Важные замечания о сортировке:

  • Пузырьковая сортировка проста, но неэффективна для больших массивов.
  • Хорошо подходит для образовательных целей.
  • Существуют более эффективные алгоритмы сортировки для реальных приложений.

Реализация линейного поиска в массивах

На этом этапе вы узнаете, как реализовать алгоритм линейного поиска на языке C++. Линейный поиск - это простой метод нахождения элемента в массиве, при котором каждый элемент проверяется последовательно до тех пор, пока не будет найден целевой элемент или не будет достигнут конец массива.

Откройте WebIDE и создайте новый файл с именем linear_search.cpp в директории ~/project:

touch ~/project/linear_search.cpp

Добавьте следующий код в файл linear_search.cpp:

#include <iostream>

int linearSearch(int arr[], int size, int target) {
    // Iterate through each element in the array
    for (int i = 0; i < size; i++) {
        // Check if current element matches the target
        if (arr[i] == target) {
            return i;  // Return the index if found
        }
    }
    return -1;  // Return -1 if target is not found
}

int main() {
    // Create an array of student scores
    int scores[] = {85, 92, 78, 95, 88, 76, 90};
    int size = sizeof(scores) / sizeof(scores[0]);

    // Target score to search
    int targetScore = 78;

    // Perform linear search
    int result = linearSearch(scores, size, targetScore);

    // Display search results
    if (result!= -1) {
        std::cout << "Target score " << targetScore
                  << " found at index " << result << std::endl;
    } else {
        std::cout << "Target score " << targetScore
                  << " not found in the array" << std::endl;
    }

    // Try another search
    int missingScore = 100;
    result = linearSearch(scores, size, missingScore);

    if (result!= -1) {
        std::cout << "Score " << missingScore
                  << " found at index " << result << std::endl;
    } else {
        std::cout << "Score " << missingScore
                  << " not found in the array" << std::endl;
    }

    return 0;
}

Основные концепции линейного поиска:

  • Последовательно проверяет каждый элемент массива.
  • Возвращает индекс целевого элемента, если он найден.
  • Возвращает -1, если целевой элемент не найден в массиве.
  • Временная сложность: O(n) - линейное время.
  • Прост в реализации и работает для неотсортированных массивов.

Скомпилируйте и запустите программу:

g++ linear_search.cpp -o linear_search
./linear_search

Пример вывода:

Target score 78 found at index 2
Score 100 not found in the array

Важные замечания о поиске:

  • Линейный поиск прост в понимании, но неэффективен для больших массивов.
  • Подходит для маленьких массивов или неотсортированных коллекций.
  • Существуют более эффективные алгоритмы поиска для отсортированных массивов.

Обработка строкового ввода с использованием getline()

На этом этапе вы узнаете, как использовать функцию getline() для чтения целых строк текстового ввода на языке C++. В отличие от cin >>, функция getline() может считывать строки, содержащие пробелы, и обрабатывать более сложные сценарии ввода.

Откройте WebIDE и создайте новый файл с именем getline_input.cpp в директории ~/project:

touch ~/project/getline_input.cpp

Добавьте следующий код в файл getline_input.cpp:

#include <iostream>
#include <string>

int main() {
    // Declare a string to store input
    std::string fullName;
    std::string address;

    // Prompt for full name input
    std::cout << "Enter your full name: ";
    std::getline(std::cin, fullName);

    // Prompt for address input
    std::cout << "Enter your full address: ";
    std::getline(std::cin, address);

    // Display input with additional information
    std::cout << "\n--- User Information ---" << std::endl;
    std::cout << "Name: " << fullName << std::endl;
    std::cout << "Address: " << address << std::endl;

    // Demonstrate reading multiple lines
    std::string multiLineText;
    std::cout << "\nEnter a multi-line description (press Ctrl+D to finish):" << std::endl;

    std::string line;
    while (std::getline(std::cin, line)) {
        multiLineText += line + "\n";
    }

    std::cout << "\nYour description:" << std::endl;
    std::cout << multiLineText;

    return 0;
}

Основные концепции использования getline():

  • Считывает целую строку текста, включая пробелы.
  • Синтаксис: std::getline(input_stream, string_variable).
  • Может считывать несколько строк ввода.
  • Умеет обрабатывать сложный ввод с пробелами.
  • Полезна для считывания полных имен, адресов и т.д.

Скомпилируйте программу:

g++ getline_input.cpp -o getline_input
./getline_input

Пример взаимодействия:

Enter your full name: John Michael Smith
Enter your full address: 123 Main Street, Anytown, USA

--- User Information ---
Name: John Michael Smith
Address: 123 Main Street, Anytown, USA

Enter a multi-line description (press Ctrl+D to finish):
This is a sample
multi-line description
with several lines of text.

Your description:
This is a sample
multi-line description
with several lines of text.

Важные замечания по обработке ввода:

  • getline() считывает текст до символа новой строки.
  • Полезна для захвата полного текстового ввода.
  • Может быть использована в сочетании с другими методами ввода.

Резюме

В этом практическом занятии (лабораторной работе) вы узнаете, как создавать и инициализировать одномерные массивы на языке C++, обращаться к элементам массива и изменять их с использованием индексов, реализовывать двумерные массивы для представления матриц, инициализировать строки в стиле C с нулевым терминатором, использовать методы класса string, преобразовывать строки в стиле C в объекты класса string и наоборот, сортировать элементы массива с помощью пузырьковой сортировки, реализовывать линейный поиск в массивах и обрабатывать строковый ввод с использованием функции getline().

Вы изучите различные способы инициализации массивов, включая явное указание размера и инициализацию всех элементов, автоматическое определение размера компилятором, инициализацию всех элементов нулями и ручное присвоение значений с использованием индексов. Вы также научитесь обращаться к элементам массива и изменять их с помощью индексов, а также обрабатывать границы массива, чтобы избежать ошибок. Кроме того, вы будете работать с двумерными массивами, строками в стиле C и классом string, узнав, как преобразовывать их друг в друга и выполнять различные операции с ними.