Осуществить сортировку строк по наиболее длинному слову в порядке неубывания.

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Ответить
Kazanove
Сообщения: 41
Зарегистрирован: 24 фев 2016, 14:55

ЗАДАЧА
Задан текст, состоящий из строк. Строк не менее 10. В строке не менее 5
слов. В слове не менее 5 символов. Слова разделены 1 пробелом.
Осуществить сортировку строк по наиболее длинному слову в порядке
не убывания.
Программа должна выполнять ввод текста, вывод его исходного варианта,
выполнять необходимые действия и выводить полученный текст.

СИ

Код: Выделить всё

#include <stdio.h>
#include <windows.h>

char* Rus(const char* text);

void main(void){
	int minString = 10;
	int minWord = 5;
	int minSymbol = 5;
	const int maxString = 20;
	const int maxSymbol = 100;
	static char buffer[maxString][maxSymbol];
	char input[maxString][maxSymbol];
	int arrLen[maxString];
	int row = 0;

	printf(Rus("Введите не мение %d строк. В строке не менее %d слов.\nВ слове не менее %d символов. Слова разделены 1 пробелом\n"), minString, minWord, minSymbol);
	printf(Rus("Для прекращения ввода нажмите <Enter> в начале строки.\n\n"));
	while (gets_s(buffer[row]) != NULL && row < maxString){
		if (strcmp(buffer[row], "") == 0){
			if (row < minString){
				printf(Rus("Вы должны ввести не менее %d строк(введено %d)\n"), minString, row);
				continue;
			}
			break;
		}
		strcpy(input[row], buffer[row]);
		char *pWord = strtok(buffer[row], " ");
		int countWord = 0;
		bool error = false;
		arrLen[row] = 0;
		while (pWord){
			if (strlen(pWord) < minSymbol){
				printf(Rus("Слово доолжно стоять не мение из %d символов (состоит из %d)\n"), minSymbol, strlen(pWord));
				error = true;
				break;
			}
			if (arrLen[row] < strlen(pWord)){
				arrLen[row] = strlen(pWord);
			}
			pWord = strtok(NULL, " ");
			countWord++;
		}

		if (error){
			continue;
		}
		else if (countWord < minWord){
			printf(Rus("Вы должны ввести не менее %d слов (введено %d)\n"), minWord, countWord);
		}
		else{
			row++;
		}
	}

	for (int i = 0; i < row; i++){
		int tmpLen = arrLen[i];
		char *tmpInp = input[i];
		for (int j = i; j < row; j++){
			if (tmpLen>arrLen[j]){
				tmpLen = arrLen[j];
				arrLen[j] = arrLen[i];
				arrLen[i] = tmpLen;
				strcpy(tmpInp, input[j]);
				strcpy(input[j], input[i]);
				strcpy(input[i], tmpInp);
			}
		}
	}

	printf(Rus("Отсортированые строки по наиболее длинному слову в порядке неубывания\n\n"));
	for (int i = 0; i < row; i++){
		printf("%s\n", input[i]);
	}
}

char bufRus[256];
char* Rus(const char* text){
	CharToOemA(text, bufRus);
	return bufRus;
}
что не так ссортировкой
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Вот в этом месте:

Код: Выделить всё

        char *tmpInp = input[i];
У тебя в переменную tmpInp присваивается не строка символов, а лишь её адрес. В результате, парами строк кода ниже, ты благополучно затираешь значение input без возможности его восстановления.

Для обмена значений двух буферов нужен вспомогательный буфер, а не переменная-указатель. Всё полностью аналогично обмену значений обычных переменных.

А вообще, обмен значений в input можно и не делать, если вместо массива с длинами строк отсортировать массив с индексами этих строк, а потом вывести input через значения этих индексов.

Код: Выделить всё


// int arrLen[maxString]; // убираем
int arrIdx[maxString]; // добавляем

... // читаем строки и записываем их в input

if (row > 1)
{
   for (int i = 0; i < row; ++i) arrIdx[i] = i;

   for (int i = 0; i < row - 1; ++i)
      for (int j = i + 1; j < row ; ++j)
         if (strlen(input[arrIdx[i]]) > strlen(input[arrIdx[j]])
         {
            int temp = arrIdx[i];
            arrIdx[i] = arrIdx[j];
            arrIdx[j] = temp;
         }  
}

printf(Rus("Отсортированые строки по наиболее длинному слову в порядке неубывания\n\n"));
for (int i = 0; i < row; ++i)
{
   printf("%s\n", input[arrIdx[i]]);
}
Надеюсь, нигде не ошибся, так как писал прямо на форуме и не проверял на работоспособность.

Кстати, если уж используешь пузырьковую сортировку, то почему не используешь её основное преимущество - большую скорость для частично сортированных массивов? Если во внутреннем цикле не было ни одного обмена, то крутить циклы дальше бесполезно, так как массив уже отсортирован.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Kazanove
Сообщения: 41
Зарегистрирован: 24 фев 2016, 14:55

Спасибо все работает ... насчет сортировки идея очень хорошая
Ответить