Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Kotelliada
1 / 1 / 0
Регистрация: 01.11.2015
Сообщений: 52
1

Ошибка в удалении повторяющихся данных в списках

30.03.2016, 19:06. Просмотров 189. Ответов 6
Метки нет (Все метки)

Добрый вечер. Не удаляются повторяющиеся данные в программе с использованием списков (функция Delete_double())
Спасибо за помощь.
List.cpp
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
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
#include "stdafx.h"
#include "List.h"
#include <string>
 
bool Object::Insert(void* data)           // Вставка в начало
{     bool rc = 0;
        if (Head == NULL)   
            {      
                Head = new Element(NULL,data,Head);    
                rc = true; 
            }
        else     
            {    
                Head = (Head->Prev = new Element(NULL, data,Head));
                rc = true;    
            } 
       return rc;
}   
 
Element* Object::Search (void* data)    // Найти заданный элемент
{    Element* rc  = Head;
       while((rc != NULL) && (rc->Data != data))    
                rc = rc->Next;    
       return rc;   
}
 
void Object::PrintList(void(*f)(void*))     // Вывод
{   
    Element* e = Head;
    while (e != NULL)
    {     
        f(e->Data);
        e = e->GetNext();
    };
}
 
bool  Object::Delete(Element* e)    // Удалить по ссылке
{     bool rc=0;
        if (rc = (e != NULL))
        {       if (e->Next != NULL)   e->Next->Prev = e->Prev; 
                 if (e->Prev != NULL)   e->Prev->Next = e->Next;
                 else   Head = e->Next; 
                 delete e;    
         }  
        return rc;
}
 
void Object::PrintList(void(*f)(void*), Element *e)
{   
       f(e->Data);  
} 
 
bool Object::Delete(void* data)      // Удалить первый 
{   
     return Delete(Search(data)); 
};
 
Element* Object::GetLast()
{  
      Element* e = Head, *rc = e;
      while (e != NULL)
        {      
            rc = e; 
            e = e->GetNext();    
        };
      return rc;
}
 
Element* Object::GetFirst()                         // получить первый элемент списка
{ 
         return Head; 
};
 
 Object Create()
{    
      return *(new Object());  
}
 
bool Object::DeleteList() //удалить список
{
    Element *temp = GetLast();
    if(temp)
    {
        if (temp ->Prev != NULL)
            temp ->Prev ->Next = temp ->Next;
        else Head = temp -> Next;
        delete temp;
        DeleteList();
    }
    return true;
}
 
int  Object::CountList()
{
    int cout = 0;
    Element *temp = GetFirst();
    for(int i = 0; temp != NULL; i++)
    {
        if(temp->Next != NULL)
        {
            temp = temp->Next;
            cout++;
        }
        else 
        {
            cout++; break;
        }
    }
    return cout;
}
 
void Object::Delete_double()
{
    Element *point = GetFirst();
    if (point == NULL)
    {
        return;
    }
    while (point->Next != NULL)
    {
        if (point->Next == point->Next->Next)
        {
            Element *Next_next = point->Next->Next;
            delete point->Next;
            point->Next = Next_next;
        }
        else
            point = point->Next;
    }
}
List.h
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
#pragma once 
 struct Element                                 // Элемент списка 
 {    
     Element* Prev;                             // указатель на предыдущий элемент 
     Element* Next;                             // указатель на следующий элемент 
     void*  Data;                                   //  данные  
     Element(Element* prev, void* data,  Element* next) // конструктор
        {    
            Prev = prev;
            Data = data;
            Next = next;
        }
      Element* GetNext()     // получить следующий
      {    
            return Next;  
      };          
        Element* GetPrev()     // получить предыдущий  
        {    
            return Prev;  
        };          
  }; 
 
  struct Object                       // Блок управления списком 
 {   Element* Head;              // указатель на начало списка
     Object()  
     {  
         Head = NULL;  
     };
     Element* GetFirst();// получить первый элемент списка;  
     Element* GetLast();                        // получить последний элемент списка
     Element* Search (void* data);       // найти  первый элемент по данным 
     bool Insert(void* data);                   // добавить элемент в начало
     bool InsertEnd(void* data);          // добавить в конец 
     bool Delete(Element* e);                  // удалить по адресу элемента 
     bool Delete(void* data);                   // удалить первый по данным
     bool DeleteList();            // очистить список 
     void Object::PrintList(void(*f)(void*));
     void Object::PrintList(void(*f)(void*), Element*);
     int  Object::CountList();
     void Object::Delete_double();
};
 Object Create();
ConsoleApplication3.cpp
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
75
76
77
78
79
80
81
82
83
84
85
#include "stdafx.h"
#include "List.h"
#include <iostream>
#include "Windows.h"
#include <string>
using namespace std;
 
struct men
{
char name[15];
char birthday[15];
char city[15];
char pol[3];
men *next;
};
 
void f (void* b)
{
    men *a = (men*) b;
    cout << a->name << " " << a->birthday << " " << a->city << " " << a->pol << endl;
    cout << endl;
}  
 
