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

  • Автор темы ermackprogramis
  • Дата начала
E

ermackprogramis

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

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(); 
}

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

a0z

Well-known member
15.03.2011
108
0
#2
Во первых у тебя после всех вычислений напрочь теряется указатель на голову. Объяви локаьную переменную и модифицируй её.

Во вторых 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;
}
 

lazybiz

Well-known member
03.11.2010
1 339
0
#3
Ничего личного, но меня всегда интересовало зачем люди пишут while ( head != NULL ) { ... } а не while ( head ) { ... }.
 
E

ermackprogramis

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


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

ermackprogramis

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

//==ввод у вспомогательный стек==
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();
}
подскажите пожалуйста, если не сложно.
 

a0z

Well-known member
15.03.2011
108
0
#6
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)


Ничего личного, но меня всегда интересовало зачем люди пишут while ( head != NULL ) { ... } а не while ( head ) { ... }.
Во-первых легче читается.
А во-вторых, я пишу на С++ и C# поровну + немного python, java, javascript. Нет резона сбивать руку и вспоминать, что где можно подсократить.
 
E

ermackprogramis

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

solova

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