Премини към съдържанието
  • Добре дошли!

    Добре дошли в нашите форуми, пълни с полезна информация. Имате проблем с компютъра или телефона си? Публикувайте нова тема и ще намерите решение на всичките си проблеми. Общувайте свободно и открийте безброй нови приятели.

    Моля, регистрирайте се за да публикувате тема и да получите пълен достъп до всички функции.

     

Помощ за задачи на C/C++ (merged)


Препоръчан отговор

Здравейте, имам една задача свързана с динамичен стек и искам да попитам, защо при формалните параметри на функцията push и pop, стека се задава с *& (*&start).По-конкретно, какво означава като пред името на стека има добавени "*&".А ето и кода на програмата(която си работи просто не мога да си обясня това нещо):

#include <iostream>
using namespace std;
int br=0;

struct elem
{
      int key;
      elem *next;
}*s1=NULL, *p, *s2=NULL;
void push(int n, elem *&start);
int pop(int &n,elem *&start);
void insert();


void insert()
{    
    int n=1;

    while(n!=0)  // 0 za izhod
    {
        cout<<"\n Vuvedi cifra: ";
        cin>>n;
        if (n!=0) push(n,s1);
    }

    cout<<endl;
}

void push(int n, elem *&start)
{
      p=start;
      start=new elem;
      start->key=n;
      start->next=p;
      br++;
}

int pop(int &n,elem *&start)
{
      if(start)
      {
            n=start->key;
            p=start;
            start=start->next;
            delete p;
            return 1;
      }
      else
      {
            return 0;
      }
}


void main()
{
    insert();
      int m, a, i;

      do
      {
            cout<<"\n Vuvedi chislo mejdy 1 i "<<br<<" !"<<endl;
            cout<<" m= ";
            cin>>m;

      }while(m<1 && m>br);

 

        for(i=1;i<m;i++)
        {
            pop(a,s1);
            push(a,s2);
        }
        cout<<"\n Vuvedi nova stojnost "<<endl;
      cout<<" A=  ";
      cin>>a;
        s1->key=a;
        while(pop(a,s2))
            push(a,s1);
    
        while(pop(a,s1))
        cout<<" "<<a<<"\t";
      
}
Редактирано от notorious19 (преглед на промените)
Линк към коментара
Сподели в други сайтове

Старт е пойнтър към структурата. Обаче го променяш във функциите. За да можеш да го променяш, трябва да го подадеш бай реферънс, не бай велю.


Подаваш адреса на пойнтъра, за да можеш да променяш във функцията стойността му за да може той после да сочи към друга структура при следващото извикване на функцията.

 

Иначе ако го подадеш бай Велю, като излезеш от функцията и той все едно не е променян, когато я викаш пак..


Когато подаваш параметър по стойност (бай Велю), подаваш копие и във функцията се променя копието. 

 

Ако искаш параметъра примерно да нараства или да намалява със всяко извикване на функцията и да "помни" променената си от предишното извикване стойност, трябва да го подадеш бай реферънс.


Направено е за улеснение на потребителите на функцията. Иначе ако авторът напише в декларацията пойнтър ту пойнтър, тогава потребителя ще трябва като я вика, да я вика с референция. 


Не знаех, че може и така. Сега за първи път виждам. Щом казваш, че работи, значи компилатора го позволява.

 

Виждал съм само варианта с пойнтър ту пойнтър в декларацията, и като викаш функцията да трябва да референсираш.

Редактирано от Реджеп Иведик (преглед на промените)
Линк към коментара
Сподели в други сайтове

Мерси за бързия отговор!Понеже и аз за пръв път виждам такова нещо, реших да попитам какво точно означава.В крайна сметка щом между знака * /dereference/ и start(променлива указател) има &/reference/, значи всъщност се променя стойността на предадения по адрес указател във функцията.

Редактирано от notorious19 (преглед на промените)
Линк към коментара
Сподели в други сайтове

