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 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
#include <iostream> #include <windows.h> //для поддержки русских символов #include <string> #include <cstring> using namespace std; //Будем инициализировать массив после создания его в памяти. void init_arr(char *&Arr, const int size) { for (int i = 0; i<size; i++) { Arr[i] = 0; } } //Проверка является ли символ символом-разделителем bool is_separator(const char &ch) { switch (ch) { case ' ': //case ' ': //Сюда можно добавлять любые разделители. по аналогии с прокомментированным кодом //case ',': return true; } return false; } //Функция читает число символов (т.к. <string.h> не используем, считаем руками сами) int str_len(char *S) { //Создается локальная копия указателя, поэтому любое его смещение не влияет на Передаваемый сюда массив символов. int count = 0; //Это число символов while (*S) { //Пока символ не нулевой count++; //Увеличивает счетчик символов *S++; //Используем адресную арифметику для смещения указателя на начало строки } return count; } void show(string Str) { const char *S = Str.c_str(); //Анализируемая строка const char *t = S; //Чуть позднее будет происходить смещение указателя на начало строки, поэтому запоминаем адрес на начало во временную переменную size_t size_string = Str.length(); //Запоминаем и размер основной строки. const int N = 255; //Размер длины строк в массиве строк /*Создаем двумерный массив. Это будет массив строк, в который мы запишем слова*/ char **MyStrinArray = new char*[size_string]; for (size_t i = 0; i<size_string; i++) { MyStrinArray[i] = new char[N]; init_arr(MyStrinArray[i], N); //Мало ли какой мусор может оказаться в созданной строке. Инициализируем для очистки } ///////////////////////////////////////////////// int j = 0; //Номер строки int k = 0; //Курсор, бегающий по строке, позиция символа /*Осталось заполнить массив словами*/ while (*S) { //Тут будет смещение указателя на начало строки, из-за этого создавалась t if (!is_separator(*S)) { //Если текущий символ НЕ является разделителем MyStrinArray[j][k] = *S; //Записываем его в строку на позицию к k++; //соответственно наращиваем к } //Если же разделитель else { k = 0; //Возвращаем k в начало j++; //Увеличиваем номер строки } //Проверка прошла, меняем указатель на начало строки, смещая его на следующий символ *S++; } for (size_t i = 0; i<size_string - 1; i++) { for (size_t j = i + 1; j<size_string; j++) { if (strcmp(MyStrinArray[i], MyStrinArray[j])>0) swap(MyStrinArray[i], MyStrinArray[j]); } } //Выводим на экран массив string buf; for (size_t i = 0; i<size_string; i++) { if (str_len(MyStrinArray[i])) buf = buf + MyStrinArray[i] + " "; //Нулевые строки пропускаем, они скорее всего нам бесполезны } cout << buf << "\n";; //////////////////////////////////////////////// //Очищаем память for (size_t i = 0; i<size_string; i++) delete[]MyStrinArray[i]; delete[]MyStrinArray; // S=t; //Возвращаем указатель на начало строки к изначальному адресу/ Вероятно исходная строка может еще потребоваться, поэтому так можно делать, если не надо, можно не делать. ; } /*ФУНКЦИЯ ВВОДА НЕОПРЕДЕЛЕННОГО ЧИСЛА СТРОК*/ string GetMyStr(int &count_word) { string S, temp; //S - это буферная строка, в нее читаем информацию с клавиатуры //temp - это итоговая строка, скомпилированная из всех полученных строк в S cout << "Для прекращения ввода нажми CTRL+Z или введи пустую строку (НАЖМИ Enter)\n"; while ((getline(cin, S)) && (S.length())>2) { //Считываем символы с клавиатуры temp = temp + S + '\n'; //Запоминаем строку в temp count_word++; //Увеличиваем счетчик строк } return temp; //Возвращаем скомпилированную строку } /*ФУНКЦИЯ ДЛЯ ПОЛУЧЕНИЯ СТРОКИ ПО НОМЕРУ СТРОКИ*/ string GetStrFromMyStr(string S, int N) { int i = 0; //Количество встреченных разделителей string buf; //Вытаскиваемая строка const char *temp = (S.c_str()); //Указатель на начало строки S while (i != N) { //Пока мы не встретим разделитель указанное число раз, будет цикл while (*temp != '\n') { //Ищем разделитель if (i == N - 1) buf = buf + *temp; //Если следующая итерация последняя, то начинаем собирать строчку (Это та самая, взятая по номеру) *temp++; //Переход к следующему символу } *temp++; //Переход к след символу i++; //Увеличиваем счетчик разделителей } return buf; //Возвращаем выбранную строчку } /*ФУНКЦИЯ СОРТИРОВКИ СТРОК*/ void sort(string *S, int N) { for (int i = 0; i < N - 1; i++) for (int j = i + 1; j < N; j++) { if (strcmp(S[i].c_str(), S[j].c_str())>0) swap(S[i], S[j]); } } int main() { setlocale(LC_ALL, ""); SetConsoleOutputCP(1251); SetConsoleCP(1251); int count_word = 0; string MyStr = GetMyStr(count_word); cout << "***********ЗАКОНЧИЛИ ВВОД ДАННЫХ***********\n\n"; //cout<<MyStr; //MyStr == многострочная строка //Пишем функцию для взятия любой строчки из оной GetStrFromMyStr (обратимся к ней позднее) string *S = new string[count_word]; //Массив строк //заполняем массив строками for (int i = 0; i<count_word; i++) { S[i] = GetStrFromMyStr(MyStr, i + 1); show(S[i]); } sort(S, count_word); //Сортруем массив //ВЫВОДИМ МАССИВ НА ЭКРАН for (int i = 0; i<count_word; i++) { // cout<<S[i]<<"\n"; } delete[]S; cin.get(); } |
Добавить комментарий