Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 08.06.2017, 00:39   #1
ShINkoz
Новичок
Джуниор
 
Регистрация: 08.06.2017
Сообщений: 2
По умолчанию Сортировка по фамилиям (списки). С++

Здравствуйте. Не получается (даже скорее всего не понимаю) как отсортировать списки по фамилиям. То есть, суть задачи, необходимо создать список студентов, я сам ввожу: сколько человек необходимо добавить в список, все данные студента и тд. В конце появляется меню, в котором необходимо выбрать - вывести полный список добавленных студентов или только тех, у кого средний балл меньше 3.5 и при этом необходимо, чтобы студенты сортировались в алфавитном порядке по фамилии. У меня получилось сделать только критерий по баллам, а вот сортировка не получается, выдает бесконечный цикл.
Код:
#include "stdafx.h"
#include <iostream>
#include <string> 
#include <Windows.h>
#include <conio.h>
#include <cstring>
using namespace std;
/// структура
struct student
{
char imya[10]; 
char familiya[15]; 
int kurs; 
float ocenka; 
char pol[8];
student *Next;
}*l1,*l2,*q,*w,temp,temp2;

/// функция add - ввод полей через cin >> temp. 
void add()
{
cout << "Введите имя: "; 
cin >> temp.imya; 
cout << "Введите фамилию: "; 
cin >> temp.familiya; 
cout << "Введите пол: "; 
cin >> temp.pol; 
cout << "Введите курс: "; 
cin >> temp.kurs; 
cout << "Введите cреднюю оценку: "; 
cin >> temp.ocenka; 
}


/// функция addl1 - копирование полей и добавление их в список l1
void addl1()
{
student *l1 = new student; 
strcpy(l1->imya, temp.imya); 
strcpy(l1->familiya, temp.familiya); 
strcpy(l1->pol, temp.pol); 
l1->kurs = temp.kurs; 
l1->ocenka = temp.ocenka; 
l1->Next = q; 
q = l1; 
}
/// функция addl2 - копирование полей и добавление их в список l2
void addl2()
{
student *l2 = new student; 
strcpy(l2->imya, temp.imya); 
strcpy(l2->familiya, temp.familiya); 
strcpy(l2->pol, temp.pol); 
l2->kurs = temp.kurs; 
l2->ocenka = temp.ocenka; 
l2->Next = w;
w = l2;
}
///////////////////////////////////////////////////
/// функция showl1 - вывод всех полей списка l1 ///
///////////////////////////////////////////////////
void showl1()
{
student *l1 = q;
while (l1!=NULL)
{
cout << "Имя: "; 
cout << l1->imya << endl; 
cout << "Фамилия: "; 
cout << l1->familiya << endl; 
cout << "Пол: "; 
cout << l1->pol << endl; 
cout << "Курс: "; 
cout << l1->kurs << endl; 
cout << "Средняя оценка: "; 
cout << l1->ocenka << endl; 
l1 = l1->Next; 
cout << endl; 
}
}
/// функция showl2 - вывод всех полей списка l2
void showl2(int people)
{
student *l2 = w;
while (l2 != NULL)
{
cout << "Имя: "; 
cout << l2->imya << endl; 
cout << "Фамилия: "; 
cout << l2->familiya << endl; 
cout << "Пол: "; 
cout << l2->pol << endl; 
cout << "Курс: "; 
cout << l2->kurs << endl; 
cout << "Средняя оценка: "; 
cout << l2->ocenka << endl; 
l2 = l2->Next; 
cout << endl; 
}
}
//////////////////////////////////////////////////////
void show(struct student* pers)
{
	cout << pers->imya << " " << pers->familiya << " " << pers->kurs << " " << pers->ocenka << " " << pers->kurs << "\n";
}
void sort(struct student* pers1, struct student* pers2)
{
	struct student buf;
	int k = strcmp(pers1->familiya, pers2->familiya);
	if (k>0)
	{
		buf = *pers1;
		*pers1 = *pers2;
		*pers2 = buf;
	}
}
////////////////////////////////////////////////////
/// основа
int _tmain(int argc, _TCHAR* argv[])
{
	SetConsoleCP(1251);
	SetConsoleOutputCP(1251);
	setlocale(LC_ALL, "rus");
	int people, e = 0;
	cout << "Введите количество человек, которые будут добавленны в список: ";
	cin >> people;
	q = NULL;
	w = NULL;
	for (int i = 1; i <= people; i++)
	{
		add();
		addl1();
		if (temp.ocenka < 3.5){
			addl2();
		}
		system("cls");
	}
	while (true){
		cout << "1 - показать весь список" << endl;
		cout << "2 - показать отсортированный список" << endl;
		cout << "Выберете действие: ";
		int action;
		cin >> action;
		switch (action)
		{
		case 1:showl1();
			break;
		case 2:
	{
			  for (int j = 0; j<e; j++)
			  {
				  for (int t = j + 1; t<e; t++)
				  {
					  sort(&l2[j], &l2[t]);
				  }
			  }
			  for (int b = 0; b<e; b++)
			  {
				  show(&l2[b]);
			  }
			  break;
	}
		}
	}
	cout << endl;
	system("pause");
	return 0;
}
Получается проблема в case 2 и в void sort и я слабо понимаю, в чем проблема и как исправить. Заранее благодарен.
ShINkoz вне форума Ответить с цитированием
Старый 08.06.2017, 11:38   #2
eoln
Старожил
 