Типа е elem* а & показва че трябва да върне обратно стойността след излизане от функцията.

Иначе ако беше указател към указател трябваше да бъде elem ** - подобен запис се ползва в С-то

само че функцията тогава трябва да се вика с pop(&n, &start);

Макар че двата записа на практика правят едно и също, първия е по-четлив и по-лесен за ползаване.

Линк към коментара
Сподели в други сайтове

Макар че двата записа на практика правят едно и също, първия е по-четлив и по-лесен за ползаване.

Не е така, да подаваш през указател и през псевдоним са две различни неща, и на теория и на практика, и тази разлика трябва да се знае.
Линк към коментара
Сподели в други сайтове

Никъде не е съм написал, че са едно и също нещо.

Каза "и двата записа на практика правят едно и също", в действителност правят едно и също само в определени случаи. Може да са повечето случаи, но не са и всички случаи. Редактирано от flare (преглед на промените)
Линк към коментара
Сподели в други сайтове

Типа е elem* а & показва че трябва да върне обратно стойността след излизане от функцията.

Иначе ако беше указател към указател трябваше да бъде elem ** - подобен запис се ползва в С-то

само че функцията тогава трябва да се вика с pop(&n, &start);

Макар че двата записа на практика правят едно и също, първия е по-четлив и по-лесен за ползаване.

 

ххх** се ползва и в С++, не само в С.

 

В документацията на Windows,  навсякъде е ххх** и референсираш като ги викаш. 

Линк към коментара
Сподели в други сайтове