int _tmain(int argc, _TCHAR* argv[])
{
    int choice;
    setlocale(LC_ALL, "Russian");
    men a1 = {"Антон", "29.11.1997", "Минск", "М"};     
    men a2 = {"Роман", "10.07.1998", "Минск", "М"};
    men a3 = {"Дарья", "09.06.1998", "Мозырь", "Ж"};
    men a4 = {"Анастасия", "21.08.1994", "Барановичи", "Ж"};
    men a5 = {"Антон", "29.11.1997", "Минск", "М"};
    bool rc;
    Object L1 = Create(); // Head = NULL
    rc = L1.Insert(&a1); 
    rc = L1.Insert(&a2);
    rc = L1.Insert(&a3);
    rc = L1.Insert(&a4);
    rc = L1.Insert(&a5);
    do
    {
        cout << "1. Получить первый элемент списка" << endl;
        cout << "2. Получить последний элемент списка" << endl;
        cout << "3. Показать элемент " << endl;
        cout << "4. Вывод списка" << endl;
        cout << "5. Добавить элемент в начало списка" << endl;
        cout << "6. Удалить первый элемент " << endl;
        cout << "7. Очистить список " << endl;
        cout << "8. Посчитать число элементов списка " << endl;
        cout << "9. Удаление повторяющегося элемента списка " << endl;
        cout << "0. Выход " << endl;
        cout << "Номер операции: ";
        cin >> choice;
        system("cls");
        int n = 4;
        switch (choice)
        {
        case 1:  L1.PrintList(f, L1.GetFirst()); 
            system("Pause"); 
            break;
        case 2:  L1.PrintList(f, L1.GetLast()); 
            system("Pause"); 
            break;
        case 3:  L1.PrintList(f, L1.Search(&a3)); 
            system("pause"); 
            break;
        case 4:  L1.PrintList(f); 
            break;
        case 5:  L1.Insert(&a5); 
            break;
        case 6:  L1.Delete(&a5); 
            break;
        case 7:  L1.DeleteList(); 
            break;
        case 8:  cout << "Количество элементов: " << L1.CountList() << endl; 
            break;
        case 9:  L1.Delete_double();
            break;
        case 0: exit(0);
        default: cout << "Некорректный ввод! Повторите ещё раз. " << endl;
        }
    } while (choice != 0); 
    system("pause");
    return 0;
}
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.03.2016, 19:06
Ответы с готовыми решениями:

Ошибка при удалении в базе данных.
Здравствуйте. Есть код готовый, рабочий с баззой данных. Ошибка вылетает(через...

Ошибка в списках
В функции сравнения Compare не инициализируется переменная y. Зато такая же...

Ошибка в списках
#include &lt;iostream&gt; #include &lt;list&gt; using namespace std; void main() {...

В связанных списках ошибка - параметры конструктора не задекларированы
На 26 строке выдает ошибку -...

Ошибка при удалении класса
Доброго времени суток! Есть класс: class Sector { public: Sector();...

6
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
4837 / 2482 / 695
Регистрация: 18.10.2014
Сообщений: 4,290
30.03.2016, 19:14 2
Что такое "данные"? Какие "данные" считаются одинаковыми, а какие разными?

У вас похоже, что для хранения "данных" предназначено поле void *data. При этом у вас в функции Delete_double вообще нет ни одного обращения к полю data. Каким образом эта функция может "удалять повторяющиеся данные" если она вообще не обращает никакого внимания на данные?
0
Hikari
Хитрая блондиночка $)
1451 / 964 / 399
Регистрация: 21.12.2015
Сообщений: 3,785
30.03.2016, 19:28 3
Я бы так писала:
C++
1
2
3
4
5
6
7
8
9
10
11
12
void Object::Delete_double()
{
    Element *p2;
    for(Element *point = GetFirst();point && point->Next;)
     if(point->Data==point->Next->Data){
          p2=point->Next->Next;
          delete point->Next;
          point->Next=p2;
     }  else {
      point=point->Next;
     }
}
Там где == нужно подставить нужную методику сравнивания.
1
Kotelliada
1 / 1 / 0
Регистрация: 01.11.2015
Сообщений: 52
30.03.2016, 20:32  [ТС] 4
Hikari,
Что-то похожее как у вас написал.
В итоге ни моё, ни ваше не работает.

Добавлено через 36 минут
Hikari, удаляет все, кроме последнего.
0
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
4837 / 2482 / 695
Регистрация: 18.10.2014
Сообщений: 4,290
30.03.2016, 20:36 5
Цитата Сообщение от Kotelliada Посмотреть сообщение
В итоге ни моё, ни ваше не работает.
Вам же ясно сказали: "там где == нужно подставить нужную методику сравнивания" (!)

У Hikari все прекрасно работает. Только в качестве методики сравнения используется прямое сравнение указателей Data. Это не то, что вам нужно. А уж какая вам действительно нужна методика сравнения для данных, видимых через void * указатель - это уже у вас надо спрашивать. Мы тут не телепаты.

Скорее всего вам нужен callback как в функции PrintList.
1
Kotelliada
1 / 1 / 0
Регистрация: 01.11.2015
Сообщений: 52
30.03.2016, 21:07  [ТС] 6
TheCalligrapher, Hikari,
Сделал по-своему.
Код:
C++
1
2
3
4
5
6
7
Element *temp = GetLast();
    if (temp != 0)
    {
        if (temp->Prev != NULL)
            temp->Prev->Next = temp->Next;
        else Head = temp->Next;
        delete temp;
Спасибо вам за идеи.
0
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
4837 / 2482 / 695
Регистрация: 18.10.2014
Сообщений: 4,290
30.03.2016, 21:11 7
Цитата Сообщение от Kotelliada Посмотреть сообщение
Сделал по-своему
Что это и какое это отношение имеет к функции Delete_double???
0
30.03.2016, 21:11
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
30.03.2016, 21:11

Ошибка при удалении массива
Программа работает нормально, но в конце при удалении выдает ошибку &quot;Invalid...

Ошибка в удалении элемента в списке
Собственно не получается последняя функция &quot;delete_e&quot;, задача удалить в списке...

Ошибка при удалении массива
Проблема в том, что при попытке добавить строки удаления массивов программа...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru