|
Где ошибка в данном коде? | ☑ | ||
---|---|---|---|---|
0
Mits
29.01.12
✎
10:56
|
Функция добавления нового элемента в конец списка, а не в его начало. Почему-то добавляются только первый и последний элемент.
void List::AddLast(char data) { Element* temp= new Element; temp->data = data; temp->Next = NULL; if(Head==NULL) Head=temp; else { Element* current; for(current=Head;current->Next=0;current=current->Next); current->Next=temp; } Curr=temp; Count++; } |
|||
1
Mits
29.01.12
✎
10:57
|
Получается, что каждый последующий элемент затирает предыдущий и в целом список хранит первый и следующий элемент. Не могу понять, как записать код, чтобы хранились все элементы.
|
|||
2
Fragster
гуру
29.01.12
✎
10:58
|
а шо такое HEAD?
|
|||
3
Fragster
гуру
29.01.12
✎
10:58
|
for(current=Head;current->Next=NULL;current=current->Next);
|
|||
4
andrewks
29.01.12
✎
10:59
|
"Почему-то добавляются только первый и последний элемент" это как?
|
|||
5
Fragster
гуру
29.01.12
✎
11:00
|
current->Next==NULL !!!!
|
|||
6
Fragster
гуру
29.01.12
✎
11:01
|
кстати, нормальная IDE/компилятро там бы варнинг фиганул
|
|||
7
Mits
29.01.12
✎
11:07
|
Заработало, спасибо.
|
|||
8
Mits
29.01.12
✎
11:08
|
(6)Microsoft Visual Studio по партизански молчал.
|
|||
9
Mits
29.01.12
✎
11:31
|
Теперь вот тут ошибка - компилятор говорит, что lst1[j].AddLast(str[i]) должно быть типа класс, хотя это и есть ссылка на класс.
void input(List* lst1[maxsize]) { char str[maxsize]; int i,j,sj; i=j=sj=0; while (cin.getline(str,maxsize,'\n')!='\0') { int len = strlen(str); for(i = 0; i < len; i++)lst1[j].AddLast(str[i]); j++;sj++; } } |
|||
10
Ненавижу 1С
гуру
29.01.12
✎
11:40
|
lst1[j]->AddLast(str[i]);
|
|||
11
Fragster
гуру
29.01.12
✎
11:40
|
добавь звездочку, или что там в сях надо, чтобы он из ссылки значение получил
|
|||
12
Fragster
гуру
29.01.12
✎
11:40
|
а, вот
|
|||
13
Fragster
гуру
29.01.12
✎
11:41
|
вообще циклы без {} взрывают мозг
|
|||
14
Mits
29.01.12
✎
11:45
|
(13)если один оператор, то обязательно разве писать операторные скобки?
|
|||
15
Fragster
гуру
29.01.12
✎
11:46
|
(14) не обязательно. но читать проще с ними
|
|||
16
ДенисЧ
29.01.12
✎
11:48
|
(9) ёмать.. код в (9) нечитабелен... Прибил бы за такое...
|
|||
17
Mits
29.01.12
✎
11:53
|
(16)что именно там не читается?
|
|||
18
Mits
29.01.12
✎
11:55
|
Вот окончательный вариант, но при попытке обратиться из основной программы выходит ошибка, что должен быть тип не * (указатель), а **(указатель на указатель - двойной указатель)
void input(List* lst1[maxsize]) { List lst1[maxsize]; char str[maxsize]; int i,j,sj; i=j=sj=0; while (cin.getline(str,maxsize,'\n')!='\0') { int len = strlen(str); for(i = 0; i < len; i++)lst1[j]->AddLast(str[i]); j++;sj++; } } List* lst1[maxsize], lst2[maxsize]; input(lst1[maxsize]); output(lst1[maxsize]); |
|||
19
Mits
29.01.12
✎
11:55
|
Вроде бы все логично и правильн, но не работает.
|
|||
20
Mits
29.01.12
✎
11:56
|
void main()
{ List* lst1[maxsize], lst2[maxsize]; input(lst1[maxsize]); output(lst1[maxsize]); system("pause"); } |
|||
22
Mits
29.01.12
✎
12:08
|
если добавить & - разименование указателя, то есть вместо указателя берется непосредственное значение, то программа запускается, но при попытке обратиться к классу вылетает в exception.
void main() { List* lst1[maxsize], lst2[maxsize]; input(lst1[maxsize]); output(lst1[maxsize]); system("pause"); } |
|||
23
Mits
29.01.12
✎
12:09
|
void main()
{ List* lst1[maxsize], lst2[maxsize]; input(&lst1[maxsize]); output(&lst1[maxsize]); system("pause"); } |
|||
24
Mits
29.01.12
✎
12:58
|
up
|
|||
25
IamAlexy
29.01.12
✎
12:58
|
с точки зрения 1С у вас почти в каждой строке ошибка.
исправьте. |
|||
26
Mits
29.01.12
✎
13:09
|
с точки зрения 1с это китайский язык.
|
|||
27
Mits
30.01.12
✎
02:31
|
как я понимаю надо перегрузить оператор []
|
|||
28
Steel_Wheel
30.01.12
✎
02:56
|
(14) в целом, из-за этого ты топик и создал
|
|||
29
Дядя Васька
30.01.12
✎
03:05
|
Имхо List lst1[maxsize]; в Input неверно. У нее время жизни в пределах функции. Нужно создать нормальный список, а не указатель в main(), передать на него ссылку и в самой проце уже ничего не создавать.
|
|||
30
Mits
30.01.12
✎
03:46
|
(29)можно и так, но передача по указателю считается лучше, так как вместо всей структуры данных передается только ее адрес в памяти, что намного быстрее и требует меньше памяти.
|
|||
31
Rie
30.01.12
✎
04:57
|
(27) Зачем?
|
|||
32
Rie
30.01.12
✎
05:05
|
(30) Тебе же сказали - передать _ссылку_.
|
|||
33
Mits
30.01.12
✎
05:10
|
То есть так?
input(&lst1[maxsize]); output(&lst1[maxsize]); |
|||
34
Mits
30.01.12
✎
05:12
|
Сейчас вот такой код
#include <stdio.h> #include <iostream> #include <string.h> using namespace std; const int maxsize=80; struct Element { char data; Element * Next; }; class List { private: Element * Head; Element * Curr; Element * Tail; int Count; public: List(); ~List(); void AddFirst(char data); void AddLast(char data); void Del(); void DelAll(); void PrintAll(); int GetCount(); void FirstRec(); void NextRec(); char GetChar(); /* void FindSampleWord(List* lst1[20]);*/ }; List::List() { Head = NULL; Curr = NULL; Tail = NULL; Count = 0; } List::~List() { DelAll(); } int List::GetCount() { return Count; } void List::AddFirst(char data) { Element * temp = new Element; temp->data = data; temp->Next = Head; Head=temp; Curr=temp; Count++; } void List::AddLast(char data) { Element* temp= new Element; temp->data = data; temp->Next = NULL; if(Head==NULL) Head=temp; else { Element* current; for(current=Head;current->Next!=0;current=current->Next); current->Next=temp; } Curr=temp; Count++; } void List::Del() { Element * temp = Head; Head = Head->Next; delete temp; } void List::DelAll() { while(Head != 0) Del(); } void List::PrintAll() { Element * temp = Head; while(temp != 0) { cout << temp->data; temp = temp->Next; } cout<<endl; } void List::NextRec() { if (Curr != NULL) Curr = Curr->Next; } char List::GetChar() { Element * temp = Curr; return temp->data; } /*void List::FindSampleWord(List* lst1[20]) { int i,j; List lst2[100]; for(j=0;j<20;j++) for(i=0;i<lst1[j].GetCount();i++) { if(lst1[j].GetChar()=' ')||(lst1[j].GetChar()='\t')||(lst1[j].GetChar()='\n') } }*/ void input(List lst1) { char str[maxsize]; int i,j,sj; i=j=sj=0; while (cin.getline(str,maxsize,'\n')!='\0') { int len = strlen(str); for(i = 0; i < len; i++)lst1[j]->AddLast(str[i]); j++;sj++; } } void output(List lst1) { int i,j,sj; i=j=sj=0; /*for (j=0;j<sj;j++)lst1[j]->PrintAll();*/ } void main() { List lst1[maxsize], lst2[maxsize]; input(lst1[maxsize]); output(lst1[maxsize]); system("pause"); } |
|||
35
Rie
30.01.12
✎
05:15
|
(34) AddLast выглядит загадочно - зачем тебе искать хвост циклом, если у тебя есть указатель на него? (То, что при самом первом добавлении ты забыл этот указатель установить - это другой вопрос).
|
|||
36
Rie
30.01.12
✎
05:17
|
+(35) в main - передавай _ссылки_. А ещё лучше - в описаниях input и output укажи, что параметр передаётся по ссылке (имеет тип ссылки).
|
|||
37
Mits
30.01.12
✎
05:18
|
(35)так правильно?
void List::AddLast(char data) { Element* temp= new Element; temp->data = data; temp->Next = NULL; if(Head==NULL) Head=temp; Tail=temp; else { /*Element* current; for(current=Head;current->Next!=0;current=current->Next);*/ Tail->Next=temp; } Curr=temp; Count++; } |
|||
38
Rie
30.01.12
✎
05:18
|
И к слову о (30): хранить строку связанным списком - это жестоко. А беспокоиться при этом о времени/памяти на передачу параметров - несколько ханжески.
|
|||
39
Rie
30.01.12
✎
05:19
|
(37) Уже лучше.
|
|||
40
Mits
30.01.12
✎
05:19
|
А какая разница между указателем и ссылкой на уровне компилятора?
|
|||
41
Rie
30.01.12
✎
05:20
|
+(39) Ну а теперь поправь AddFirst - и приблизишься к счастью.
|
|||
42
Rie
30.01.12
✎
05:21
|
(40) На уровне компилятора - огромная. На уровне порождаемого им кода - никакой. А вот между передачей ссылки и передачей значения (как у тебя сейчас) - колоссальная.
|
|||
43
Mits
30.01.12
✎
05:22
|
void List::AddFirst(char data)
{ Element * temp = new Element; temp->data = data; temp->Next = Head; Head=temp; Curr=temp; if(Head=NULL)Tail=temp; Count++; } |
|||
44
Rie
30.01.12
✎
05:22
|
+(42) Вообще забудь об "уровне компилятора". Современные компиляторы C++ генерируют весьма эффективный код - при _правильном_ использовании _языка_ программистом.
|
|||
45
Rie
30.01.12
✎
05:28
|
(43) Ну а теперь - поправь input, output и main.
|
|||
46
Mits
30.01.12
✎
05:29
|
(38)Условие задачи такое, что вводится многострочный текст и нужно его строки хранить в списке. А как хранить множество списков: в массиве. Ну или в других списках, что сложнее и не требуется по условию задачи.
|
|||
47
Rie
30.01.12
✎
05:30
|
(46) Так и храни _строки_ в _списке_ (а не _списки_ в _массиве_, как ты сейчас делаешь).
|
|||
48
Mits
30.01.12
✎
05:35
|
(47)можно весь текст хранить в одном списке, а строки разделять по символу перевода строки
|
|||
49
Rie
30.01.12
✎
05:39
|
(48) Строка - в простейшем виде - это char* (и завершается она не "переводом строки", а нулём - просто 0).
Если в input ты её прочитал - в этот самый char* - то зачем огород городить и превращать её в список char? (Поправь всё же input, output и main). |
|||
50
Mits
30.01.12
✎
05:42
|
void input(List &lst1)
{ char str[maxsize]; int i,j,sj; i=j=sj=0; while (cin.getline(str,maxsize,'\n')!='\0') { int len = strlen(str); for(i = 0; i < len; i++)lst1[j]->AddLast(str[i]);//error C2676: бинарный "[": "List" не определяет этот оператор или преобразование к типу приемлемо к встроенному оператору j++;sj++; } } |
|||
51
Mits
30.01.12
✎
05:43
|
не знаю как правильно передать по ссылке
|
|||
52
Mits
30.01.12
✎
05:44
|
void input(List &lst1)
{ char str[maxsize]; int i,j,sj; i=j=sj=0; while (cin.getline(str,maxsize,'\n')!='\0') { int len = strlen(str); for(i = 0; i < len; i++)lst1[j]->AddLast(str[i]); j++;sj++; } } void output(List &lst1) { int i,j,sj; i=j=sj=0; for (j=0;j<sj;j++)lst1[j]->PrintAll(); } void main() { List lst1[maxsize], lst2[maxsize]; input(lst1[maxsize]); output(lst1[maxsize]); system("pause"); } |
|||
53
Rie
30.01.12
✎
05:47
|
(52) Не торопись править. Сначала определись - что делают твои input и output. Сейчас ты вызываешь их для _одного_ элемента массива (причём за пределами границ - вспомни, что массивы в C++ нумеруются, начиная с 0).
|
|||
54
Rie
30.01.12
✎
05:48
|
+(53) Судя по тексту input, тебе хочется заполнить _массив_ - _списками_. Именно так тебе поставлена задача? Если нет - то как именно? Если так - то и передавай в input _массив_ (и укажи это в описании формальных параметров). Хотя передавать именно массив в твоём случае я бы не стал.
|
|||
55
Mits
30.01.12
✎
05:53
|
Из входного потока вводится произвольное число строк. Каждая строка представляет собой последовательность слов, разделенных одним или несколькими пробелами и/или знаками табуляции. Длина каждой строки не превышает 80 символов. Конец ввода определяется концом файла.
Каждая строка представлена списком; первое поле элемента списка - символ строки; второе - указатель на следующий элемент списка или NULL в конце списка; |
|||
56
Rie
30.01.12
✎
05:57
|
(55) Остаётся неясным - что является элементом "строки" (в кавычках - чтобы не путать твои строки с string или char*)? Отдельный символ? Или же "строка" - последовательность _слов_ (то есть, всё тех же string или char*)?
|
|||
57
Mits
30.01.12
✎
05:58
|
(56)последовательность слов
|
|||
58
Mits
30.01.12
✎
05:58
|
Для каждой строки сформировать новую, поместив в нее все слова исходной строки, начинающиеся и заканчивающиеся на одну и ту же букву. В полученной строке слова разделять только одним пробелом. Полученную строку вывести на экран.
|
|||
59
Rie
30.01.12
✎
05:59
|
(57) Как представлено _слово_ в программе?
|
|||
60
Mits
30.01.12
✎
06:01
|
(59)слова в одной строке, хранимой в списке
|
|||
61
Rie
30.01.12
✎
06:04
|
(60) Спрошу иначе. Допустим, имеется описание
word w; Что такое тип word? Опиши его (через class или typedef). |
|||
62
Mits
30.01.12
✎
06:05
|
(61)такого типа нет, слова сразу обрабатываются в списке
|
|||
63
Rie
30.01.12
✎
06:06
|
(62) Ну так опиши его! Ведь (если я правильно понимаю твою задачу) именно этот тип должен стоять в описании
class List { word data; //... чтобы строка была списком _слов_, а не хрен знает чего. |
|||
64
Mits
30.01.12
✎
06:10
|
Полное задание:
Из входного потока вводится произвольное число строк. Каждая строка представляет собой последовательность слов, разделенных одним или несколькими пробелами и/или знаками табуляции. Длина каждой строки не превышает 80 символов. Конец ввода определяется концом файла. Для каждой строки сформировать новую, поместив в нее все слова исходной строки, начинающиеся и заканчивающиеся на одну и ту же букву. В полученной строке слова разделять только одним пробелом. Полученную строку вывести на экран. Разработать следующие варианты программы: 1. каждая строка представлена массивом символов, доступ к элементам массива осуществляется с помощью указателей; 1.1. при обработке строки (строк) использовать библиотечные функции (<string.h>); 1.2. библиотечные функции обработки строки не использовать. 2. каждая строка представлена списком; первое поле элемента списка - символ строки; второе - указатель на следующий элемент списка или NULL в конце списка; 2.1. при обработке исходного списка (исходных списков) формировать новый список (списки); 2.2. список результата формировать, модифицируя исходный список. Примечания: 1. Ввод строк должен быть организован с помощью метода cin.getline(куда, максимум_сколько). Метод cin >> куда не использовать! 2. Логически-законченные части алгоритма программы оформлять функциями с параметрами (например, пропуск разделителей, построении списка, вывод списка, удаление списки и др.). |
|||
65
Mits
30.01.12
✎
06:14
|
то есть список хранит целую строку, а не отдельные слова
|
|||
66
Mits
30.01.12
✎
06:14
|
2. каждая строка представлена списком; первое поле элемента списка - символ строки; второе - указатель на следующий элемент списка или NULL в конце списка;
|
|||
67
Mits
30.01.12
✎
06:15
|
Но это не суть важно в данном случае. Мне уже пофиг как хранить. Мне важно в первую очередь, чтобы программа работала. И пофигу как передавать. Главное передать и вернуть.
|
|||
68
Mits
30.01.12
✎
06:16
|
Но у меня не получается и даже не вижу возможного решения. Я вижу "поле", где может быть решение.
|
|||
69
Rie
30.01.12
✎
06:16
|
(65) Да на здоровье (правда, как в таком представлении ты намереваешься искать слова на одну и ту же букву - это уже другой вопрос).
|
|||
70
Rie
30.01.12
✎
06:17
|
(68) Решение простое:
int main() { List line; while(input(line)) output(line); } Ну и переписать input и output соответствующим образом. |
|||
71
Rie
30.01.12
✎
06:18
|
+(70)
Вершее, int main() { List line = new List(); while(input(line)) output(line); } |
|||
72
Rie
30.01.12
✎
06:19
|
+(71) Не читай! Это я бред написал :-)
|
|||
73
Mits
30.01.12
✎
06:20
|
(69)Цикл перебирает символы строки, находит разделитель слов, значит все что было до него - слово, ищет следующее слово, если первый и последний символы совпали, то добавляет слово в новый список, и так далее. Если было совпадение, то сравниваемое слово тоже добавляется. И так далее перебором сравниваются все возможные комбинации слов. После новый список выводится на экран.
|
|||
74
Mits
30.01.12
✎
06:22
|
(70)это один элемент, а если массив элементов?
|
|||
75
Rie
30.01.12
✎
06:23
|
(74) Какой ещё массив? Зачем он тебе нужен? В качестве охотничьего трофея?
|
|||
76
Mits
30.01.12
✎
06:27
|
(75)так строк же много, каждая строка свой список
|
|||
77
Rie
30.01.12
✎
06:29
|
+(75) Если более подробно, то
/* читает строку из входного потока в список str; возвращает true, если строку считать удалось, false - в противном случае (конец потока и т.д.) */ bool input(List str); /* преобразует строку dest в строку src, как там сказано в задаче насчёт слов с одинаковыми буквами */void process(List dest, List src); /* выводит строку-результат */ void output(List str); и затем int main() { List line; List result; while (input(line) { process(line,result); output(result); } } |
|||
78
Rie
30.01.12
✎
06:30
|
(76) После того, как строка обработана - она тебе уже не нужна.
Очищай - и используй повторно. |
|||
79
Rie
30.01.12
✎
06:31
|
+(77) Трах-тибидох! Вредно писать одновременно на двух языках сразу! :)
Конецно же, /* читает строку из входного потока в список str; возвращает true, если строку считать удалось, false - в противном случае (конец потока и т.д.) */ bool input(List& str); /* преобразует строку dest в строку src, как там сказано в задаче насчёт слов с одинаковыми буквами */void process(const List& dest, List& src); /* выводит строку-результат */ void output(const List& str); |
|||
80
Mits
30.01.12
✎
06:37
|
то есть массив не нужен, сразу обрабатывается построчно
|
|||
81
Mits
30.01.12
✎
06:39
|
В принципе можно и так, но мне привычнее, что ввод идет сначала полностью, а потом вывод. А тут получается ввод/вывод и т. д.
|
|||
82
Rie
30.01.12
✎
06:39
|
(80) Конечно (если нет задачи копить строки для чего-то ещё).
|
|||
83
Rie
30.01.12
✎
06:41
|
(81) Отвыкай от нехороших привычек :-)
(Тем более что в твоей задаче нет ограничения на длину входного файла - а значит, объём данных может превышать объём оперативной памяти, и даже объём дисков (и даже объём _всех_ дисков на планете)). |
|||
84
Mits
30.01.12
✎
06:46
|
Тогда и не нужны массивы, задача упрощается.
|
|||
85
Mits
30.01.12
✎
06:49
|
Ладно, это позже. Сейчас надо срочно другое дело сделать.
|
|||
86
Mits
30.01.12
✎
06:50
|
может быть мне к вам в аську постучаться, чтобы позже можно было вопросы задать?
|
|||
87
Rie
30.01.12
✎
06:51
|
(84) С массивами - всё было бы аналогично:
int main() { List line[SORCE_SIZE]; List result[SORCE_SIZE]; int i = 0; while (input(line[i++]) { process(line[i],result[i]); output(result[i]); } } Но условия задачи говорят - размер определяется концом файла. Стало быть, так (через массивы) - нельзя. |
|||
88
Rie
30.01.12
✎
06:53
|
(86) Постучаться можно. Но я не отвечу - поскольку ICQ у меня по умолчанию выключено и включаю я его примерно раз в неделю, если не реже.
Но вопросы можно задавать на форуме (например, на этом). |
|||
89
Ковычки
30.01.12
✎
07:01
|
пример классический
|
|||
90
Ковычки
30.01.12
✎
07:03
|
for(current=Head;current->Next!=NULL;current=current->Next)
Tail->Next=temp; |
|||
91
Ковычки
30.01.12
✎
07:04
|
с точкозапятой конечно, как и было
|
|||
92
Rie
30.01.12
✎
07:05
|
(90) Зачем искать конец списка - если у него он уже имеется?
|
|||
93
Ковычки
30.01.12
✎
07:05
|
скорее наверное так
for(current=Head;current!=NULL;current=current->Next); |
|||
94
Ковычки
30.01.12
✎
07:06
|
(92) нужно перейти за конец списка
|
|||
95
Rie
30.01.12
✎
07:09
|
(94) У него есть Tail. В (90) - current ведь всё равно не используется.
|
|||
96
Ковычки
30.01.12
✎
07:20
|
Задание по СПО ? (не путать со свободным по)
|
|||
97
Mits
30.01.12
✎
07:23
|
(96)ООП
|
|||
98
Ковычки
30.01.12
✎
07:35
|
(95) ну да, если тайл инициализирован
|
|||
99
Rie
30.01.12
✎
07:37
|
(98) А он должен быть инициализирован - иначе на фига он там вообще нужен.
А поскольку в задаче предполагается добавление только в конец списка - то именно "Хвост" и нужен. |
|||
100
1Сергей
30.01.12
✎
07:46
|
100 %
|
|||
101
Ковычки
30.01.12
✎
11:44
|
Кипятите ?
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |