1. Получи 30.000 рублей. Для получения денег необходимо принять участие в конкурсе авторов codeby. С условиями и призами можно ознакомиться на этой странице ...

    Внимание! Регистрация авторов на конкурс закрыта.

    Скрыть объявление
  2. Требуются разработчики и тестеры для проекта codebyOS. Требования для участия в проекте: Знание принципов работы ОС на базе Linux; Знание Bash; Крайне желательное знание CPP, Python, Lua; Навыки системного администрирования. Подробнее ...

    Скрыть объявление

Помогите исправить код задачи...

Тема в разделе "Вопросы новичков и не только", создана пользователем xparen, 28 мар 2011.

  1. xparen

    xparen Гость

    Репутация:
    0
    Помогите найти ошибку в коде... Программа написана в оконном режиме.. при нажатии клавиши Просмотр... программа зацикливаеться и выводит без конца одно и то же число... Ниже код программы... Также прикрепляю всю программу целиком.

    Код:
    //---------------------------------------------------------------------------
    struct Stack {
    int info;
    Stack * next;
    } *begin, *t;
    //---------------------------------------------------------------------------
    Stack* InStack(Stack*, int);
    void View(Stack*);
    void Del_All(Stack **);
    //--------------------------------- Создать ---------------------------------
    void __fastcall TForm1::Button1Click(TObject *Sender)
    //------проверка перед созданием----
    {
    int i, in, n = StrToInt(Edit1->Text);
    if(begin != NULL){
    ShowMessage("Освободите память!");
    return;
    }
    //----------------------------------
    for(i = 1; i <= n; i++){
    in = random(20);
    begin = InStack(begin, in);
    }
    Memo1->Lines->Add("Создано элементов " + IntToStr(n));
    }
    //---------------------------- Добавить -------------------------------------
    
    void __fastcall TForm1::Button2Click(TObject *Sender)
    {
    int i, in, n = StrToInt(Edit2->Text);
    for(i = 1; i <= n; i++){
    in = random(20);
    begin = InStack(begin, in);
    }
    Memo1->Lines->Add("Добавлено элементов " + IntToStr(n));
    }
    //-------------------------------- Очистить ---------------------------------
    
    void __fastcall TForm1::Button3Click(TObject *Sender)
    {
    if (begin != NULL) Del_All(&begin);
    ShowMessage("Память освобождена!");
    }
    //------------------------------------ Выход --------------------------------
    
    void __fastcall TForm1::Button5Click(TObject *Sender)
    {
    if(begin != NULL) Del_All(&begin);
    Close();
    }
    //------------------------------- Просмотр ----------------------------------
    
    
    void __fastcall TForm1::Button6Click(TObject *Sender)
    {
    if(!begin){
    ShowMessage("Стек Пуст!");
    return;
    }
    Memo1->Lines->Add("--- Элементы ---");
    View(begin);
    }
    //----------------------------- Ф-ия добавки --------------------------------
    Stack* InStack(Stack *p, int in) {
    Stack *t = new Stack;
    t -> info = in;
    t -> next = p;
    return t;
    }
    //----------------------------- ф-ия просмотра ------------------------------
    void View(Stack *p) {
    Stack *t = p;
    while( t != NULL) {
    Form1->Memo1->Lines->Add("  " + IntToStr( t->info));
    }
    }
    //---------------------------- ф-ия освобождения памяти ---------------------
    void Del_All(Stack **p) {
    while(*p != NULL) {
    t = *p;
    *p = (*p) -> next;
    delete t;
    }
    }
     

    Вложения:

    • 2.2.zip
      Размер файла:
      4,4 КБ
      Просмотров:
      8
  2. xparen

    xparen Гость

    Репутация:
    0
    Народ, ау=))) кто-нибудь поможет найти ошибку?!
     
  3. ierofant

    ierofant Гость

    Репутация:
    0
    А самому поискать, лень что ли? Ты бы хоть место нашёл, где программа в цикл падает, а потом бы анализировал почему так.

    Код:
    std::cout << "line: "<< __LINE__ << std::endl;
    Вставь в циклы, которые больше всего подозреваешь, и смотри где программа циклится.
     
  4. xparen

    xparen Гость

    Репутация:
    0
    Не хочу показаться грубым, но я пишу тему в разделе, специально созданном для таких "ляпов" и ошибок. Если бы я сам мог найти эту ошибку, я бы давно это сделал и не писал, откровенно говоря, тупых сообщений с вашей стороны.
    Надеюсь на дальнейшее взаимопонимание и поддержку.
     
  5. ierofant

    ierofant Гость

    Репутация:
    0
    Чего так переживать? Поверьте мне мало кто захочет искать в этом коде ошибку. А совет я вам дал дельный, не знаю почему вы не хотите им воспользоваться, так вы её самостоятельно проще всего и найдёте. Программист должен учится не только непосредственно программированию, но и поиску ошибок в коде.
     
  6. RiCrO

    RiCrO Гость

    Репутация:
    0
    Ищите "взаимопонимание" и "поддержку"? Добро пожаловать на http://msdn.microsoft.com

    Успехов вам! ;)

    Полностью поддерживаю слова ierofant. Он знает что говорит.
     
  7. xparen

    xparen Гость

    Репутация:
    0
    Все нашел ошибку....
    В функции просмотра после вывода в Memo1 не хватает перемещения текущего элемента на следующий, т.е.
    t=t->next;
     
  8. xparen

    xparen Гость

    Репутация:
    0
    С программой разобрался... Но снова
    Код:
    void del_chet(Stack **p) {
    while(*p != NULL) {
    t = *p;
    *p = (*p) -> next;
    if((t->info)%2==0)
    delete t;
    }
    }
    Вроде, должна работать.... Но не работает=)) (должна удалять из стека четные элементы)

    Что здесь не так?!
     
  9. ierofant

    ierofant Гость

    Репутация:
    0
    Сложно, конечно, разобраться в этом кусочке. Рискну предположить, что здесь происходит смещение элементов, а потом удаление с проверкой условия. Только тогда получается что второй элемент запишется на место первого. Почему перезапись происходит даже тогда, когда элементы не удаляются?
     
  10. xparen

    xparen Гость

    Репутация:
    0
    эта функция работает, но не так как надо... совсем...
    после выполнения её удаляеться весь стек целиком, а не его четные элементы.... вопрос почему?!
     
  11. lazybiz

    lazybiz Well-Known Member

    Репутация:
    0
    Регистрация:
    3 ноя 2010
    Сообщения:
    1.339
    Симпатии:
    0
    Показывай исправленный код целиком.
     
  12. xparen

    xparen Гость

    Репутация:
    0
    Вылаживаю весь код целиком (оконное приложение). Файлы программы ниже. Привожу здесь текст того, что у меня получилось. Суть: ввод(вывод) данных в(из) стека (случайные числа), удаление из стека четных чисел (вот именно эта ф-ия не работает правильно, а удаляет стек целиком).
    Код:
    struct Stack {
    int info;
    Stack * next;
    } *begin, *t;
    //---------------------------------------------------------------------------
    Stack* InStack(Stack*, int);
    void View(Stack*);
    void Del_All(Stack **);
    void Resh(Stack **);
    //--------------------------------- Создать ---------------------------------
    void __fastcall TForm1::Button1Click(TObject *Sender)
    //------проверка перед созданием----
    {
    int i, in, znak, n = StrToInt(Edit1->Text);
    if(begin != NULL){
    ShowMessage(" Освободите память ");
    return;
    }
    //----------------------------------
    for(i = 1; i <= n; i++){
    in = random(20);
    znak = random(2);
    if(znak < 1)
    in=in*(-1);
    begin = InStack(begin, in);
    }
    Memo1->Lines->Add("Создано элементов " + IntToStr(n));
    }
    //---------------------------- Добавить -------------------------------------
    
    void __fastcall TForm1::Button2Click(TObject *Sender)
    {
    int i, in, znak, n = StrToInt(Edit2->Text);
    for(i = 1; i <= n; i++){
    in = random(100);
    znak = random(2);
    if(znak < 1)
    in=in*(-1);
    begin = InStack(begin, in);
    }
    Memo1->Lines->Add("Добавлено элементов " + IntToStr(n));
    }
    //-------------------------------- Очистить ---------------------------------
    
    void __fastcall TForm1::Button3Click(TObject *Sender)
    {
    if (begin != NULL) Del_All(&begin);
    ShowMessage(" Память освобождена ");
    }
    //------------------------------------ Выход --------------------------------
    
    void __fastcall TForm1::Button5Click(TObject *Sender)
    {
    if(begin != NULL) Del_All(&begin);
    Close();
    }
    //------------------------------- Просмотр ----------------------------------
    
    
    void __fastcall TForm1::Button6Click(TObject *Sender)
    {
    if(!begin){
    ShowMessage(" Стек Пуст ");
    return;
    }
    Memo1->Lines->Add("--- Элементы ---");
    View(begin);
    }
    //----------------------------- Ф-ия добавки --------------------------------
    Stack* InStack(Stack *p, int in) {
    Stack *t = new Stack;
    t -> info = in;
    t -> next = p;
    return t;
    }
    //----------------------------- ф-ия просмотра ------------------------------
    void View(Stack *p) {
    Stack *t = p;
    while( t != NULL) {
    Form1->Memo1->Lines->Add("  " + IntToStr( t->info));
    t=t->next; 
    }
    }
    //---------------------------- ф-ия освобождения памяти ---------------------
    void Del_All(Stack **p) {
    while(*p != NULL) {
    t = *p;
    *p = (*p) -> next;
    delete t;
    }
    }
    //-------------------------------------------------------------------------------
    //--------------------------------- Удаление ---------------------------------
    //-------------------------------------------------------------------------------
    void __fastcall TForm1::Button4Click(TObject *Sender)
    {
    if(!begin){
    ShowMessage(" Стек Пуст ");
    return;
    }
    Memo1->Lines->Add("--- Решение ---");
    Resh(&begin);
    View(begin);
    }
    //----------------------------------- ф-ия удаления четных чисел ---------
    void Resh(Stack **p) {
    while(*p != NULL) {
    t = *p;
    *p = (*p) -> next;
    if((t->info)%2==0)
    delete t;
    }
    }
     

    Вложения:

    • 2.2.zip
      Размер файла:
      784,4 КБ
      Просмотров:
      7
  13. lazybiz

    lazybiz Well-Known Member

    Репутация:
    0
    Регистрация:
    3 ноя 2010
    Сообщения:
    1.339
    Симпатии:
    0
    Слишком много чего исправлять. Смотри мой пример и делай по аналогии:
    Код:
    #include <iostream.h>
    
    struct xlist {
    int		value;
    xlist *	next;
    };
    
    struct xlist *	first	= NULL;
    struct xlist *	last	= NULL;
    
    void add( int val )
    {
    struct xlist * p = new xlist;
    p->value = val;
    p->next = NULL;
    if ( !last ) {
    first = p;
    last = p;
    } else {
    last->next = p;
    last = p;
    }
    }
    
    void del_even()
    {
    struct xlist * a = first;
    while ( a && !(a->value & 1) ) a = a->next;
    first = a;
    
    while ( a && a->next ) {
    if ( !(a->next->value & 1) ) {
    a->next = a->next->next;
    } else {
    a = a->next;
    }
    }
    }
    
    void print()
    {
    struct xlist * p = first;
    while ( p ) {
    cout << p->value << endl;
    p = p->next;
    }
    }
    
    int main()
    {
    for ( int i = 0; i < 10; i++ ) {
    add( i );
    }
    del_even();
    print();
    return 0;
    }
     
  14. xparen

    xparen Гость

    Репутация:
    0
    Спасибо, круто работает.... быстро, и четко, и без лишнего.... Только плз можешь еще объяснить как работает удаление?! а то что-то капался в функции удаления... но не сообразил как это происходит.... С МЕНЯ ПЕЧЕНЬКА=) ввиде + в репутацию=)
    Код:
    void del_even()
    {
    struct xlist * a = first;
    while ( a && !(a->value & 1) )
    a = a->next;
    first = a;
    
    while ( a && a->next ) {
    if ( !(a->next->value & 1) ) {
    a->next = a->next->next;
    } else {
    a = a->next;
    }
    }
    }
     
  15. lazybiz

    lazybiz Well-Known Member

    Репутация:
    0
    Регистрация:
    3 ноя 2010
    Сообщения:
    1.339
    Симпатии:
    0
    Тут происходит перебор элементов с самого начала до тех пор пока не встретится первый нечетный, т.е. все четные с самого начала пропускаются и в конце указатель first указывает на первый нечетный элемент:
    Код:
    	struct xlist * a = first;
    while ( a && !(a->value & 1) ) a = a->next;
    first = a;
    Тут, начиная с нечетного элемента перебираются все остальные и из них так же удаляются все четные:
    Код:
    	while ( a && a->next ) {
    if ( !(a->next->value & 1) ) { // если a->next четный ...
    a->next = a->next->next; // пропускаем
    } else {
    a = a->next; // не пропускаем
    }
    }
    P.S.: единственное о чем я забыл, так это об освобождении памяти удаляемых элементов)
     
  16. xparen

    xparen Гость

    Репутация:
    0
    Спасиб=/ ну очистить память эт не проблема=)
     
  17. lazybiz

    lazybiz Well-Known Member

    Репутация:
    0
    Регистрация:
    3 ноя 2010
    Сообщения:
    1.339
    Симпатии:
    0
    Так будет правильней:
    Код:
    void del_even()
    {
    struct xlist * a = first;
    struct xlist * b;
    while ( a && !(a->value % 2) ) {
    b = a;
    a = a->next;
    delete b;
    }
    first = a;
    
    while ( a && a->next ) {
    if ( a->next->value % 2 ) {
    // odd
    a = a->next;
    } else {
    // even
    b = a->next;
    a->next = a->next->next;
    delete b;
    }
    }
    }
     
Загрузка...

Поделиться этой страницей