Здравейте, може ли да ми помогнете със следната задача:  Имаме масив [10][10], като трябва да се въведе стойност за всяка от клетките, да се сумират положителните числа над главния диагонал и да се изведе масива в табличен вид. Да, ама при мен нещо със сбора ми куца. Кодът дотук(дал съм големина на масива [3][3], за да е по лесно изчислението и ++ на елементите от масива при сумата, за да като пробвам с еднакви числа да разбирам кои сумира. Та ето го и него:

#include <stdio.h>
int main (void)
{
    int A[3][3],red,kolona,sum;
sum=0;

for(kolona=0; kolona<3; kolona++)
for(red=0; red<3; red++){
printf("vavedi A[%d][%d]= ", kolona, red);
scanf("%d", &A[kolona][red]);
}
 
 kolona= 1;
 
 for(red=0; red<3; red++){
            if(A[kolona][red] >0) {
            sum= sum+ A[kolona][red];
            A[kolona][red]++;
            }
 kolona++;
}
   
printf("sumata na polokolonaitelnite elementi nad glavniq diagonal e %d\n",sum);
for(red=0; red<3;red++)
for(kolona=0; kolona<3; kolona++){
         printf("A[%d][%d]= %d", red, kolona, A[red][kolona]);
         printf("\t");
         }
         printf("\n");
  system("PAUSE");	
  return 0;
}
Линк към коментара
Сподели в други сайтове

sum=0;
// za A[10][10]
for (red=0; red<9; red++) 
    for (kolona=red+1; kolona<10; kolona++)
         if (A[red][kolona]>0) sum+=A[red][kolona];

Редактирано от ined (преглед на промените)
Линк към коментара
Сподели в други сайтове

  • 2 седмици по-късно...

Здравейте, моля за малко помощ или насоки как трябва да стане една задача с двусвързани списъци, понеже не мога разбера добре условието и.Задачата е следната:

Да се състави функция за обединение на два подредени в двусвързани списъка с начални указатели START1 и START2 в нов списък със запазване на подредбата.

Линк към коментара
Сподели в други сайтове

Здравейте, моля за малко помощ или насоки как трябва да стане една задача с двусвързани списъци, понеже не мога разбера добре условието и.Задачата е следната:

Да се състави функция за обединение на два подредени в двусвързани списъка с начални указатели START1 и START2 в нов списък със запазване на подредбата.

 

1. Като тръгнеш от SТART1 и продължаваш докато стигнеш до последния елемент в списъка. 

2. Указателя next на последния елемент на първия списък го променяш така, че да сочи към първия елемент на втория списък.

3. Указателя previous на първия елемент на втория списък го променяш така, че да сочи към последния елемент на първия списък.

 

Ако някъде записваш броя на елементите в списъка, то броя на елементите в получения нов списък е равен на броя на елементите на първия списък плюс броя на елементите на втория.

Линк към коментара
Сподели в други сайтове

Това е най-лесния начин да се направи новия масив, но не съм сигурен дали "със запазване на подредбата" значи това или че и новия списък трябва да е подреден по същия начин. А и ако трябва да се запазят първоначалните два списъка непокътнати нещата малко ще се усложнят.

Линк към коментара
Сподели в други сайтове

Да, трябва да останат непокътнати и това малко ме затруднява.Аз, доколкото разбирам, първо трябва да попълня двата списъка с помощта на функция за попълване и после да направя функция, която да ги слепи като се запази първоначалната им подредба.Какъв sort трябва да използвам в тази функция, ако не се лъжа?

Линк към коментара
Сподели в други сайтове

Здравейте! Може ли малко помощ? При пускане пише "Missing function header (old style format?) Благодаря ви ! 
 
#include <iostream> 
using namespace std;
struct elem
 
{int key;elem*left,*right;}*root=NULL;
int count = 1;
{
if ( Left() ) count += Left()->CoutChildren();
if ( Right() ) count += Right()->CoutChildren();
 
return count;
}
Линк към коментара
Сподели в други сайтове

 

Здравейте! Може ли малко помощ? При пускане пише "Missing function header (old style format?) Благодаря ви ! 
 
#include <iostream> 
using namespace std;
struct elem
 
{int key;elem*left,*right;}*root=NULL;
int count = 1;
{
if ( Left() ) count += Left()->CoutChildren();
if ( Right() ) count += Right()->CoutChildren();
 
return count;
}

 

 

Нямаш заглавие на функцията. Всяка функция трябва да има име.

 

Освен това, ако не дефинираш входна точка, трябва да имаш една функция с име main(), която се приема за входна точка по подразбиране.

Редактирано от Реджеп Иведик (преглед на промените)
Линк към коментара
Сподели в други сайтове

Не знам на какъв език е писана тая функция, ама ако е на C или C++ по-скоро би трябвало да изглежда

int CountChildren(elem *ptr)
{
    int count=1;
    if (ptr->left)  count+=CountChildren(ptr->left);
    if (ptr->right) count+=CountChildren(ptr->right);
    return count;
}
Линк към коментара
Сподели в други сайтове

 

Не знам на какъв език е писана тая функция, ама ако е на C или C++ по-скоро би трябвало да изглежда

int CountChildren(elem *ptr)
{
    int count=1;
    if (ptr->left)  count+=CountChildren(ptr->left);
    if (ptr->right) count+=CountChildren(ptr->right);
    return count;
}

 

Няма как да е на С  :D  :D  :D

В С няма <iostream>

Линк към коментара
Сподели в други сайтове

void merge(elem *start1, elem *start2){
while(start1->next)
start1=start1->next;
if(start2->prev=NULL){
start1->next=start2;
start2->prev=start1;
}}

Нещо такова ли трябва да стане функцията за обединението на двата двусвързани списъка?

Линк към коментара
Сподели в други сайтове

Не, така написано списъците никога няма да се обединят,

а и ако някой от тях е празен ще стане проблемация.

elem* merge(elem* s1, elem* s2)
{
    if (s1==NULL) return s2;
    if (s2) 
    {
        elem *p=s1;
        while (p->next) p=p->next;
        s2->prev=p;
        p->next=s2;
    }
    return s1;
}
а в програмата я викаш функцията примерно със:

start=merge(start1, start2);

Редактирано от ined (преглед на промените)
Линк към коментара
Сподели в други сайтове

Благодаря много за бързия отговор, само искам да попитам последно, как трябва да се промени функцията за въвеждане, така че елементите да бъдат подредени в списъка?

elem *add(elem *st, int n) 
{ 
    elem *p=st; 
    st=new elem; 
    st->key=n; 
    st->prev=NULL; 
    st->next=p; 
    if(p) 
        p->prev=st;
	return st;
}
Линк към коментара
Сподели в други сайтове

Ами ти кажи, не мене ще ме изпитват.

Само да спомена, че така написана функцията не е удобна за ползаване; по-добре е:

void add(elem *&st, int n) 
{ 
    elem *p=st; 
    st=new elem; 
    st->key=n; 
    st->prev=NULL; 
    st->next=p; 
    if (p) p->prev=st;
}
Линк към коментара
Сподели в други сайтове

elem *add(elem *st, int n) 
{ 
 elem *p=st; 
    if(p!=NULL && p->key>n){
	     st=new elem;
	     st->key=n;
	     st->next=p->next;
	     st->prev=p;
	     }
	else if(p!=NULL && p->key<n){
	    st=new elem;
	    st->key=n;
	    st->next=p;
	    st->prev=p->prev;
	    }
	else{
	    st=new elem;
	    st->key=n;
	    st->next=p;
	    st->prev=NULL;
	    }
	    return st;
}

Ето така успях да измисля функцията да ги подрежда, но отново нещо не е както трябва и не се извеждат всички въведени числа...

Редактирано от notorious19 (преглед на промените)
Линк към коментара
Сподели в други сайтове

void add(elem* &st, int num)
{
    elem *p=new elem;
    p->key=num;
    if (st==NULL)
    {
        p->next=NULL;
        p->prev=NULL;
        st=p;
        return;
    }
    if (st->key >= num)
    {
        p->next=st;
        p->prev=NULL;
        st->prev=p;
        st=p;
        return;
    }
    elem *t=st;
    while (t->next && t->next->key < num)
         t=t->next;
    p->prev=t;
    p->next=t->next;
    t->next=p;
    if (p->next) p->next->prev=p;
    return;
}
Редактирано от ined (преглед на промените)
Линк към коментара
Сподели в други сайтове

Здравейте!Може ли да ми помогнете с модификацията на тези функции, така че да се открият върховете с 2 входящи дъги в граф.

void check_max(char key, link *addr, int *br)
{
bool flag = true;
link *p;

for (int i = 0; i < N; i++)
if (g[i]) {
p = g[i];
while (p) {
if (key == p->key && addr != p) {
flag = false;
break;
}
p = p->next;
}
}
cout << endl;

if (flag == true) {
*br += 1;
cout << key << "\n e tarsenia vrah." << endl;
}
}

void print_max()
{
int dg = 0, br = 0;
link *p;

for (int i = 0; i < N; i++)
if (g[i]) {
p = g[i];
dg++;
while (p) {
dg += 1;
p = p->next;
}
if (dg)
check_max(g[i]->key, g[i], &br);
}

if (!br)
cout << endl << " Niama takiva varhove!" <<endl;
else
cout << endl << " Broiat na namerenite varhove s vhodiashti dygi e: " << br << endl;
}
Линк към коментара
Сподели в други сайтове

Добавете отговор

Можете да публикувате отговор сега и да се регистрирате по-късно. Ако имате регистрация, влезте в профила си за да публикувате от него.

Гост
Напишете отговор в тази тема...

×   Вмъкнахте текст, който съдържа форматиране.   Премахни форматирането на текста

  Разрешени са само 75 емотикони.

×   Съдържанието от линка беше вградено автоматично.   Премахни съдържанието и покажи само линк

×   Съдържанието, което сте написали преди беше възстановено..   Изтрий всичко

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Добави ново...

Информация

Поставихме бисквитки на устройството ви за най-добро потребителско изживяване. Можете да промените настройките си за бисквитки, или в противен случай приемаме, че сте съгласни с нашите Условия за ползване