Аватар для eoln
 
Регистрация: 26.04.2008
Сообщений: 2,645
По умолчанию

Код:
	{
		buf = *pers1;
		*pers1 = *pers2;
		*pers2 = buf;
Здесь элементы списка целиком перемещаются в памяти, но их связи не изменяются. В итоге никакой сортировки вообще нет.
Выходов минимум два:
- либо менять только информационную часть (char imya[10]; char familiya[15]; int kurs; float ocenka; char pol[8] и не трогать student *Next;
- либо менять только указательную часть (student *Next плюс корректировать связи соседей.

Код целиком не смотрел
eoln вне форума Ответить с цитированием
Старый 08.06.2017, 18:35   #3
ura_111
Участник клуба
 
Регистрация: 14.05.2016
Сообщений: 1,793
По умолчанию

Лучше данными обменяться (через промежуточный узел), а связи не трогать...
Вот набросал:

Код:
#include "stdafx.h"
#include <Windows.h>
#include <iomanip>
#include <iostream>
using namespace std;

struct student
{
	char imya[10];
	char familiya[15];
	int kurs;
	float ocenka;
	char pol[8];
	student *next;
}*head;

int _tmain(int argc, _TCHAR* argv[])
{
	head = NULL;
	setlocale(LC_ALL, "rus");	
	SetConsoleCP(1251);
	SetConsoleOutputCP(1251);

	head = new student;  strcpy_s(head->imya, "Станислав"); strcpy_s(head->familiya, "Суслова"); strcpy_s(head->pol, "муж"); head->ocenka = 2.4; head->kurs = 1; 
	student *l1 = new student;  strcpy_s(l1->imya, "Евгений"); strcpy_s(l1->familiya, "Аванов"); strcpy_s(l1->pol, "муж"); l1->ocenka = 2.4; l1->kurs = 2;
	student *l2 = new student;  strcpy_s(l2->imya, "Лера"); strcpy_s(l2->familiya, "Иванова"); strcpy_s(l2->pol, "жен"); l2->ocenka = 3.0; l2->kurs = 3;
	student *l3 = new student;  strcpy_s(l3->imya, "Екатерина"); strcpy_s(l3->familiya, "Бобов"); strcpy_s(l3->pol, "жен"); l3->ocenka = 1.5; l3->kurs = 4;
	student *l4 = new student;  strcpy_s(l4->imya, "Владимир"); strcpy_s(l4->familiya, "Кукушкин"); strcpy_s(l4->pol, "муж"); l4->ocenka = 1.8; l4->kurs = 5;
	
	head->next = l1;
	l1->next = l2;
	l2->next = l3;
	l3->next = l4;
	l4->next = NULL;
	
	////////// ПЕРВОНАЧАЛЬНО //////////

	student *q1 = head;
	cout << "    Имя      Фамилия  Пол   Курс  Ср.оценка" << endl;
	while (q1 != NULL)
	{
		cout << setw(10);
		cout << q1->imya << setw(10);
		cout << q1->familiya;
		cout << "   " << q1->pol;
		cout << "   " << q1->kurs << "       " << q1->ocenka << endl;
		q1 = q1->next;
	}

	cout << endl << endl << endl;
	

	////////// Сортировка 1.отсортируем сначало по 0-му элементу //////////

	q1 = head;
	while (q1 != NULL)
	{
		student *q2 = q1->next;
		while (q2 != NULL)
		{
			if (q2->familiya[0] < q1->familiya[0])
			{
				student *q3 = new student;

				strcpy_s(q3->imya, q1->imya);     
				strcpy_s(q3->familiya, q1->familiya);
				strcpy_s(q3->pol, q1->pol);
				q3->kurs = q1->kurs;
				q3->ocenka = q1->ocenka;

				strcpy_s(q1->imya, q2->imya);
				strcpy_s(q1->familiya, q2->familiya);
				strcpy_s(q1->pol, q2->pol);
				q1->kurs = q2->kurs;
				q1->ocenka = q2->ocenka;

				strcpy_s(q2->imya, q3->imya);
				strcpy_s(q2->familiya, q3->familiya);
				strcpy_s(q2->pol, q3->pol);
				q2->kurs = q3->kurs;
				q2->ocenka = q3->ocenka;
			}
			q2 = q2->next;
		}
		q1 = q1->next;		
	}
	

	////////// ПОСЛЕ СОРТИРОВКИ //////////
	
	q1 = head;
	cout << "    Имя      Фамилия  Пол   Курс  Ср.оценка" << endl;
	while (q1 != NULL)
	{
		cout << setw(10);
		cout << q1->imya << setw(10);
		cout << q1->familiya;
		cout << "   " << q1->pol;
		cout << "   " << q1->kurs << "       " << q1->ocenka << endl;
		q1 = q1->next;
	}

	/////////////////////////////////////////////

system("pause");
	return 0;
}

Только сортировка у меня идёт по первой букве фамилии (а если будет две фамилии начинающие с одинаковой буквы? - то программа не отсортирует их)...
Возьми поэкспериментируй с кодом: добавляй новые записи, с разными фамилиями, чтобы посмотреть как программа ни них реагирует.
Сначала выводиться первоначальный список, а потом отсортированный:

1.png

p.s.: кстате ShINkoz, удобней отлаживать куски кода где-то в сторонке, а потом в чистую программу интегрировать (бери на заметку).

Последний раз редактировалось ura_111; 08.06.2017 в 18:42.
ura_111 вне форума Ответить с цитированием
Старый 08.06.2017, 18:35   #4
ura_111
Участник клуба
 
Регистрация: 14.05.2016
Сообщений: 1,793
По умолчанию

А вообще у тебя в задании написано, чтобы был только один список, а не два. А в сортировке - просто создаёшь новый список, в который заносишь все <3.5... После вывода надо не забыть удалить список с головой "head_35;"
Вот приближено набрасал (без сортировки):

Код:
#include "stdafx.h"
#include <Windows.h>
#include <iomanip>
#include <iostream>
using namespace std;

struct student
{
	char imya[10];
	char familiya[15];
	int kurs;
	float ocenka;
	char pol[8];
	student *next;
}*head;

void add()
{
	student *temp = new student;
	cout << "Введите имя: ";
	cin >> temp->imya;
	cout << "Введите фамилию: ";
	cin >> temp->familiya;
	cout << "Введите пол: ";
	cin >> temp->pol;
	cout << "Введите курс: ";
	cin >> temp->kurs;
	cout << "Введите cреднюю оценку: ";
	cin >> temp->ocenka;
	temp->next = NULL;
	if (head == NULL)
	{
		head = temp;
	}
	else
	{
		student *q = head;
		while (q->next != NULL)
		{
			q = q->next;
		}
		q->next = temp;
	}
}
void show()
{	
	student *q = head;
	cout << "    Имя      Фамилия  Пол   Курс  Ср.оценка" << endl;
	while (q!= NULL)
	{
		cout << setw(10);
		cout << q->imya << setw(10);
		cout << q->familiya;
		cout << "   " << q->pol;
		cout << "   " << q->kurs << "       " << q->ocenka << endl;
		q = q->next;
	}
}
void show_35()
{
	student *q = head;
	student *head_35 = NULL;
	student *l1, *l2;

	// выделение узлов < 3.5
	while (q != NULL)
	{
		if (q->ocenka < 3.5)
		{
			if (head_35 == NULL)
			{
				head_35 = new student;
				strcpy_s(head_35->imya, q->imya);
				strcpy_s(head_35->familiya, q->familiya);
				strcpy_s(head_35->pol, q->pol);
				head_35->kurs = q->kurs;
				head_35->ocenka = q->ocenka;
				head_35->next = NULL;
			}
			else
			{					
				l1 = head_35;
				while (l1->next != NULL)
				{
					l1 = l1->next;
				}
				l2 = new student;
				strcpy_s(l2->imya, q->imya);
				strcpy_s(l2->familiya, q->familiya);
				strcpy_s(l2->pol, q->pol);
				l2->kurs = q->kurs;
				l2->ocenka = q->ocenka;
				l2->next = NULL;
				l1->next = l2;
			}
		}
		q = q->next;
	}

	// сортировка узлов < 3.5
	
	q = head_35;
	cout << "    Имя      Фамилия  Пол   Курс  Ср.оценка" << endl;
	while (q != NULL)
	{
		cout << setw(10);
		cout << q->imya << setw(10);
		cout << q->familiya;
		cout << "   " << q->pol;
		cout << "   " << q->kurs << "       " << q->ocenka << endl;
		q = q->next;
	}
	q = head_35;
	while (q != NULL)
	{
		q = q->next;
		delete head_35;
		head_35 = q;		
	}	
}

int _tmain(int argc, _TCHAR* argv[])
{
	head = NULL;
	setlocale(LC_ALL, "rus");	
	SetConsoleCP(1251);
	SetConsoleOutputCP(1251);
	
	//int people = 0;
	//cout << "  Введите количество человек: ";
	//cin >> people;
	//for (int i = 0; i < people; i++)
	//{
	//	cout << "\n";
	//	add();
	//}	

	head = new student;  strcpy_s(head->imya, "Станислав"); strcpy_s(head->familiya, "Бобов"); strcpy_s(head->pol, "муж"); head->ocenka = 2.4; head->kurs = 3; 
	student *l1 = new student;  strcpy_s(l1->imya, "Евгений"); strcpy_s(l1->familiya, "Иванов"); strcpy_s(l1->pol, "муж"); l1->ocenka = 2.4; l1->kurs = 6;
	student *l2 = new student;  strcpy_s(l2->imya, "Лера"); strcpy_s(l2->familiya, "Иванова"); strcpy_s(l2->pol, "жен"); l2->ocenka = 3.0; l2->kurs = 2;
	student *l3 = new student;  strcpy_s(l3->imya, "Екатерина"); strcpy_s(l3->familiya, "Суслова"); strcpy_s(l3->pol, "жен"); l3->ocenka = 1.5; l3->kurs = 5;
	student *l4 = new student;  strcpy_s(l4->imya, "Владимир"); strcpy_s(l4->familiya, "Кукушкин"); strcpy_s(l4->pol, "муж"); l4->ocenka = 1.8; l4->kurs = 1;
	
	head->next = l1;
	l1->next = l2;
	l2->next = l3;
	l3->next = l4;
	l4->next = NULL;
	
	int meniu = 5;
	while (true)
	{
		if ((1 <= meniu && meniu <= 6))
		{
			if (meniu == 1)
			{
				cout << "______________________________________________\n";
				show();
				cout << "______________________________________________\n";
			}
			if (meniu == 2)
			{
				cout << "______________________________________________\n";
				show_35();
				cout << "______________________________________________\n";
			}
			if (meniu == 3)
			{
				;
			}
			if (meniu == 4)
			{
				;
			}
			if (meniu == 5)
			{
				system("cls");
				cout << " МЕНЮ:\n";
				cout << "  1.Просмотр всего списка\n";
				cout << "  2.Просмотр ущащихся < 3.5\n";
				cout << "  3.Добавить человека\n";
				cout << "  4.Удалить человека\n";
				cout << "  5.Очистить консоль\n";
				cout << "  6.ВЫХОД\n\n";
			}
			if (meniu == 6)
			{
				break;
			}
		}
		else
		{
			cout << "  ERROR! \n\n";
		}
		cout << "меню ";
		cin >> meniu;
	}
	system("pause");
	return 0;
}
Если ты хочешь через консоль вводить данные, тогда разкоментируй
Код:
	//int people = 0;
	//cout << "  Введите количество человек: ";
	//cin >> people;
	//for (int i = 0; i < people; i++)
	//{
	//	cout << "\n";
	//	add();
	//}
и удали:

Код:
	head = new student;  strcpy_s(head->imya, "Станислав"); strcpy_s(head->familiya, "Бобов"); strcpy_s(head->pol, "муж"); head->ocenka = 2.4; head->kurs = 3; 
	student *l1 = new student;  strcpy_s(l1->imya, "Евгений"); strcpy_s(l1->familiya, "Иванов"); strcpy_s(l1->pol, "муж"); l1->ocenka = 2.4; l1->kurs = 6;
	student *l2 = new student;  strcpy_s(l2->imya, "Лера"); strcpy_s(l2->familiya, "Иванова"); strcpy_s(l2->pol, "жен"); l2->ocenka = 3.0; l2->kurs = 2;
	student *l3 = new student;  strcpy_s(l3->imya, "Екатерина"); strcpy_s(l3->familiya, "Суслова"); strcpy_s(l3->pol, "жен"); l3->ocenka = 1.5; l3->kurs = 5;
	student *l4 = new student;  strcpy_s(l4->imya, "Владимир"); strcpy_s(l4->familiya, "Кукушкин"); strcpy_s(l4->pol, "муж"); l4->ocenka = 1.8; l4->kurs = 1;
	
	head->next = l1;
	l1->next = l2;
	l2->next = l3;
	l3->next = l4;
	l4->next = NULL;

Последний раз редактировалось ura_111; 08.06.2017 в 18:44.
ura_111 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Сортировка по фамилиям (Pascal) alex_warrior Помощь студентам 3 06.02.2012 21:09
Списки,сортировка. Muro Общие вопросы C/C++ 0 04.06.2010 04:27
Сортировка по имени (списки) sunman Паскаль, Turbo Pascal, PascalABC.NET 1 30.05.2010 22:38
поиск по фамилиям и вывод результатов в DBGrid Explosion БД в Delphi 14 23.04.2010 20:47
Задача: списки/сортировка uranus Паскаль, Turbo Pascal, PascalABC.NET 4 22.05.2007 14:34