Премини към съдържанието
Форумът в приложение

По-лесно сърфиране. Научи повече.

Kaldata.com - Форуми

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

За да инсталирате това приложение на iOS и iPadOS
  1. Докоснете Иконата за споделяне в Safari
  2. Превъртете менюто и докоснете Добавяне към началния екран.
  3. Докоснете Добавяне в горния десен ъгъл.
За да инсталирате това приложение на Android
  1. Докоснете менюто с 3 точки (⋮) в горния десен ъгъл на браузъра.
  2. Докоснете Добавяне към началния екран или Инсталиране на приложение.
  3. Потвърдете, като докоснете Инсталиране.

Добре дошли!

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

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

 

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

Featured Replies

Здравейте, имам една задача свързана с динамичен стек и искам да попитам, защо при формалните параметри на функцията 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 (преглед на промените)

  • Отговори 941
  • Прегледи 234,5k
  • Създадено
  • Последен отговор

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


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

 

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


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

 

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


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


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

 

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

Редактирано от Реджеп Иведик (преглед на промените)

Мерси за бързия отговор!Понеже и аз за пръв път виждам такова нещо, реших да попитам какво точно означава.В крайна сметка щом между знака * /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;
}

Архивирана тема

Темата е твърде стара и е архивирана. Не можете да добавяте нови отговори в нея, но винаги можете да публикувате нова тема, в която да продължи дискусията. Регистрирайте се или влезте във вашия профил за да публикувате нова тема.

Разглеждащи това в момента 0

  • Няма регистрирани потребители разглеждащи тази страница.

Дарение

  • Подкрепи съществуването на форума - направи дарение
    25%
    Дарени 252.69 EUR от нужните 1,000.00 EUR

Бюлетин

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

Профил

Навигация

Търсене

Търсене

Конфигуриране на push известия в браузъра

Chrome (Android)
  1. Докоснете иконата на катинар до адресната лента.
  2. Докоснете Разрешения → Известия.
  3. Променете предпочитанията си.
Chrome (Desktop)
  1. Кликнете върху иконата на катинар в адресната лента.
  2. Изберете Настройки на сайта.
  3. Намерете Известия и коригирайте предпочитанията си.