Имя: Пароль:
IT
 
Где ошибка в данном коде?
,
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
Кипятите ?
Требовать и эффективности, и гибкости от одной и той же программы — все равно, что искать очаровательную и скромную жену... по-видимому, нам следует остановиться на чем-то одном из двух. Фредерик Брукс-младший