Стек и операции над ним

Тема в разделе "Общие вопросы по С и С++", создана пользователем ermackprogramis, 7 апр 2011.

  1. ermackprogramis

    ermackprogramis Гость

    Всем привет! Уважаемые програмисты, дайте совет.
    Мне нужно узнать сколько раз в стеке повторяется каждый елемент. Я перепробовал мого чего, но ничего не выходит.
    Вот програма, но не могу найти ошибку у подсчете вхожджения елемента в стек. (последняя функция)

    Код (C++):
    // подключение библиотек
    #include <iostream>
    #include <conio.h>
    #include <stdlib.h>


    using namespace std;

    // прототипы функций
    void input();
    void output();
    void push();
    void stack();
    void outstack();
    void number();

    // оглашение переменных
    FILE *In,*Out; // указатель на файли
    char word[15];

    struct Stack                   
    {
    char data[50];              // поле
    Stack* next;                 //указатель на слкдующий компонент
    }*head,*current;                // указатель на голову и текущий елемент стека

    //==главная функция==
    int main()
    {
    while(true)
    {
    system("cls");
    puts("=====================================");

    // меню
    cout<<"      Menu"<<endl;
    cout<<"1. Input data to file"<<endl;
    cout<<"2. Output data"<<endl;
    cout<<"3. Build the stack"<<endl;
    cout<<"4. Output stack"<<endl;
    cout<<"5. Number of equal words"<<endl;
    cout<<"6. Exit"<<endl;

    // выбор пункта меню
    switch((int)getch())
    {
    case 49: {input();break;}
    case 50: {output();break;}
    case 51: {stack();break;}
    case 52: {outstack();break;}
    case 53: {number();break;}
    case 54: {exit(0);break;}
    // case 56: {;break;}
    }
    }
    }

    //==ввод данных у файл==
    void input()
    {
    system("cls");
    cout<<"Input words to file: "<<endl;
    if(In!=NULL)
    {
    remove("In.txt");
    }
    else
    {
    if((In=fopen("In.txt","w")))
    {
    cout<<"Enter words (in column)"<<endl;
    do{
    fflush(stdin);
    cin>>word; // ввод слова
    fputs(word,In); // запись слова у файл
    fputs("\n",In);
    cout<<"Would you like to continue?[y/n]"<<endl;
    }while(getch()!='n');
    }
    else {cout<<"Cannot open file!!!"<<endl;getch();}
    }
    fclose(In); // закрытие файла
    }

    //==вывод данных из файла==
    void output()
    {
    system("cls");
    if((In=fopen("In.txt","r")))
    {
    cout<<"Entered words: "<<endl<<endl;
    while(!feof(In))
    {
    fgets(word,10,In);
    if(feof(In)) break;
    printf(" %s",word);
    }
    }
    else {cout<<"Cannot open file!!!"<<endl;}
    fclose(In);
    getch();
    }

    //==создание стека==
    void push(char *value)
    {
    current=new(Stack);  
    strcpy(current->data,value);        // внесение елемента в стек
    current->next=head;          
    head=current;                //установить новую вершину стека
    }

    //==создание стека==
    void stack()
    {
    system("cls");
    puts("Building stack from file");
    if((In=fopen("In.txt","r")))
    {
    while(!feof(In))
    {
    fgets(word,15,In); // чтение файла
    if(feof(In)) break;
    push(word);
    }
    }
    else {cout<<"Cannot open file!!!"<<endl;}
    fclose(In);
    cout<<"Done!"<<endl;
    getch();
    }

    //==вывод стека==
    void outstack()
    {
    system("cls");
    cout<<"The components of build stack"<<endl<<endl;
    // виведення стеку
    if((Out=fopen("Out.txt","w")))
    {
    while(head!=NULL)
    {
    cout<<head->data<<endl;
    fputs(head->data,Out);
    head=head->next;
    }
    }
    else {cout<<"Cannot open file!!!"<<endl;}
    fclose(Out);
    getch();
    }

    //==количество==
    void number()
    {
    system("cls");
    int count=0; // счетчик вхождения елемента
    cout<<"Number of equal words in stack"<<endl;

    while(head!=NULL)
    {
    head->data;
    while(head!=NULL)
    {
    if(strcmp(head->data,head->next->data))
    {
    count++;
    }
    head=head->next;
    }
    cout<<head->data<<" == "<<count<<endl;  // вывод елеметна и количества его вхождений в стек
    head=head->next;
    }
    getch();
    }

    Помогите пожалуйста. Скажите что не так.
     
  2. a0z

    a0z Well-Known Member

    Регистрация:
    15 мар 2011
    Сообщения:
    109
    Симпатии:
    0
    Во первых у тебя после всех вычислений напрочь теряется указатель на голову. Объяви локаьную переменную и модифицируй её.

    Во вторых strcmp возвращает 0, если строки равны:
    if(strcmp(head->data,head->next->data) == 0)

    В третьих ты сравниваешь непонятно что. Должно быть как-то так(не компилял):

    while(head!=NULL)
    {
    cur = head->next;
    while(cur)
    {
    if(strcmp(cur->data, head->data))
    {
    count++;
    }
    cur=cur->next;
    }
    cout<<head->data<<" == "<<count<<endl; // вывод елеметна и количества его вхождений в стек
    head=head->next;
    }
     
  3. lazybiz

    lazybiz Well-Known Member
    C\C++ Team

    Регистрация:
    3 ноя 2010
    Сообщения:
    1.344
    Симпатии:
    0
    Ничего личного, но меня всегда интересовало зачем люди пишут while ( head != NULL ) { ... } а не while ( head ) { ... }.
     
  4. ermackprogramis

    ermackprogramis Гость

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


    Добавлено: a0z, спасибо сейчас попробую.
     
  5. ermackprogramis

    ermackprogramis Гость

    Да работает, спасибо большое!!!
    И еще, если не сложно подскажите идею, как создать еще один стек из файла в который будут слова добавлятся только один раз(если в файле есть однаковые)
    Я пробовал так:
    Создать еще один стек, в функцие //==создание стека== создать цикл и условие ввода в новый стек, но чет не пашет

    //==ввод у вспомогательный стек==
    void push_tmp(char *value)
    {
    current_tmp=new(Temp);
    strcpy(current_tmp->info,value);
    current_tmp->next_tmp=head_tmp;
    head_tmp=current_tmp;
    }


    //==создание стека==
    void stack()
    {
    system("cls");
    puts("Building stack from file");
    if((In=fopen("In.txt","r")))
    {
    while(!feof(In))
    {
    fgets(word,15,In); // чтение файла
    if(feof(In)) break;
    push(word);
    while(head)
    {
    if(head->data!=word)
    {
    push_tmp(word); // запись у спомогательный стек
    }
    head=head->next;
    }
    }
    }
    else {cout<<"Cannot open file!!!"<<endl;}
    fclose(In);
    cout<<"Done!"<<endl;
    getch();
    }
    подскажите пожалуйста, если не сложно.
     
  6. a0z

    a0z Well-Known Member

    Регистрация:
    15 мар 2011
    Сообщения:
    109
    Симпатии:
    0
    1.
    if(feof(In)) break;
    Эта строка выглядит подозрительно. Зачем она? Мы уже что-то прочитали в word, оно просто пропадёт?

    2. Строки char* сравнивать
    head->data!=word
    нельзья. strcmp

    3. head затирается. После первого прохода цикла head указывает на дно стека.

    4. В цикле надо проверить, что слово есть в стеке, и если нет - добавить.
    bool found = false;
    ...
    if(strcmp(head->data, word) == 0)
    {
    found = true;
    }
    ...

    if(!found)
    push(word)


    Во-первых легче читается.
    А во-вторых, я пишу на С++ и C# поровну + немного python, java, javascript. Нет резона сбивать руку и вспоминать, что где можно подсократить.
     
  7. ermackprogramis

    ermackprogramis Гость

    Спасибо большое сейчас попробую.
     
  8. ermackprogramis

    ermackprogramis Гость

    if(feof(In)) break; У меня если не поставить ее то последнюю строку файла выводит 2 раза if(feof(In)) break;
     
  9. solova

    solova Гость

    себя не раз подлавливал на !=NULL
    в моём случае всё просто:
    если ход мыслей таков
    "так, эта функция заполняет данные, если выполнилось правильно то..."
    while ( head != NULL ) { ... }
    "так, эта функция заполняет данные. А теперь если данные есть то..."
    while ( head ) { ... }
    когда я сомневаюсь в выполнении какой либо функции(например, новой для меня) то я это место как бы помечаю этим большим ==NULL/!=NULL
    а в том в чём уверен пишу автоматом (head)/(!head)
    так что, некоторые пишут (==NULL/!=NULL) по неопытности, некоторые для наглядности
     
Загрузка...

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