Մուտք

Դիտել ողջ տարբերակը : C++



Էջեր : 1 [2] 3

Lusina
31.03.2012, 09:40
Այո, էտ շուստրի հարցն առաջին կուրսի քննությանն եմ ստացել :)) Ասում էր 2[a]-ն որն ա?
Լեկցիայում սենց թռուցիկ կես բերան ասել էր դասախոսը:
Դե սենց բաները միշտ էլ տետրի մի անկյունում թեթևակի գրածներն էին :))

Հաաա, մոտավորապես հասկացա ինչի մասին ա խոսքը, բայց ճշգրիտ պատասխան տալ չեմ կարող: Քանի որ զանգվածի անունը (էս դեպքում a-ն) հենց ինքը հասցե ա, դրա պատճառով սխալ չի տալիս...բայց թե ինչ ա բերում, էդքան էլ չեմ հասկանում: Սկզբում մտածում էի, որ հենց զանգվածի առաջին տարրը կբերի, բայց ոնց որ թե չէ:
Ես երևի մի քիչ թերի էի գրել, դրա համար էլ զանգվածի առաջին տարրի միտքն ա ծագել, ասեմ, որ i-ն կամայական բնական թիվ ա ( բնականաբար զանգվածի չափի սահմաններում).
Իսկ որպես հուշում՝ սրա հիմքում ընկած ա մաթեմատիկայի ամենատարրական կանոններից մեկը;)

armen9494
31.03.2012, 11:30
Ես երևի մի քիչ թերի էի գրել, դրա համար էլ զանգվածի առաջին տարրի միտքն ա ծագել, ասեմ, որ i-ն կամայական բնական թիվ ա ( բնականաբար զանգվածի չափի սահմաններում).
Իսկ որպես հուշում՝ սրա հիմքում ընկած ա մաթեմատիկայի ամենատարրական կանոններից մեկը;)

Ճիշտն ասած հլը որ էդքան էլ չեմ հասկանում, թե ինչ ա, բայց դրանք իրար ոնց որ թե միշտ հավասար են :unsure

Lusina
31.03.2012, 11:34
Ճիշտն ասած հլը որ էդքան էլ չեմ հասկանում, թե ինչ ա, բայց դրանք իրար ոնց որ թե միշտ հավասար են :unsure
Դե հա, եթե հավասար չլինեին, հետաքրքրություն չէր ունենա ասածս:)) Խնդիրը նրանում ա, թե խի են հավասար, ու խի ա կոմպիլյատորը թույլ տալիս մեզ սենց բան գրել, փորձիր հասկանալ, թե ինչ ա իրա համար a[i] ասվածը.

ashot_1987
31.03.2012, 12:45
Կոմպիլյատորը թույլ ա տալիս որովհետև C++-ի կոմպիլյատորի համար a[0]-ն դա *(a+0)-ն է, a[1]-ը *(a+1)-ը, a[2]-ը *(a+2)-ը ..... a[i]-ն *(a+i)-ին: Իսկ քանի որ *(a+i) = *(i+a) հետևաբար
a[i] = i[a];

Lusina
31.03.2012, 12:53
Կոմպիլյատորը թույլ ա տալիս որովհետև C++-ի կոմպիլյատորի համար a[0]-ն դա *(a+0)-ն է, a[1]-ը *(a+1)-ը, a[2]-ը *(a+2)-ը ..... a[i]-ն *(a+i)-ին: Իսկ քանի որ *(a+i) = *(i+a) հետևաբար
a[i] = i[a];
Շատ ճիշտ ա:) Ինչպես ասացի, հիմքում մաթեմատիկայի ամենատարրական օրենքներից մեկն ա՝ գումարելիների տեղերը փոխելիս գումարը չի փոխվում :))

armen9494
31.03.2012, 13:00
Կոմպիլյատորը թույլ ա տալիս որովհետև C++-ի կոմպիլյատորի համար a[0]-ն դա *(a+0)-ն է, a[1]-ը *(a+1)-ը, a[2]-ը *(a+2)-ը ..... a[i]-ն *(a+i)-ին: Իսկ քանի որ *(a+i) = *(i+a) հետևաբար
a[i] = i[a];

Ա դե պասկալըս ուրիշ էր էլի :D
Մերսի Լուսինային սենց հետաքրքիր հարց տալու ու Աշոտ ջան քեզ, սենց պարզ բացատրելու համար;)


Հ.Գ. եթե սենց հետաքրիր հարցեր էլի հիշեք, տվեք, փորձեմ մտածել, եթե նույնիսկ լուծումը չգտնեմ էլ, ապա էսքանից հետո հաստատ չեմ մոռանա :))

Lusina
31.03.2012, 13:09
Ա դե պասկալըս ուրիշ էր էլի :D
Մերսի Լուսինային սենց հետաքրքիր հարց տալու ու Աշոտ ջան քեզ, սենց պարզ բացատրելու համար;)


Հ.Գ. եթե սենց հետաքրիր հարցեր էլի հիշեք, տվեք, փորձեմ մտածել, եթե նույնիսկ լուծումը չգտնեմ էլ, ապա էսքանից հետո հաստատ չեմ մոռանա :))
Խնդրեմ, ինձ էլ ուրիշն ա ասել:) Ու քանի որ ինձ ասողը հետագայում շփոթության առիթ չլինելու համար ուրիշ բան էլ ա ասել, դա էլ ասեմ.
Սա սովորական int տիպի զանգվածի համար էր ճիշտ, սակայն std::vector -ի համար արդեն չենք կարող գրել v[i] == i[v].Սրա "ինչու"-ի մասին կարաս մտածես:)

armen9494
31.03.2012, 13:12
Խնդրեմ, ինձ էլ ուրիշն ա ասել:) Ու քանի որ ինձ ասողը հետագայում շփոթության առիթ չլինելու համար ուրիշ բան էլ ա ասել, դա էլ ասեմ.
Սա սովորական int տիպի զանգվածի համար էր ճիշտ, սակայն std::vector -ի համար արդեն չենք կարող գրել v[i] == i[v].Սրա "ինչու"-ի մասին կարաս մտածես:)

իսկ std::vector-ը ի՞նչ ա

Lusina
31.03.2012, 13:16
իսկ std::vector-ը ի՞նչ ա

c++-ի ստանդարտ գրադարանի թեմփլեյթ կլաս ա, ավելի մանրամասն այստեղ՝
http://www.cplusplus.com/reference/stl/vector/
Ի դեպ, հարցի պատասխանն էլ կա հղման մեջ, եթե ուշադիր լինես;)

armen9494
31.03.2012, 13:17
c++-ի ստանդարտ գրադարանի թեմփլեյթ կլաս ա, ավելի մանրամասն այստեղ՝
http://www.cplusplus.com/reference/stl/vector/
Ի դեպ, հարցի պատասխանն էլ կա հղման մեջ, եթե ուշադիր լինես;)

Անգլերենով էդքան էլ լավ չեմ հասկանում, նամանավանդ նման բաները. կփորձեմ ռուսերենը ման գալ: Շնորհակալություն:)

Lusina
31.03.2012, 13:29
Անգլերենով էդքան էլ լավ չեմ հասկանում, նամանավանդ նման բաները. կփորձեմ ռուսերենը ման գալ: Շնորհակալություն:)
Դե կարամ մի երկու բառով տնավարի նկարագրեմ :)) Պատկերացրու քեզ ծանոթ մասիվը սովորական, որը կարա լինի քո ուզած տիպի.Այսինքն ինքը կոնտեյներ ա, որի էլեմենտները կլինեն քո ասած տիպով, մասնավորապես , կարան լինեն int տիպի.Ուղղակի vector-ը դա կլաս ա, ու երբ գրում ես v[i], կոմպիլյատոը "կանչում ա" իրա operator[] մեթոդը՝ v[i] == v.operator[](i);

Ruzanna Stepanyan
31.03.2012, 20:31
Դե x-ը կարող եք հայտարարել ինչ տիպի որ կուզեք, էդ կապ չունի:
Այ 100-ի փոխարեն n գրել ինչքան գիտեմ չենք կարող սովորական եղանակով (դե ալտերնատիվ միջոց հաստատ կլինի, բայց դժվար թե էդ ձեր խնդիրներում հետաքրքրի): Չնայած հնարավոր է նաև մի հեշտ հասկանալի մեթոդ առաջարկեն: Ինքս դեռ չգիտեմ:

Ախր խնդրում չի խոսում 100 թվի մասին, խնդիրը ասում է n տարր պարունակող զանգված

ashot_1987
31.03.2012, 21:11
Ախր խնդրում չի խոսում 100 թվի մասին, խնդիրը ասում է n տարր պարունակող զանգված

Զանգվածը հայտարարելիս ինդեքսում պետք է պարտադիր գրել հաստատուն թիվ օրինակ x[50], x[100], կամ const int p=60; int x[p], Զանգվածի ինդեքսում զանգվածը նկարագրելիս չեք կարող գրել փոփոխական թիվ: Դա նածատեսված է նրա համար քանի որ C++ կոմպիլյատորը կոմպիլյացիայից առաջ պետք է իմանա թե հիշողության մեջ ինչքան տեղ պետք է հատկացնի:
Տվյալ դեպքում այդպիսի խնդիրներում վարվում են այսպես` նախապես զանգվածը նկարագրում են այնքան տարրերով որքանը կբավարարի խնդրի լուծման, այսինքն եթե տվյալ խնդրի համար վերցնեք int x[1000], դժվար թե մեկի մտքով անցնի 1000-ից մեծ վերցնի n-ը:

C++ -ում իհարկե կա հնարավորություն որը թույլ կտա զանգվածի ինդեքսում վերցնել փոփոխական թիվ, բայց դրանք արվում են class-երով և կոչվում են դինամիկ հիշողություններ: Բայց այսքան պարզ խնդրի համար չեմ կարծում տենց բաներ պետք գան

armen9494
31.03.2012, 22:35
Զանգվածը հայտարարելիս ինդեքսում պետք է պարտադիր գրել հաստատուն թիվ օրինակ x[50], x[100], կամ const int p=60; int x[p], Զանգվածի ինդեքսում զանգվածը նկարագրելիս չեք կարող գրել փոփոխական թիվ: Դա նածատեսված է նրա համար քանի որ C++ կոմպիլյատորը կոմպիլյացիայից առաջ պետք է իմանա թե հիշողության մեջ ինչքան տեղ պետք է հատկացնի:
Տվյալ դեպքում այդպիսի խնդիրներում վարվում են այսպես` նախապես զանգվածը նկարագրում են այնքան տարրերով որքանը կբավարարի խնդրի լուծման, այսինքն եթե տվյալ խնդրի համար վերցնեք int x[1000], դժվար թե մեկի մտքով անցնի 1000-ից մեծ վերցնի n-ը:

C++ -ում իհարկե կա հնարավորություն որը թույլ կտա զանգվածի ինդեքսում վերցնել փոփոխական թիվ, բայց դրանք արվում են class-երով և կոչվում են դինամիկ հիշողություններ: Բայց այսքան պարզ խնդրի համար չեմ կարծում տենց բաներ պետք գան

Լրիվ համամիտ եմ Աշոտի հետ, մենք էլ սկզբում որ անցնում էինք էս խնդիրները, ասում էի ընդեղ ասվում ա n, ինչի՞ ենք նրա վրա սահմանափակում դնում, կամ եթե այդպես է՝ թող գրքում նշվի n-ի սահմանը:
Բայց դա նորմալ է ու այս խնդիրներում դինամիկ հիշողություն չենք օգտագործում, դա շատ ավելի բարդ է:

Թավով ընդգծաս պահը կանխարգելելու համար մենք n-ը ներմուծելիս էդ սահմանափակումը դնում ենք՝ "ներմուծել n-ը այնքան ժամանակ, քանի դեռ այն մեծ է 1000-ից և փոքր 1-ից" (այսինքն երբ n-ը կգտնվի 1-1000 միջակայքում, ծրագիրը կշարունակվի):

ashot_1987
31.03.2012, 22:55
Չգիտեմ ստեղ գրառմանը ոնց են Շնորհակալություն հայտնում, չգտա :D Մի խոսքով շնորհակալություն

ashot_1987
31.03.2012, 23:06
"ներմուծել n-ը այնքան ժամանակ, քանի դեռ այն մեծ է 1000-ից և փոքր 1-ից":

Բայց երևի հակառակը:)

armen9494
01.04.2012, 00:43
Չգիտեմ ստեղ գրառմանը ոնց են Շնորհակալություն հայտնում, չգտա :D Մի խոսքով շնորհակալություն

Հենց տակը կոճակ կա՝ "շնորհակալություն" :)) Շատ շատ մերսի վարկանիշի համար;)


Բայց երևի հակառակը:)

Չէ, հենց այդպես. ներմուծել այնքան ժամանակ, քանի դեռ n-ը մեծ է 1000 կամ փոքր 1-ից:
Վայ, ընդեղ "և" եմ գրել:oy

ashot_1987
01.04.2012, 09:18
Ներմուծել այնքան ժամանակ, քանի դեռ n-ը մեծ է 1000 կամ փոքր 1-ից:
Վայ, ընդեղ "և" եմ գրել:oy

Ներմուծել այնքան ժամանակ, քանի դեռ n-ը մեծ է 1-ից փոքր է 1000-ից

armen9494
01.04.2012, 09:48
Ներմուծել այնքան ժամանակ, քանի դեռ n-ը մեծ է 1-ից փոքր է 1000-ից

Չէ, էդ դեպքում սխալ կլինի. նայի, ես օրինակ ներմուծում եմ 50, ինքը գնում ստուգում է՝ 50-ը մեծ է 1-ից և փոքր է 1000-ից ու նորից պահանջում ներմուծել n-ը: Իսկ եթե ես ներմուծեմ 2000, ինքը կգնա, կստուգի, որ 2000-ը մեծ է 1-ից, բայց փոքր չէ 1000-ից ու կշարունակի լուծել խնդիրը, արդյունքում սխալ ձևով (մեր դեպքում կուզի, որ ներմուծենք զանգվածի 2000 տարրերը):


Հ.Գ. ոնց որ թե Պասկալի հետ ես խառնում, ընդեղ էր պայմանը հակառակ ձևով դրվում, քանի որ "repeat" "until" էր, այսինքն արա գործողությունը, քանի դեռ պայմանը սխալ է:

ashot_1987
01.04.2012, 10:25
Չէ, էդ դեպքում սխալ կլինի. նայի, ես օրինակ ներմուծում եմ 50, ինքը գնում ստուգում է՝ 50-ը մեծ է 1-ից և փոքր է 1000-ից ու նորից պահանջում ներմուծել n-ը: Իսկ եթե ես ներմուծեմ 2000, ինքը կգնա, կստուգի, որ 2000-ը մեծ է 1-ից, բայց փոքր չէ 1000-ից ու կշարունակի լուծել խնդիրը, արդյունքում սխալ ձևով (մեր դեպքում կուզի, որ ներմուծենք զանգվածի 2000 տարրերը):


Հ.Գ. ոնց որ թե Պասկալի հետ ես խառնում, ընդեղ էր պայմանը հակառակ ձևով դրվում, քանի որ "repeat" "until" էր, այսինքն արա գործողությունը, քանի դեռ պայմանը սխալ է:

Չէ պասկալի հետ չեմ խառնում ուղղակի երևի ինչ որ բան կա իրար չենք հասկանում: Ստեղ n-ը զանգվածում տարրերի քանակն ա, որը ներմուծվում ա նախօրոք, ստուգվում ա մի անգամ, իսկ էտ ստուգվում ա սենց եթե ես զանգվածը նկարագրել եմ x[1000] ուրեմն իմ ներմուծած n-ը պետք ա լինի 1<n<1000, էս ոչ Պասկալ ա, ոչ C++, ոչ էլ Java, պարզ տրամաբանություն ա:

armen9494
01.04.2012, 14:45
Չէ պասկալի հետ չեմ խառնում ուղղակի երևի ինչ որ բան կա իրար չենք հասկանում: Ստեղ n-ը զանգվածում տարրերի քանակն ա, որը ներմուծվում ա նախօրոք, ստուգվում ա մի անգամ, իսկ էտ ստուգվում ա սենց եթե ես զանգվածը նկարագրել եմ x[1000] ուրեմն իմ ներմուծած n-ը պետք ա լինի 1<n<1000, էս ոչ Պասկալ ա, ոչ C++, ոչ էլ Java, պարզ տրամաբանություն ա:

Բեր հլը փորձենք քո ասած ծրագիրը, դու ասում ես այսպես՝


#include <iostream.h>

void main()
{
int n;
do
{
cin>>n;
}
while (1<n && n<1000);

cout<<"nerumucvac e chisht arjeq";
}

Ճի՞շտ եմ հասկացել:

Ruzanna Stepanyan
01.04.2012, 15:38
#include <iostream.h>
void main()
{
double x[100],s=0;
int i,n;
do { cin>>n; } while(1>n || n>100);
for( i=0; i<n; i++)
{
cout<<"x["<<i<<"]=";
cin>>x[i];
}
for( i=2; i<n; i+=2)
s+=x[i];
cout<<"s="<<s<<endl;
}

Էստեղ մի երկու հարց ունեմ:

Մտածում եմ, որ
do { cin>>n; } while(1>n || n>100); էստեղ ինչ որ բան սխալ է: Եվ այս տողում { cin>>n; } սա ինչի ենք վերցրել ձևավոր փակագծերի մեջ:

armen9494
01.04.2012, 15:49
#include <iostream.h>
void main()
{
double x[100],s=0;
int i,n;
do { cin>>n; } while(1>n || n>100);
for( i=0; i<n; i++)
{
cout<<"x["<<i<<"]=";
cin>>x[i];
}
for( i=2; i<n; i+=2)
s+=x[i];
cout<<"s="<<s<<endl;
}

Էստեղ մի երկու հարց ունեմ:

Մտածում եմ, որ
do { cin>>n; } while(1>n || n>100); էստեղ ինչ որ բան սխալ է: Եվ այս տողում { cin>>n; } սա ինչի ենք վերցրել ձևավոր փակագծերի մեջ:

Սկզբում պատասխանեմ երկրորդ հարցին (ձևավոր փակագծերը) ճիշտն ասած չգիտեմ, դասախոսների խորհուրդներցի մնացած սովորություն ա :))

Իսկ առաջինի մեջ ի՞նչն է սխալ. ասում է ներմուծի n-ը քանի դեռ այն փոքր է 1-ից կամ մեծ 100-ից (այսինքն եթե 1<n<100, ուրեմն դուրս արի ներմուծելու ցիկլից ու շարունակի ծրագիրը):

Ruzanna Stepanyan
01.04.2012, 15:59
Սկզբում պատասխանեմ երկրորդ հարցին (ձևավոր փակագծերը) ճիշտն ասած չգիտեմ, դասախոսների խորհուրդներցի մնացած սովորություն ա :))

Իսկ առաջինի մեջ ի՞նչն է սխալ. ասում է ներմուծի n-ը քանի դեռ այն փոքր է 1-ից կամ մեծ 100-ից (այսինքն եթե 1<n<100, ուրեմն դուրս արի ներմուծելու ցիկլից ու շարունակի ծրագիրը):

իսկ էդտեղ կարող եմ կլոր փակագիծ դնել?

1<n<100 բայց սա նշանակում է քանի n-ը me] 1 1-ից և փոքր է 100-ից

armen9494
01.04.2012, 16:25
իսկ էդտեղ կարող եմ կլոր փակագիծ դնել?

Ոչ:)


1<n<100 բայց սա նշանակում է քանի n-ը me] 1 1-ից և փոքր է 100-ից
վայ, սխալ եմ գրել :)) պիտի լինի n<1 կամ n>100

Ruzanna Stepanyan
01.04.2012, 19:22
Ոչ:)

վայ, սխալ եմ գրել :)) պիտի լինի n<1 կամ n>100

Բայց ես մտածում եմ, որ պիտի լինի էսպես n>1 կամ n<100

armen9494
01.04.2012, 20:15
Բայց ես մտածում եմ, որ պիտի լինի էսպես n>1 կամ n<100

Փորձեք գրել էդպես, տեսեք ճիշտ կաշխատի՞:

Ruzanna Stepanyan
02.04.2012, 00:01
Վայ, ոնց գլխի չէի ընկնում, ինչ ամոթ ա :)Ամեն ինչ պարզվեց կամաց-կամաց, շնորհակալություն բոլորիցդ :)

armen9494
02.04.2012, 00:09
Վայ, ոնց գլխի չէի ընկնում, ինչ ամոթ ա :)Ամեն ինչ պարզվեց կամաց-կամաց, շնորհակալություն բոլորիցդ :)

Խնդրեմ, ամոթ բան չկա, իրոք շատ խառն ա, սկզբում ես էլ էի լավ խառնում, նամանավանդ պասկալից հետո, որտեղ գրվում էր հենց էնձեև, ոնց դուք էիք ասում: Դե ասում եմ էլի, պասկալը ավելի մոտիկ ա մարդու լեզվին :))

ashot_1987
02.04.2012, 00:40
#include <iostream.h>
void main()
{
double x[100],s=0;
int i,n;
do { cin>>n; } while(1>n || n>100);
for( i=0; i<n; i++)
{
cout<<"x["<<i<<"]=";
cin>>x[i];
}
for( i=2; i<n; i+=2)
s+=x[i];
cout<<"s="<<s<<endl;
}

Էս ծրագիրը չեմ հասկանում :) Ավելի ճիշտ ինքը սխալ ա էլի: n-ը զանգվածում տարրերի քանակն է, որը ներմուծվում է մի անգամ, այլ ոչ թե do, while-ով: n-ը ներմուծելուց հետո բացվում է ցիկլ որը թույլ է տալիս ներմուծել զանգվածը: Օրինակ ես սենց կգրեի.
#include <iostream>
using std::cout;
using std::cin;
using std::endl;

int main()
{
int x[1000];
int n=0;

cin >> n;

int sum = 0;

for (int i=0; i<n; i++)
cin >> x[i];

for (int i=0; i<n; i+=2)
sum+=x[i];

return 0;
}

Varzor
02.04.2012, 10:39
Զանգվածը հայտարարելիս ինդեքսում պետք է պարտադիր գրել հաստատուն թիվ օրինակ x[50], x[100], կամ const int p=60; int x[p], Զանգվածի ինդեքսում զանգվածը նկարագրելիս չեք կարող գրել փոփոխական թիվ: Դա նածատեսված է նրա համար քանի որ C++ կոմպիլյատորը կոմպիլյացիայից առաջ պետք է իմանա թե հիշողության մեջ ինչքան տեղ պետք է հատկացնի:
Տվյալ դեպքում այդպիսի խնդիրներում վարվում են այսպես` նախապես զանգվածը նկարագրում են այնքան տարրերով որքանը կբավարարի խնդրի լուծման, այսինքն եթե տվյալ խնդրի համար վերցնեք int x[1000], դժվար թե մեկի մտքով անցնի 1000-ից մեծ վերցնի n-ը:

C++ -ում իհարկե կա հնարավորություն որը թույլ կտա զանգվածի ինդեքսում վերցնել փոփոխական թիվ, բայց դրանք արվում են class-երով և կոչվում են դինամիկ հիշողություններ: Բայց այսքան պարզ խնդրի համար չեմ կարծում տենց բաներ պետք գան

Եթե հայտարարվող զանգվածի չափը սկզբնապես հայտնի չէ, ապա օգտագործում են ցուցիչները` int *x:

Varzor
02.04.2012, 10:44
Էս ծրագիրը չեմ հասկանում :) Ավելի ճիշտ ինքը սխալ ա էլի: n-ը զանգվածում տարրերի քանակն է, որը ներմուծվում է մի անգամ, այլ ոչ թե do, while-ով: n-ը ներմուծելուց հետո բացվում է ցիկլ որը թույլ է տալիս ներմուծել զանգվածը:
Սխալ չի: Էդ պայմանը դեկորացիա է: Այսինքն զանգվածի տարրերի քանակը պետք է լինի 1-100 միջակայքում: ներմուծումն այնքան ժամանակ է շարունակվում, մինչև ճիշտ միջակայքի թիվ չներմուծես:
Սա անում են այն դեպքերում, երբ զանգվածի սահմանման ժամանակ նախապես սահմանվել է տարրերի քանակը, համ էլ որպեսզի 0 կամ բացասական թիվ չներմուծվի: Բացասականի պահը կարելի էր հայտարարությամբ լուծել` unsigned int, bajc 0-ի պահը` ոչ:

ashot_1987
02.04.2012, 11:47
Սխալ չի: Էդ պայմանը դեկորացիա է: Այսինքն զանգվածի տարրերի քանակը պետք է լինի 1-100 միջակայքում: ներմուծումն այնքան ժամանակ է շարունակվում, մինչև ճիշտ միջակայքի թիվ չներմուծես:
Սա անում են այն դեպքերում, երբ զանգվածի սահմանման ժամանակ նախապես սահմանվել է տարրերի քանակը, համ էլ որպեսզի 0 կամ բացասական թիվ չներմուծվի: Բացասականի պահը կարելի էր հայտարարությամբ լուծել` unsigned int, bajc 0-ի պահը` ոչ:

Հաաաաաաաաաաաաաա հիմա պարզ ա

Ruzanna Stepanyan
02.04.2012, 12:14
Խնդրում եմ, մի հատ նայեք ինչն եմ սխալ գրել, որ չի աշխատում

Որոշել և արտածել տրված n տարր պարունակող միաչափ զանգվածի փոքրագույն տարրը:


#include <iostream>
using namespace std;
void main()
{
double x[10];
int min, i, n;
for(i=0; i<=n; i++)
cin>>x[i];
min=x[0];
for(i=0; i<=n; i++)
if(x[i]<min)
min=x[i];
cout<<"min="<<min<<endl;
}

Varzor
02.04.2012, 13:06
Խնդրում եմ, մի հատ նայեք ինչն եմ սխալ գրել, որ չի աշխատում
Որոշել և արտածել տրված n տարր պարունակող միաչափ զանգվածի փոքրագույն տարրը:
#include <iostream>
using namespace std;
void main()
{
double x[10];
int min, i, n;
for(i=0; i<=n; i++)
cin>>x[i];
min=x[0];
for(i=0; i<=n; i++)
if(x[i]<min)
min=x[i];
cout<<"min="<<min<<endl;
}
Միանգամից մի քանի սխալ ունես.
1. չես ներմուծում n թիվը, բայց i<=n-ով ցիկլ ես ստուգում:
2. զանգվածիդ տարրերը double տիպի են, բայց min-ը վերցրել ես int:

armen9494
02.04.2012, 17:33
Խնդրում եմ, մի հատ նայեք ինչն եմ սխալ գրել, որ չի աշխատում

Որոշել և արտածել տրված n տարր պարունակող միաչափ զանգվածի փոքրագույն տարրը:


#include <iostream>
using namespace std;
void main()
{
double x[10];
int min, i, n;
for(i=0; i<=n; i++)
cin>>x[i];
min=x[0];
for(i=0; i<=n; i++)
if(x[i]<min)
min=x[i];
cout<<"min="<<min<<endl;
}

Բացի Վարզորի նշած սխալներից, ևս մի սխալ՝
ոչ թե for(i=0; i<=n; i++) այլ for(i=0; i<n; i++)
Բացատրեմ, թե ինչու այսպես: Եթե ես n-ը ներմուծել եմ օրինակի համար 4, ապա պիտի ներմուծեմ 4 տարր, այնպես չէ՞: Այսինքն՝ x[0], x[1], x[2], x[3]: Եթե պայմանը մնա i<=n, ապա ծրագիրը կպահանջի, որ ներմուծեք նաև x[4]-ը, որը չպիտի լինի:

Այս մեկը սխալ չէ, ուղղակի անիմաստ ավել քայլ եք անում:
Երկրորդ ցիկլի մեջ for(i=0; i<n; i++) -ի փոխարեն կարող եք գրել for(i=1; i<n; i++) քանի որ x[0]<x[0] անիմաստ պայման է, քանի որ այդ պահին min=x[0]:
Ծրագիրը ձեր գրած ձևով ճիշտ կաշխատի, բայց անիմաստ տեղը մի անգամ ավել է ստուգելու անիմաստ պայմանը:

ashot_1987
02.04.2012, 20:34
Մի հատ սենց խնդիր ասեմ, չգիտեմ կարողա շատ պարզ խնդիր ա, բայց ուսանող տարիներիս դասախոսս ասեց չկարացա լուծեմ (Էն ժամանակ ծրագրավորումն ու ես շատ հեռու էինք իրարից :D): Խնդիրը սկսնակ ծրագրավորողների համար ա (Չնայած ինքը ավելի շատ հարց ա քան խնդիր)
Ունենք երկու փոփոխական, որոնք ունեն որոշակի արժեքներ, ասենք օրինակ`
int x=29;
int y=38;

Ինչպես առանց միջանկյալ փոփոխականի x-ին վերագրենք y-ի արժեքը y-ին x-ի:

Ruzanna Stepanyan
02.04.2012, 21:04
Ճիշտը որ ասեմ, ես էլ շատ հարազատի պես չեմ ծրագրավորման հետ,նոր -նոր կամաց-կամաց ծանոթանում ենք :)
բայց երևի էսպես
int x=29+9;
int y=38-9;

Lusina
02.04.2012, 21:27
Մի հատ սենց խնդիր ասեմ, չգիտեմ կարողա շատ պարզ խնդիր ա, բայց ուսանող տարիներիս դասախոսս ասեց չկարացա լուծեմ (Էն ժամանակ ծրագրավորումն ու ես շատ հեռու էինք իրարից :D): Խնդիրը սկսնակ ծրագրավորողների համար ա (Չնայած ինքը ավելի շատ հարց ա քան խնդիր)
Ունենք երկու փոփոխական, որոնք ունեն որոշակի արժեքներ, ասենք օրինակ`
int x=29;
int y=38;

Ինչպես առանց միջանկյալ փոփոխականի x-ին վերագրենք y-ի արժեքը y-ին x-ի:


Ճիշտը որ ասեմ, ես էլ շատ հարազատի պես չեմ ծրագրավորման հետ,նոր -նոր կամաց-կամաց ծանոթանում ենք :)
բայց երևի էսպես
int x=29+9;
int y=38-9;
Կամայական թվերի համար ա պետք, մասնավոր դեպք եք նայել դուք:)
Հ.Գ. Հարցը լավն ա, բայց երկուական համակարգի հետ գործ չունեցածի համար էդքան էլ պարզ չի:)

ashot_1987
02.04.2012, 22:04
Կամայական թվերի համար ա պետք, մասնավոր դեպք եք նայել դուք:)
Հ.Գ. Հարցը լավն ա, բայց երկուական համակարգի հետ գործ չունեցածի համար էդքան էլ պարզ չի:)

Չե երկուական թվերի հետ կապ չունի: :)

Lusina
02.04.2012, 22:06
Չե երկուական թվերի հետ կապ չունի: :)
Xor-ից բացի էլի՞ սիրուն ձև կա:think

ashot_1987
02.04.2012, 22:10
Xor-ից բացի էլի՞ սիրուն ձև կա:think

Ինքը պարզ բան ա պետք չի բարդ եղանակներ ման գալ

Lusina
02.04.2012, 22:20
Ինքը պարզ բան ա պետք չի բարդ եղանակներ ման գալ
Դե շատ բարդ չի, բայց սիրուն լուծում ա xor-ովը.
Իսկ պարզ լուծման համար իմ ուղեղը հիմա արգելափակված ա:))

ashot_1987
02.04.2012, 22:22
Դե շատ բարդ չի, բայց սիրուն լուծում ա xor-ովը.
Իսկ պարզ լուծման համար իմ ուղեղը հիմա արգելափակված ա:))

Լավ բարդ լուծումը գրի, ոչինչ :)

Lusina
02.04.2012, 22:30
Լավ բարդ լուծումը գրի, ոչինչ :)
usage.ն էլ արդեն չեմ հիշում, թե ոնց էր, բայց իմաստը սենց՝
x xor y;
y xor x;
x xor y,

ashot_1987
02.04.2012, 22:38
Իմ գրած օրինակի վրա ցույց տամ.

int x=29;
int y=38;

x=x+y; //67
y=x-y; //29
x=x-y; //38

Lusina
02.04.2012, 22:40
Իմ գրած օրինակի վրա ցույց տամ.

int x=29;
int y=38;

x=x+y; //67
y=x-y; //29
x=x-y; //38

Նույնն ա, ինչ իմ գրածը:))
Հ.Գ. Ի դեպ, եթե չեմ սխալվում, xor-ը ավելի արագ կաշխատի.

ashot_1987
02.04.2012, 22:44
Նույնն ա, ինչ իմ գրածը:))
Հ.Գ. Ի դեպ, եթե չեմ սխալվում, xor-ը ավելի արագ կաշխատի.

Ճիշտը որ ասեմ xor չեմ օգտագործել չգիտեմ, էտ Պասկալում ա?

Valentina
02.04.2012, 22:51
Ճիշտը որ ասեմ xor չեմ օգտագործել չգիտեմ, էտ Պասկալում ա?
Գումար ըստ մոդուլ 2-ի
0,0-0
0,1-1
1,0-1
1,1-0

a ^ b
Պասկալում չգիտեմ, բայց C++ ում կա:

Varzor
03.04.2012, 11:30
Մեկ էլ էդ նույնը C++-ում կարելի է ցուցիչների ու հղումների միջոցով անել, բայց ամենահարմար ու արագ լուծումն է ashot_1987-ի տված տարբերակը`

x=x+y;
y=x-y;
x=x-y;

Lusina
03.04.2012, 23:43
Մեկ էլ էդ նույնը C++-ում կարելի է ցուցիչների ու հղումների միջոցով անել, բայց ամենահարմար ու արագ լուծումն է ashot_1987-ի տված տարբերակը`

x=x+y;
y=x-y;
x=x-y;
Ես հիմա ճակատագրական քայլ կանեմ ու կփորձեմ հակառակվել Varzor-ին:))
Ես գրեթե համոզված եմ, որ xor-ը ավելի արագ կաշխատի, քան այդ գրված տարբերակը.

Հ.Գ."Գրեթե" բառս հետո կարա փրկի :))

soultaker
04.04.2012, 01:37
Ես հիմա ճակատագրական քայլ կանեմ ու կփորձեմ հակառակվել Varzor-ին:))
Ես գրեթե համոզված եմ, որ xor-ը ավելի արագ կաշխատի, քան այդ գրված տարբերակը.

Հ.Գ."Գրեթե" բառս հետո կարա փրկի :))

Բնականաբար XOR-ը ավելի արագ կաշխատի, որովհետև 3 բիտային գործողություն անելը ավելի արագ է քան 3 գումարում/հանումը:

Մի այսպիսի հարց` ենթադրենք ունեմ m[10000][10000] մատրից: Հերթով արժեք եմ տալիս(կամ արժեք վերցնում) էլեմենտներին`


for(i = 0; i < 10000; i++)
{
for(j = 0; j < 10000; j++)
{
m[i][j] = m[i][10000 - j - 1] * 2; // Օրինակի համար
}
}



Նույն բանը` երկրորդ տարբերակով


for(i = 0; i < 10000; i++)
{
int* p = m[i];
for(j = 0; j < 10000; j++)
{
p[j] = p[10000 - j - 1] * 2;
}
}


Այժմ հարցը` ինչի համար երկրորդ տարբերակը ավելի արագ չի աշխատում (ոնց որ մի բան էլ ավելի դանդաղ):

ashot_1987
04.04.2012, 12:35
for(i = 0; i < 10000; i++)
{
int* p = m[i];
for(j = 0; j < 10000; j++)
{
p[j] = p[10000 - j - 1] * 2;
}
}


Ինձ թվում ա երկրորդ տարբերակը ավելի արագ չի աշխատում քանի որ երկրորդ տարբերակում p ցուցիչը 10000 անգամ հայտարարվում ա.
for(i = 0; i < 10000; i++)
{
int* p = m[i];
...........

Ruzanna Stepanyan
04.04.2012, 12:56
Խնդրում եմ օգնեք, էս խնդրի մեջ մի բանը էն չեմ արել

Հաշվել և արտածել տրված n տարր պարունակող միաչափ զանգվածի կենտ ինդեքս ունեցող տարրերի քառակուսիների արտադրայլը:

#include <iostream>
#include <math.h>
using namespace std;
void main()
{
int x[10], p, i, n;

do {
cin>>n;
}
while(1>n||n>10);
for(i=0; i<n; i++)
{
cout<<"x["<<i<<"]=";
cin>>x[i];
}
p=1;
for(i=2; i<n; i+=2)

p=p*pow(double (x(i)),2);

cout<<"p="<<p<<endl;
}

ashot_1987
04.04.2012, 13:02
Խնդրում եմ օգնեք, էս խնդրի մեջ մի բանը էն չեմ արել

Հաշվել և արտածել տրված n տարր պարունակող միաչափ զանգվածի կենտ ինդեքս ունեցող տարրերի քառակուսիների արտադրայլը:

#include <iostream>
#include <math.h>
using namespace std;
void main()
{
int x[10], p, i, n;

do {
cin>>n;
}
while(1>n||n>10);
for(i=0; i<n; i++)
{
cout<<"x["<<i<<"]=";
cin>>x[i];
}
p=1;
for(i=2; i<n; i+=2)

p=p*pow(double (x(i)),2);

cout<<"p="<<p<<endl;
}

Մի հատ ակնհայտ սխալ որ առաջին հայացքից տեսա էսա p=p*pow(double (x(i)),2); x(i) չէ x[i] :)

Ruzanna Stepanyan
04.04.2012, 13:05
x(i) x[i] կասեք էս երկուսի տարբերությունը որն է

ashot_1987
04.04.2012, 13:10
x(i) x[i] կասեք էս երկուսի տարբերությունը որն է
Տարբերությունը ահավոր շատ ա: Զանգվածի ինդեքսը գրվում ա [ ] նշանների մեջ, կոմպիլյատորը մենակ տենց ա հասկանում

Varzor
04.04.2012, 13:10
Ես հիմա ճակատագրական քայլ կանեմ ու կփորձեմ հակառակվել Varzor-ին:))
Ես գրեթե համոզված եմ, որ xor-ը ավելի արագ կաշխատի, քան այդ գրված տարբերակը.
Հ.Գ."Գրեթե" բառս հետո կարա փրկի :))
Հեչ էլ ճակատագրական չի :) Ըստ էության ճիշտ եք տեսականորեն, մասսամբ էլ տեխնիկապես: Մոդուլ երկուսով գումարման գործողությունը պրոցեսորից ավելի քիչ տակտեր է պահանջում` ստանդարտով, մանավանդ երբ այդ թվերն ամբողջ թվեր են: AMR, MIPS (RISK) ճարտարապետության պրոցեսորներում միանշանակ այդպես է, բայց այ x86-ում...
Պրոցեսորն ունի առանձին բլոկներ, որոնք կոնկրետ գործողություններն ավելի արագ են կատարում` ավելի օպտիմիզացված: Ու կախված արժեքների տիպից գործողության "արժեքը" տակտերով հաշված կարող է տարբեր լինել:
Ըստ էթության մոդուլ երկուսով գումարումը իրենից ներկայացնում է N քանակով տրամաբանական համեմատության օպերացիաներ` քանի հատ բիտ կա, այդքան էլ համեմատություն է անում:
Սակայն էլ. տեխնիկական տեսանկյունից դա այսպես չէ.
Կան երկու ռեգիստրներ, որոնցում պահված են գումարվող ամբողջ թվերը: "գումարիր ըստ մոդուլ երկուսի" հրամանի դեպքում այդ ռեգիստրների թվերը փոխանցվում են ըստ մոդուլ երկուսի գումարող մոդուլին, որն էլ իր հերթին մի տակտով ստանում է արդյունքը և այն գրանցում ելքային ռեգիստրում:
Սովորական գումարման ժամանակ "գումարիր" գործողության ժամանակ երկու ռեիստրների թվերը փոխանցվում են գումարիչին, որն էլ մեկ տակտում ստանում է արդյունքը (սակայն այդ նպատակով օգտագործում է լրացուցիչ ռեգիստր) և տեղափոխում է ելքային ռեգիստր:
Սակայն երբ թվերը սահող ստորակետով են, ապա գործողություններին ընթացքն այլ է: Շատ չմանրանամ ու ասեմ, որ մոդուլ երկուսովը ավելի արագ է կատարվում:
Քանոր որ այստեղ հնչած խնդիրը ամբողջ թվերին էր վերաբերվում, ապա ինձ թույլ տվեցի պնդել, որ սովորական գումարումն ամենահարմար ու արագ լուծումն է, քանի որ այն ավելի հասկանալի է ;)

Varzor
04.04.2012, 13:15
Այժմ հարցը` ինչի համար երկրորդ տարբերակը ավելի արագ չի աշխատում (ոնց որ մի բան էլ ավելի դանդաղ):
Շատ պարզ` ամեն տողի էլէմենտի համար ուկազատելներ ես պահում: համ տակտ ես կորցնում, համ էլ ուկազատելից (ցուցիչ) արժեք վերցնելն ավելի դանդաղ գործողություն է, քան ուղղակի դիմելը: Երբ որ զանգվածը հայտարարում ես, էդ ժամանակ հիշողությունում, ծրագրի ստեկում հասցեների տիրույթ է ռեզերվացվում այդ զանգվածի համար: Զանգվածի անունն էլ հենց հղումն է այդ տիրույթին: Իսկ դու մի հատ էլ առանձին ցուցիչ ես հայտարարում էդ հղման վրա ` համ հիշողություն է գնում, համ էլ տակտ: Պիտի սկզբից կարդա ցուցիչի տվյալը, որը հենց հղման արժեքն է ու նոր ըստ այդ տվյալի անցնի մատրիցին:

Բայց իմաստը որնա, որ տենց ես գրում?

MSGM
04.04.2012, 16:35
Ես հիմա ճակատագրական քայլ կանեմ ու կփորձեմ հակառակվել Varzor-ին:))
Ես գրեթե համոզված եմ, որ xor-ը ավելի արագ կաշխատի, քան այդ գրված տարբերակը.

Հ.Գ."Գրեթե" բառս հետո կարա փրկի :))

Մեջբերում Վիկիպեդիայից (http://en.wikipedia.org/wiki/XOR_swap_algorithm).


Most modern compilers can optimize away the temporary variable in the naive swap, in which case the naive swap uses the same amount of memory and the same number of registers as the XOR swap and is at least as fast, and often faster. The XOR swap is also much less readable and completely opaque to anyone unfamiliar with the technique.
On modern CPU architectures, the XOR technique is considerably slower than using a temporary variable to do swapping. One reason is that modern CPUs strive to execute instructions in parallel via instruction pipelines. In the XOR technique, the inputs to each operation depend on the results of the previous operation, so they must be executed in strictly sequential order. If efficiency is of tremendous concern, it is advised to test the speeds of both the XOR technique and temporary variable swapping on the target architecture.
Այսինքն ավելի լավ ա "լրացուցիչ փոփոխականով" գրել: Համ գրողի համար ա հասկանալի, համ էլ կոմպիլյատորի:

soultaker
05.04.2012, 02:02
Շատ պարզ` ամեն տողի էլէմենտի համար ուկազատելներ ես պահում: համ տակտ ես կորցնում, համ էլ ուկազատելից (ցուցիչ) արժեք վերցնելն ավելի դանդաղ գործողություն է, քան ուղղակի դիմելը: Երբ որ զանգվածը հայտարարում ես, էդ ժամանակ հիշողությունում, ծրագրի ստեկում հասցեների տիրույթ է ռեզերվացվում այդ զանգվածի համար: Զանգվածի անունն էլ հենց հղումն է այդ տիրույթին: Իսկ դու մի հատ էլ առանձին ցուցիչ ես հայտարարում էդ հղման վրա ` համ հիշողություն է գնում, համ էլ տակտ: Պիտի սկզբից կարդա ցուցիչի տվյալը, որը հենց հղման արժեքն է ու նոր ըստ այդ տվյալի անցնի մատրիցին:

Բայց իմաստը որնա, որ տենց ես գրում?


Տենց գրելուս իմաստը արագացնելնա, բայց դանդաղումա ավելի: m[i][j] դիմումը պետք է կատարի մեկ բազմապատկում և մեկ գումարում, իսկ p[i] դիմումը` մեկ գումարում: Այսինքն քանի որ պիտի դիտարկեմ ամբողջ i տողը, ու այդ տողի ամեն էլեմենտը գտնելու համար տրված i ու j ինդեքսներից պիտի ամեն դիմումի ժամանակ ծրագիրը պիտի հաշվի *(m + i * 10000 + j), դրա համար ես պահում եմ ցուցիչ այդ տողի վրա, որ տողի ամեն էլեմենտին դիմելուց միանգամից տողի ցուցիչից ստանա, ամեն անգամ բազմապատկում չանի: Իսկ ցուցիչի վրա կորցրած տակտը հազարավոր անգամ ավելի փոքր պիտի լինի քան թե բազմապատկման վրա կորցրած տակտը (մեկ անգամ ցուցիչ հայտարարել ու արժեք տալու շնորհիվ խնայվում է 10000 բազմապատկման տակտ): Ամեն դեպքում ամեն ինչ այդքան պարզ չի, որովհետև գոյություն ունի պրոցեսորի կեշ հիշողություն, ու կարող է դա էլ դեր խաղալ, այդ ամենին գումարած կոմպիլյատորի օպտիմիզացիան, այնպես որ բավականին դժվար է ենթադրություններ անել:

Varzor
05.04.2012, 13:31
Տենց գրելուս իմաստը արագացնելնա, բայց դանդաղումա ավելի: m[i][j] դիմումը պետք է կատարի մեկ բազմապատկում և մեկ գումարում, իսկ p[i] դիմումը` մեկ գումարում: Այսինքն քանի որ պիտի դիտարկեմ ամբողջ i տողը, ու այդ տողի ամեն էլեմենտը գտնելու համար տրված i ու j ինդեքսներից պիտի ամեն դիմումի ժամանակ ծրագիրը պիտի հաշվի *(m + i * 10000 + j), դրա համար ես պահում եմ ցուցիչ այդ տողի վրա, որ տողի ամեն էլեմենտին դիմելուց միանգամից տողի ցուցիչից ստանա, ամեն անգամ բազմապատկում չանի: Իսկ ցուցիչի վրա կորցրած տակտը հազարավոր անգամ ավելի փոքր պիտի լինի քան թե բազմապատկման վրա կորցրած տակտը (մեկ անգամ ցուցիչ հայտարարել ու արժեք տալու շնորհիվ խնայվում է 10000 բազմապատկման տակտ): Ամեն դեպքում ամեն ինչ այդքան պարզ չի, որովհետև գոյություն ունի պրոցեսորի կեշ հիշողություն, ու կարող է դա էլ դեր խաղալ, այդ ամենին գումարած կոմպիլյատորի օպտիմիզացիան, այնպես որ բավականին դժվար է ենթադրություններ անել:

Չգիտեմ, պարզ գրել եմ, թե ինչի է դանդաղ անում: Արագ չի անի: Էդ քեզ թվում է, որ բազմապատսկամն գործողոթւյան համար այդքան շատ տակտեր է օգտագործում: Իրականում ներակռւցված մոդուլը այդ գործողությունն ավելի արագ է կատարում` մեկ տակտի մեջ շատ գործողություններ` 8 գործողություն:
Համամաիտ եմ` պրոցեսորի քեշը կապ ունի, ու նայած թե ինչ կառուցվածքի պրոցեսոր էու ինչ մակարդակի քեշեր ունի:
Բայց հիմա նայենք սենց.
i-երորդ տողի հասցեն ցուցիչում գրանցելու համար միևնույն է էդ քո ասած բազմաբատկումը պիտի անի: m[i]-ն հաշվելու համար պիտի բազմապատկի չէ? դու էլ գրել էս *p = m[i]: Որքան հիշում եմ ստեղ m-ը հենց ինքը ցուցիչ է հանդիսանում մատրիցի զրոյական ինդեքսով էլէմենտին: m[i]-ն արդեն ցուցիչ է հանդիսանում i-երորդ տողի զրոյական ինդեքսով էլէմենտին ու ըստ էության m[i]-ն հասցե է: Այսինքն տեսականորեն` *p = *(m + i * 10000) և p-ն ստանում է i-երորդ տողի զրոյական ինդեքսով էլէմենտի հասցեն: Երբ գրում ենք p[j] նշանակում է p-ի արժեքին գումարում ենք j հատ p-ի տիպին համապատասխան բայտ ու դիմում համապատասխան հասեցին` p[j]= p+j*sixeof(int): Ստացվում է որ j=1, 10000 ցիկլի ընթացքում p[j] հասեցները ստանալու համար 10000 անգամ j-ով կատարում ենք բազմապատկում p-ի տիպի բայտերի քանակով` 4-ով (sizeof(int) = 4): Այնպես որ բազմապատկումների քանակը հեչ էլ չի նվազում:
Իսկ հաշվի առնելով նաև այն, որ p-երի պահպանման համար լրացուցիչ հասցեներ են զբաղեցվում, դա ավելի է դանդաղացնում աշխատանքը:

Եթե ինչ-որ բան սխալ եմ հիշում, արի այլ ձևով խելք-խելքի տանք :)
Միգուցե &` հղումով գրելը առավելություն տա?

soultaker
05.04.2012, 14:47
Չգիտեմ, պարզ գրել եմ, թե ինչի է դանդաղ անում: Արագ չի անի: Էդ քեզ թվում է, որ բազմապատսկամն գործողոթւյան համար այդքան շատ տակտեր է օգտագործում: Իրականում ներակռւցված մոդուլը այդ գործողությունն ավելի արագ է կատարում` մեկ տակտի մեջ շատ գործողություններ` 8 գործողություն:
Համամաիտ եմ` պրոցեսորի քեշը կապ ունի, ու նայած թե ինչ կառուցվածքի պրոցեսոր էու ինչ մակարդակի քեշեր ունի:
Բայց հիմա նայենք սենց.
i-երորդ տողի հասցեն ցուցիչում գրանցելու համար միևնույն է էդ քո ասած բազմաբատկումը պիտի անի: m[i]-ն հաշվելու համար պիտի բազմապատկի չէ? դու էլ գրել էս *p = m[i]: Որքան հիշում եմ ստեղ m-ը հենց ինքը ցուցիչ է հանդիսանում մատրիցի զրոյական ինդեքսով էլէմենտին: m[i]-ն արդեն ցուցիչ է հանդիսանում i-երորդ տողի զրոյական ինդեքսով էլէմենտին ու ըստ էության m[i]-ն հասցե է: Այսինքն տեսականորեն` *p = *(m + i * 10000) և p-ն ստանում է i-երորդ տողի զրոյական ինդեքսով էլէմենտի հասցեն: Երբ գրում ենք p[j] նշանակում է p-ի արժեքին գումարում ենք j հատ p-ի տիպին համապատասխան բայտ ու դիմում համապատասխան հասեցին` p[j]= p+j*sixeof(int): Ստացվում է որ j=1, 10000 ցիկլի ընթացքում p[j] հասեցները ստանալու համար 10000 անգամ j-ով կատարում ենք բազմապատկում p-ի տիպի բայտերի քանակով` 4-ով (sizeof(int) = 4): Այնպես որ բազմապատկումների քանակը հեչ էլ չի նվազում:
Իսկ հաշվի առնելով նաև այն, որ p-երի պահպանման համար լրացուցիչ հասցեներ են զբաղեցվում, դա ավելի է դանդաղացնում աշխատանքը:

Եթե ինչ-որ բան սխալ եմ հիշում, արի այլ ձևով խելք-խելքի տանք :)
Միգուցե &` հղումով գրելը առավելություն տա?

Ուշադրություն դարձրու թե բազմապատկում քանի անգամ կկատարվի առաջին դեպքում, ու քանի անգամ` երկրորդ դեպքում:

Varzor
05.04.2012, 15:30
Ուշադրություն դարձրու թե բազմապատկում քանի անգամ կկատարվի առաջին դեպքում, ու քանի անգամ` երկրորդ դեպքում:
Նույն քանակով է կատարվում:
Սենց հաշվենք` m[i][j] պարագայում կատարվում է i*j անգամ: *p=m[i] դեպքում կատարվում է i անգամ, իսկ քանի որ յուրաքանչյուր p[i] համար, ինչպես ցույց տվեցի, կատարվում է j անգամ, ուստի նույնպես կատարվում է i*j անգամ ;)
Բայց քանի որ յուրաքանչյուր տողի համար կատարվում է *p=m[i], ապա i անգամ կատարվում է հղման փոփոխականի վերագրում և հասցեի տրամադրում: Հենց սա էլ դանդաղացնում է:
Համ էլ արդեն գտել եմ` Դեյտելից գտա զանգվածների հետ ցուցիչներով ու հղումներով աշխատելու համեմատականությունը:
Ծրագրի համարժեքության տեսանկյունից այսպես է.
Օրինակ` ունենք
int b[5];
int x;
int *bPrt = b;
Ուզում ենք դիմել 3-րդ էլէմենտին
Իրար համարժեք են
1. x = b[2]
2. x = *(b+2)
3. x = bPtr[2]
4. x = *(bPtr+2)

Բայց այս գործողութոյւններից ավելի արագ են կատարվում առաջին 2-ը, քանի որ չկա միջանկյալ *bPtr = b գործողութունը, որն էլ իր հերթին է տակտեր վերցնում պրոցեսորից:

աղբյուր` Դեյտել C++ էջ 346-347

soultaker
05.04.2012, 15:44
Նույն քանակով է կատարվում:
Սենց հաշվենք` m[i][j] պարագայում կատարվում է i*j անգամ: *p=m[i] դեպքում կատարվում է i անգամ, իսկ քանի որ յուրաքանչյուր p[i] համար, ինչպես ցույց տվեցի, կատարվում է j անգամ, ուստի նույնպես կատարվում է i*j անգամ ;)
Բայց քանի որ յուրաքանչյուր տողի համար կատարվում է *p=m[i], ապա i անգամ կատարվում է հղման փոփոխականի վերագրում և հասցեի տրամադրում: Հենց սա էլ դանդաղացնում է:
Համ էլ արդեն գտել եմ` Դեյտելից գտա զանգվածների հետ ցուցիչներով ու հղումներով աշխատելու համեմատականությունը:
Ծրագրի համարժեքության տեսանկյունից այսպես է.
Օրինակ` ունենք
int b[5];
int x;
int *bPrt = b;
Ուզում ենք դիմել 3-րդ էլէմենտին
Իրար համարժեք են
1. x = b[2]
2. x = *(b+2)
3. x = bPtr[2]
4. x = *(bPtr+2)

Բայց այս գործողութոյւններից ավելի արագ են կատարվում առաջին 2-ը, քանի որ չկա միջանկյալ *bPtr = b գործողութունը, որն էլ իր հերթին է տակտեր վերցնում պրոցեսորից:

աղբյուր` Դեյտել C++ էջ 346-347

Եթե p[j]= p+j*sixeof(int) նկատի ունես որպես բազմապատկում, ապա ես դա չեմ համարում սովորական բազմապատկում, որովհետև sizeof(int) սովորաբար 4 է, հետևաբար կոմպիլյատորը պարտավոր է օպտիմիզացնել (j * 4) գործողությունը և այն վերածել (j << 2) շատ ավելի արագ բիտային գործողության: Իսկ ցուցիչը չի կարող նկատելի չափով դանդաղեցնել, որովհետև դրսի ցիկլի մեջ է գտնվում, իսկ ամբողջ ժամանակը ծախսվում է ներսի ցիկլի վրա, այնպես որ ցուցիչի վրա ծախսված ժամանակը կկազմի ամբողջ ժամանակի մոտավորապես 0.01% մասը: Ամեն դեպքում ես հարցը տալիս նկատի ունեի ավելի սարքային պատճառներ` պրոցեսորի աշխատելու մեխանիզմը և այլն, որովհետև զուտ տրամաբանական տեսանկյունից նայելիս 2րդ տարբերակում միայն արագանալու միտում եմ տեսնում:

Varzor
05.04.2012, 16:08
Եթե p[j]= p+j*sixeof(int) նկատի ունես որպես բազմապատկում, ապա ես դա չեմ համարում սովորական բազմապատկում, որովհետև sizeof(int) սովորաբար 4 է, հետևաբար կոմպիլյատորը պարտավոր է օպտիմիզացնել (j * 4) գործողությունը և այն վերածել (j << 2) շատ ավելի արագ բիտային գործողության: Իսկ ցուցիչը չի կարող նկատելի չափով դանդաղեցնել, որովհետև դրսի ցիկլի մեջ է գտնվում, իսկ ամբողջ ժամանակը ծախսվում է ներսի ցիկլի վրա, այնպես որ ցուցիչի վրա ծախսված ժամանակը կկազմի ամբողջ ժամանակի մոտավորապես 0.01% մասը: Ամեն դեպքում ես հարցը տալիս նկատի ունեի ավելի սարքային պատճառներ` պրոցեսորի աշխատելու մեխանիզմը և այլն, որովհետև զուտ տրամաբանական տեսանկյունից նայելիս 2րդ տարբերակում միայն արագանալու միտում եմ տեսնում:
Լիովին քեզ հասկանում եմ: Բայց կոմպիլյատորի օպտիմիզացիան կապ չունի ստեղ, քանի որ վերածվում է ASSEMBLER-ի, որի պարագայում էլ ցանկացած գործողոթւոյւն բիտային է, այդ թվում և բազմապատկումը: Ստանդարտ երկուական բազմապատկումը գումար-տեղաշարջ հաջորդականությամբ է կատարվում` բիտերի մակարդակով: Այո, ճիշտ ես պիտի որ ցուցիչի հետ կատարվող օպերացիաները շատ մեծ ժամանակ չխլեն, բայց այդ օպերացիաները խիստ կախված են կողմնակի հանգամանքներից: Հիշողությունում տեղի պիտի հատկացվի ցուցիչին: Ըստ ծրագրի դու դա անում ես ամեն անգամ դրան հայտարարելով ցիլկի առաջին մակարդակում: Նախ այդ հիշողուոյւնը պիտի լինի, որ տրամադրվի, երկրորդն էլ կախված է, ինչպես նշեցիր պրողեցորի կառուցվածքից` ինչպես է կառավարվում հիշողության հասցեների տիրույթը:
Բացի այդ, շատ ճիշտ էիր նկատել, պրոցեսորի քեշը մեծ նշանակություն ունի:Եթե ամբողջ զանգվածը և ցուցչներն էլ հետը տեղավորվում են պրոցեսորի քեշում, ապա գործողությունները մի քանի անգամ ավելի արագ կկատարվեն:
Բայց արի հաշվենք` m-ը 10000x10000 հատ int է` այսինքն` 100մլն հատ int, 4 բիտով կանի 400մլն բիտ` մոտ 48ՄԲ, իսկ այդպիսի քեշ չունեն ներկայիս պրոցեսորները: Սա կոպիտ հաշվարկ էր, հաշվի պետք առնել նաև այն, որ ներկայիս պրոցեսորում հասցեավորումը 64բիտով է գնում, նույնիսկ 32 բիտանոց OՀ դեպքում: Այստեղ չմ հաշվում ծրագրի մնացած փոփոխություններն ու գործողությունների հրամաննեը (դե սրանք տուֆտա փոքր թվեր են, դրա համար):
Ուստի այսպես, թե այնպես խնդիր լուծման ընթացքում օգտագործվելու է համակարգային հիշողությունը` RAM-ը: Ու կախված պրոցեսորի վրա ընթացող այլ պրոցեսներից, հիշողության փեյջինգի մեխանիզմից, հիշողության կառուցվածքից և լիքը այլ բաներից էդ խնդրի լուծումը կարող է տարբեր ժամանակներ խլել: Սակայն 10000 անգամ ցուցիչի հայտարարումն ու արժեքի գրանցումը արդեն իսկ պիտի իր ազդեցությունը տա:

Քո մոտ ինչքան ա դանդաղում? Մոտավորապես ինչքան ա հարաբերակցությունը ցուցիչով ու առանց դրա? Խրոնոմետրաժ արել ես?

soultaker
05.04.2012, 22:23
Լիովին քեզ հասկանում եմ: Բայց կոմպիլյատորի օպտիմիզացիան կապ չունի ստեղ, քանի որ վերածվում է ASSEMBLER-ի, որի պարագայում էլ ցանկացած գործողոթւոյւն բիտային է, այդ թվում և բազմապատկումը: Ստանդարտ երկուական բազմապատկումը գումար-տեղաշարջ հաջորդականությամբ է կատարվում` բիտերի մակարդակով: Այո, ճիշտ ես պիտի որ ցուցիչի հետ կատարվող օպերացիաները շատ մեծ ժամանակ չխլեն, բայց այդ օպերացիաները խիստ կախված են կողմնակի հանգամանքներից: Հիշողությունում տեղի պիտի հատկացվի ցուցիչին: Ըստ ծրագրի դու դա անում ես ամեն անգամ դրան հայտարարելով ցիլկի առաջին մակարդակում: Նախ այդ հիշողուոյւնը պիտի լինի, որ տրամադրվի, երկրորդն էլ կախված է, ինչպես նշեցիր պրողեցորի կառուցվածքից` ինչպես է կառավարվում հիշողության հասցեների տիրույթը:
Բացի այդ, շատ ճիշտ էիր նկատել, պրոցեսորի քեշը մեծ նշանակություն ունի:Եթե ամբողջ զանգվածը և ցուցչներն էլ հետը տեղավորվում են պրոցեսորի քեշում, ապա գործողությունները մի քանի անգամ ավելի արագ կկատարվեն:
Բայց արի հաշվենք` m-ը 10000x10000 հատ int է` այսինքն` 100մլն հատ int, 4 բիտով կանի 400մլն բիտ` մոտ 48ՄԲ, իսկ այդպիսի քեշ չունեն ներկայիս պրոցեսորները: Սա կոպիտ հաշվարկ էր, հաշվի պետք առնել նաև այն, որ ներկայիս պրոցեսորում հասցեավորումը 64բիտով է գնում, նույնիսկ 32 բիտանոց OՀ դեպքում: Այստեղ չմ հաշվում ծրագրի մնացած փոփոխություններն ու գործողությունների հրամաննեը (դե սրանք տուֆտա փոքր թվեր են, դրա համար):
Ուստի այսպես, թե այնպես խնդիր լուծման ընթացքում օգտագործվելու է համակարգային հիշողությունը` RAM-ը: Ու կախված պրոցեսորի վրա ընթացող այլ պրոցեսներից, հիշողության փեյջինգի մեխանիզմից, հիշողության կառուցվածքից և լիքը այլ բաներից էդ խնդրի լուծումը կարող է տարբեր ժամանակներ խլել: Սակայն 10000 անգամ ցուցիչի հայտարարումն ու արժեքի գրանցումը արդեն իսկ պիտի իր ազդեցությունը տա:

Քո մոտ ինչքան ա դանդաղում? Մոտավորապես ինչքան ա հարաբերակցությունը ցուցիչով ու առանց դրա? Խրոնոմետրաժ արել ես?

Դե ես փորձել եմ այն դեպքում երբ որ ցուցիչը մի անգամ է հայտարարվում վերևում, այնպես որ հիշողություն վերցնել/ջնջելու խնդիրը դուրս է գալիս, բայց դրանից ժամանակային առումով ոչինչ չի փոխվում: Եթե ասեմբլերի մակարդակով նայենք` ցիկլի մեջ փոփոխական(այս դեպքում` ցուցիչը) հայտարարելու դեպքում ինչքան գիտեմ ուղղակի ստեկի մեջ է գցում, ջնջելուց` հանում, որը ուղղակի ստեկի վերջը պահող ռեգիստրի գումարում/հանում է: Ինչ վերաբերվում է ժամանակի փոփոխությանը` կարելի է ասել երկու դեպքում էլ աշխատում է նույն կերպ, երկրորդ դեպքում առաջինից ավելի արագ չի աշխատում, իսկ թե ավելի դանդաղ է թե չէ` հաստատ չեմ կարող ասել, իդեալական պայմաններում չի չափվել, բայց եթե տարբերություն կա, ուրեմն շատ չնչին է, շատ ավելի փոքր սպասելի դրական փոփոխության համեմատ: Երկու թվերի բազմապատկումը ծանր գործողություն է տրամաբանական առումով, որովհետև երկու 32 բիտանոց թվեր բազմապատկելիս կարելի է ասել, որ կատարվում է մոտ 32 * 32 = 1024 բիտերի զույգերի գործողություն: Այդ ամենը պիտի որ կատարվի մի քանի տակտով ընդամենը, կախված համակարգչի արխիտեկտուրայից, բայց ամեն դեպքում բազմապատկումը պիտի ավելի ծանր լինի, քան գումարման/հանման/բիտային գործողությունները (բիտային գործողություն ասելով նկատի ունեմ C++ի & | ^ << >> ~ գործողությունները): Ընդհանրապես եթե հարցը գնում է օպտիմիզացիայի մասին, ապա սկզբում սովորաբար արագացնում են ամենադանդաղ մասը (bottleneck), որը տվյալ դեպքում ներսի ցիկլի միջի գրածն է, որը ըստ տրամաբանության ավելի քիչ գործողություններ է պարունակում (այսինքն երկրորդ դեպքում i * 10000 արժեքը արդեն պահված է հասցեի փոփոխականի մեջ և օգտագործվում է ամեն անգամ նորից հաշվելու փոխարեն): Նման այլ դեպքեր հանդիպել են, երբ սպասված արագացումը տեղի ունենալու փոխարեն նույնիսկ ավելի դանդաղել է, ուղղակի այս պահին այդ մի դեպքն եմ հիշում: Հիմնականում դրա բացատրությունը հակված եմ փնտրելու կոմպիլյատորի օպտիմիզացիաների մեջ, որոնք անում են բավականին անսպասելի բաներ (օրինակ` ցիկլով հաշվել 1 .. 2 000 000 000 թվերի գումարը, որոշ կոմպիլյատորներ միացրած օպտիմիզացիայի դեպքում գեներացնում են այնպիսի ծրագիր, որը արդյունքը տպում է ակնթարթորեն, 0.1 վայրկյանից շուտ, մինչդեռ առանց օպտիմիզացիայի` 1 վայրկյանից ավել):

Varzor
06.04.2012, 11:08
Եթե ասեմբլերի մակարդակով նայենք` ցիկլի մեջ փոփոխական(այս դեպքում` ցուցիչը) հայտարարելու դեպքում ինչքան գիտեմ ուղղակի ստեկի մեջ է գցում, ջնջելուց` հանում, որը ուղղակի ստեկի վերջը պահող ռեգիստրի գումարում/հանում է:
Այո, ստեկում է պահում, բայց այդ ստեկը կարող է լինել ոչ թե պրոցեսորի քեշում, այդ գաղափարը կոչվում է "ծրագրի ստեկ"` կարող է գտնվել նաև RAM-ում: Բացի դրանից կոմպիլյատերից էլ է կախված, ՕՀ-ից էլ, թե տվյալ ծրագրին որքան ստեկ կհատկացնի: Օրինակ` 32բիտանոց ծրագրերին ՎԻնդավոզը երբեք 2ԳԲ-ից ավել RAM չի հատկացնում, նույնիսկ եթե ՕՀ-ն 64 բիտանոց է ու RAM-ն էլ 1TB: Միայն հատուկ մեծ ստեկով (կամ ընդլայնվող ստեկով) ծրագրերին է տալիս 2ԳԲ-ից ավել հիշողություն:
Բայց դե արի Դեյտելի ու Ստրաուստրուպի պես ավտարիտետնի տղերքին հավատանք ու համարենք, որ ցուցիչով, թե առանց դրա` նույն բանն է ու իրար համարժեք: Համենայն դեպս ինձ հասկանալի է, թե ինչու է այդպես:

Երկու թվերի բազմապատկումը ծանր գործողություն է տրամաբանական առումով, որովհետև երկու 32 բիտանոց թվեր բազմապատկելիս կարելի է ասել, որ կատարվում է մոտ 32 * 32 = 1024 բիտերի զույգերի գործողություն: Այդ ամենը պիտի որ կատարվի մի քանի տակտով ընդամենը, կախված համակարգչի արխիտեկտուրայից, բայց ամեն դեպքում բազմապատկումը պիտի ավելի ծանր լինի, քան գումարման/հանման/բիտային գործողությունները (բիտային գործողություն ասելով նկատի ունեմ C++ի & | ^ << >> ~ գործողությունները):
Դե երկուական հանրահաշվի տեսանկյունից ճիշտ ես, բայց էլ. տեխնիկական տեսանկյունից` 2 հատ 32 բիտանոց թվերիգումարումն իրենցի ներկայացնում է 32 գումարում, 32 տեղաշարժ` 64 գործողություն: Հաշվի առնոլեվ ներկայիս պրոցեսորների կառուցվածքը` 8 տակտ: Իսկ քո ասած բիտայի գործողությունները տեսականորեն են արագ: Կախված նրանից, թե կոմպիլյատորը դրանք ինչպես կօպտիմիզացնի ու տրանսլյատորն ինչպես կթարգմանի, կարող են ստացվել տարբեր արդյունքներ: Բայց էլի եմ ասում: Ամբողջ թվերի տեսանկյունից, նույնիսկ առավելագույնս օպտիմիզացված` x86-ի վրա տարբերություն չկա: Ընդհանրապես ամբողջ թվերի հետ աշխատելը շատ հեշտ ու արագ է դարձել պրոցեսորների համար, դրա համար էլ պրոցեսորի արտադրողականությունը չափում են FLOPS-ով` սահող ստորակետով թվերի հետ կատարվող օպերացիաներով:

Հիմնականում դրա բացատրությունը հակված եմ փնտրելու կոմպիլյատորի օպտիմիզացիաների մեջ, որոնք անում են բավականին անսպասելի բաներ (օրինակ` ցիկլով հաշվել 1 .. 2 000 000 000 թվերի գումարը, որոշ կոմպիլյատորներ միացրած օպտիմիզացիայի դեպքում գեներացնում են այնպիսի ծրագիր, որը արդյունքը տպում է ակնթարթորեն, 0.1 վայրկյանից շուտ, մինչդեռ առանց օպտիմիզացիայի` 1 վայրկյանից ավել):
Հաստատ համամիտ եմ այն մտքի հետ, որ կոմպիլյատորից շատ բան է կախված: օրինակ Borland-ի կոմպիլյատորնեը միշտ էլ աչքի են ընկել օպտիմալ աշխատանով և համարվել են RAPID: Հենց դրա համար էլ Delphi-ի ինժեներին տարան, որ C#-ի մոնցեպցիաները մշակի:
Դրա հետ կապված մի դեպք հիշեցի: 2000-ականների սկզբին ինտերնետով մի մարդ վաճառում էր Word97-ը, որը Disassembler էր արել, օպտիմիզացրել ու 3 անգամ ավելի արագ էր դրաձրել :))

Ruzanna Stepanyan
06.04.2012, 11:43
խնդրում եմ մի հատ նայեք, թե ինչն եմ սխալ արել, որ քանակը հաշվում է, իսկ արտադրյալը նույնիսկ ցույց չի տալիս էկրանին

Հաշվել և արտածել տրված n տարր պարունակող միաչափ այն տարրերի քանակը և արտադրյալը , որոնք պատկանում են տրված [a;b] միջակայքին

#include <iostream>
using namespace std;
void main()
{
int x[10], p,i,n,a,b, qanak;
cout<<"a=";
cin>>a;
cout<<"b=";
cin>>b;
do
{cin>>n;}
while(1>n||n>10);
for(i=0; i<n; i++)
{
cout<<"x["<<i<<"]=";
cin>>x[i];
}
p=1;
qanak=0;

for(i=1; i<n; i++)
if((x[i]>=a)&&(x[i]<=b))
{
p=p*x[i];
qanak++;
}
else
cout<<"p="<<p<<endl;
cout<<"qanak="<<qanak<<endl;

}

Varzor
06.04.2012, 12:31
խնդրում եմ մի հատ նայեք, թե ինչն եմ սխալ արել, որ քանակը հաշվում է, իսկ արտադրյալը նույնիսկ ցույց չի տալիս էկրանին

Հաշվել և արտածել տրված n տարր պարունակող միաչափ այն տարրերի քանակը և արտադրյալը , որոնք պատկանում են տրված [a;b] միջակայքին

#include <iostream>
using namespace std;
void main()
{
int x[10], p,i,n,a,b, qanak;
cout<<"a=";
cin>>a;
cout<<"b=";
cin>>b;
do
{cin>>n;}
while(1>n||n>10);
for(i=0; i<n; i++)
{
cout<<"x["<<i<<"]=";
cin>>x[i];
}
p=1;
qanak=0;

for(i=1; i<n; i++)
if((x[i]>=a)&&(x[i]<=b))
{
p=p*x[i];
qanak++;
}
else
cout<<"p="<<p<<endl;
cout<<"qanak="<<qanak<<endl;
}
Ընդգծածս հատվածում սխալ կա`else-ն պետք չի: Հակառակ պայմանի գործողություն քո խնդրում չկա:

Ruzanna Stepanyan
06.04.2012, 12:36
Ընդգծածս հատվածում սխալ կա`else-ն պետք չի: Հակառակ պայմանի գործողություն քո խնդրում չկա:

Մերսի շատ պատասխանի համար :)
ես էդպես էլ էի փորձել, բայց էդ դեպքում արտադրյալը ճիշտ ա հաշվում, իսկ քանակը միշտ գրում ա , որ հավասար ա 1-ի: Մի հատ կնայեք ինչն ա սխալ

Varzor
06.04.2012, 12:42
Մերսի շատ պատասխանի համար :)
ես էդպես էլ էի փորձել, բայց էդ դեպքում արտադրյալը ճիշտ ա հաշվում, իսկ քանակը միշտ գրում ա , որ հավասար ա 1-ի: Մի հատ կնայեք ինչն ա սխալ
Մի բան էլ ասեմ.
1. Զանգվածի էլեմենտների հաշվարկի ցիկլում գրի i=0
Քանակի պահը պիտի ճիշտ հաշվի, եթե ընենց ես գրում ոնց որ ստեղ ես դրել: Ուղղակի փոխի i=0 ու else-ն հանի:
Մեկ էլ ներմուծելուց պիտի ուշադիր լինես, որ a-ն միշտ փոքր լինի b-ից:

Ruzanna Stepanyan
06.04.2012, 12:44
Մի բան էլ ասեմ.
1. Զանգվածի էլեմենտների հաշվարկի ցիկլում գրի i=0
Քանակի պահը պիտի ճիշտ հաշվի, եթե ընենց ես գրում ոնց որ ստեղ ես դրել: Ուղղակի փոխի i=0 ու else-ն հանի:

իսկ ինչի ենք գրում 1, նախորդ խնդիրնեերում գրել էի 0, բայց ֆրումում ինձ խորհուրդ տվեցին գրել 1:

Varzor
06.04.2012, 12:47
իսկ ինչի ենք գրում 1, նախորդ խնդիրնեերում գրել էի 0, բայց ֆրումում ինձ խորհուրդ տվեցին գրել 1:
:))
Նախորդ խնդիրներում min/max խնդիր էիր լուծում, որի ժամանակ որպես սկզբնական min/max տարր ընդունում էիր զանգվածի առաջին տարրը: Ու հետագա համեմատություններրի ժամանակ իմաստ չուներ, որ ինքն իրա հետ համեմատեիր, դրա համար էլ ցիկլը սկսում էիր 2-րդ տարրից` ինդեքսը 1-ից:
Իսկ այս խնդրում զանգվածի բոլոր տարրերն էլ կարող են պատկանել [a;b]միջակայքին ուստի պիտի սկսես 0-ինդեքսից` 1-ին տարրից:

Ruzanna Stepanyan
06.04.2012, 12:49
:))
Նախորդ խնդիրներում min/max խնդիր էիր լուծում, որի ժամանակ որպես սկզբնական min/max տարր ընդունում էիր զանգվածի առաջին տարրը: Ու հետագա համեմատություններրի ժամանակ իմաստ չուներ, որ ինքն իրա հետ համեմատեիր, դրա համար էլ ցիկլը սկսում էիր 2-րդ տարրից` ինդեքսը 1-ից:
Իսկ այս խնդրում զանգվածի բոլոր տարրերն էլ կարող են պատկանել [a;b]միջակայքին ուստի պիտի սկսես 0-ինդեքսից` 1-ին տարրից:

:hands հաաա ճիշտ ա

բայց մեկա քանակը չի հաշվում, միշտ հավասար ա 1-ի

Varzor
06.04.2012, 12:58
:hands հաաա ճիշտ ա

բայց մեկա քանակը չի հաշվում, միշտ հավասար ա 1-ի

մի հատ վերջի հատվածը սենց գրի.
for(i=0; i<n; i++)
{
if((x[i]>=a)&&(x[i]<=b))
{
p=p*x[i];
qanak+=1;
}
}
cout<<"p="<<p<<endl;
cout<<"qanak="<<qanak<<endl;

Ruzanna Stepanyan
06.04.2012, 13:06
ստավեց, մերսի շատ :)

կբացատրեք ինչի էդպես գրելուց ստավեց, իսկ նախորդ տարբերակը չէր ստացվում, խնդրում եմ

Varzor
06.04.2012, 13:20
ստավեց, մերսի շատ :)

կբացատրեք ինչի էդպես գրելուց ստավեց, իսկ նախորդ տարբերակը չէր ստացվում, խնդրում եմ
{} փակագծերը For-ի համար պակասում էին:

armen9494
07.04.2012, 12:18
խնդրում եմ մի հատ նայեք, թե ինչն եմ սխալ արել, որ քանակը հաշվում է, իսկ արտադրյալը նույնիսկ ցույց չի տալիս էկրանին

Հաշվել և արտածել տրված n տարր պարունակող միաչափ այն տարրերի քանակը և արտադրյալը , որոնք պատկանում են տրված [a;b] միջակայքին

#include <iostream>
using namespace std;
void main()
{
int x[10], p,i,n,a,b, qanak;
cout<<"a=";
cin>>a;
cout<<"b=";
cin>>b;
do
{cin>>n;}
while(1>n||n>10);
for(i=0; i<n; i++)
{
cout<<"x["<<i<<"]=";
cin>>x[i];
}
p=1;
qanak=0;

for(i=1; i<n; i++)
if((x[i]>=a)&&(x[i]<=b))
{
p=p*x[i];
qanak++;
}
else
cout<<"p="<<p<<endl;
cout<<"qanak="<<qanak<<endl;

}

Դե քանի որ արդեն խնդիրը լուծեցիք, մի բան ասեմ, որ կարծում եմ պետք կգա: Խոսքը a-ի և b-ի ներմուծման մասին է:
Ուրեմն քանի որ չկարողանաք b-ն a-ից փոքր ներմուծել, կարող եք դրա վրա էլ սահմանափակում դնել, նշածս մասի փոխարեն գրելով այսպես՝
do
cout<<"a=";
cin>>a;
cout<<"b=";
cin>>b;
while ( b>=a);

Hermsbir
07.04.2012, 17:28
Ո՞վ կարող է լուծել հետևյալ խնդիրը:

Տրված է 1 հատ 15 տարեկան կենդանի: Այդ կենդանին այնպիսին է,որ ապրում է 35 տարի, իսկ սեռահասունացումը տեղի է ունենում 15 տարեկանում: Սկսած 15 տարեկանից կենդանին ամեն տարի ունենում է 1 ձագ : Բազմանալու համար կենդանուն զույգ չի պահանջվում: Գրել ծրագիր, որը պահանջի տարիների քանակ և դուրս բերի, թե այդքան տարի հետո քանի կենդանի կլինի: Ծրագիրը պետք է աշխատի մեծ թվերի համար (~800-1000 տարի):

MSGM
07.04.2012, 18:31
Սպոյլերի մեջ եմ գրում, որ ուրիշներն էլ մտածեն:

Նշանակենք F(i,j)-ով i-րդ տարվա վերջում j տարեկան կենդանիների քանակը: Ունենք` F(0,15)=1: Հիմա, ենթադրելով, որ կենդանիները ծնվում և մահանում են տարվա սկզբում,
ծնվածների քանակը (որոնք i-րդ տարվա վերջում դարձած են լինում 1 տարեկան).
F(i,1) = F(i-1,15) + F(i-1,16) + ... + F(i-1,34) (անցած տարվա վերջում 35 տարեկան եղածները մահացել են ու սերունդ այս տարի չեն տալիս)
մյուսների քանակները.
F(i,j) = F(i-1,j-1) (j = 2..35)
N-րդ տարվա վերջում էլ
Պատասխան = F(N,1) + F(N,2) + ... + F(N,35)


#include <iostream>

using namespace std;

int F[2000][40], N;

int main()
{
cin >> N;
F[0][15] = 1;
for (int i = 1; i <= N; i++)
{
int s = 0;
for (int j = 15; j < 35; j++)
s += F[i - 1][j];
F[i][1] = s;
for (int j = 2; j <= 35; j++)
F[i][j] = F[i - 1][j - 1];
}
int ans = 0;
for (int i = 1; i <= 35; i++)
ans += F[N][i];
cout << ans << endl;
return 0;
}

Hermsbir
07.04.2012, 19:29
Խնդրի լուծման ալգորիթմը ճիշտ է, բայց դե, 500 տարի հետո քանի՞ հատ կլինի :)

Lusina
07.04.2012, 22:33
Ժող,մի հատ սենց հարց.Ի՞նչ ա նշանակում հղում հղման վրա. c++ -ի ստանդարտն ասում ա, որ չի թույլատրվում, ու տրամաբանական էլ ա, որովհետև հղումը օբյեկտի վրա պետք ա լինի, իսկ ինքը հղումը օբյեկտ չի,ուղղակի լրացուցիչ անուն ա օբյեկտի համար.Հիմա հարցն էն ա, թե որ դեպքերում ա հնարավոր ունենալ T&& տիպ, որովհետև boosti-i remove_reference-ի մեջ էդ տարբերակն էլ ա հաշվի առած.

soultaker
08.04.2012, 16:44
Ո՞վ կարող է լուծել հետևյալ խնդիրը:

Տրված է 1 հատ 15 տարեկան կենդանի: Այդ կենդանին այնպիսին է,որ ապրում է 35 տարի, իսկ սեռահասունացումը տեղի է ունենում 15 տարեկանում: Սկսած 15 տարեկանից կենդանին ամեն տարի ունենում է 1 ձագ : Բազմանալու համար կենդանուն զույգ չի պահանջվում: Գրել ծրագիր, որը պահանջի տարիների քանակ և դուրս բերի, թե այդքան տարի հետո քանի կենդանի կլինի: Ծրագիրը պետք է աշխատի մեծ թվերի համար (~800-1000 տարի):

Կառաջարկեմ նույն խնդիրը, երբ տարիների քանակը կարող է լինել մինչև 1 000 000 000, իսկ պատասխանի փոխարեն պետք է տպել քանակը 1 000 003 -ի վրա բաժանվելուց ստացվող մնացորդը (մեծ թվերից խուսափելու համար):

Hermsbir
08.04.2012, 17:01
Խնդրի բարդություններից մեկը հենց մեծ թվերն են -_-

soultaker
08.04.2012, 18:29
Խնդրի բարդություններից մեկը հենց մեծ թվերն են -_-

Դե նշված 800-1000 քանակի դեպքում ուղղակի պիտի որ կենդանիների քանակը մեծ ստացվի, որը պահելու համար պետք կգա գրել երկար թվաբանություն ձեռքով, իսկ իմ առաջարկած պայմանների դեպքում բարդությունը կայանում է նրանում, որ հնարավոր չի լինում խնդիրը լուծել տրիվիալ տարբերակով` այսինքն ուղղակի հերթով դիտարկելով քանակները ըստ ամեն տարվա:

Hermsbir
08.04.2012, 18:57
Ձեր առաջարկածը ուղղակի մաշտաբավորման խնդիր չէ?

soultaker
08.04.2012, 23:24
Ձեր առաջարկածը ուղղակի մաշտաբավորման խնդիր չէ?

Մասշտաբավորում ասելով կոնկրետ ի՞նչը նկատի ունես: Ճիշտն ասած ծանոթ չեմ այդ տերմինին, իմ առաջարկած սահմանափակումների նպատակը խնդրի ալգորիթմական բարդությունը մեծացնելն էր, որ տրիվիալ ալգորիթմը դանդաղ աշխատի ու ցանկալի լինի ուրիշ արագ լուծում:

Hermsbir
09.04.2012, 00:57
Դիցուք ծնվողների քանակը 1 000 004 է : Այդ թվից ուղղակի կհանենք 1 000 003, որովհետեև այդքան հատը վերջնական պատասխանում ներդրում չեն ունենա: Էսքան բան չի?

MSGM
09.04.2012, 09:05
Կառաջարկեմ նույն խնդիրը, երբ տարիների քանակը կարող է լինել մինչև 1 000 000 000, իսկ պատասխանի փոխարեն պետք է տպել քանակը 1 000 003 -ի վրա բաժանվելուց ստացվող մնացորդը (մեծ թվերից խուսափելու համար):

Երկար հանրահաշիվ գրելու հավես չկա, բայց դրա վրա մտածել կարելի ա: Իմ գրած լուծումը փաստորեն O(N) ա, նույնիսկ եթե n-րդ անդամի համար ինչ-որ բանաձև գտնեմ, չգիտեմ O(N)-ից ավելի լավ ժամանակում կլինի հաշվել, թե չէ:think : Իսկ եթե պետք ա, որ մի 10 րոպեի մեջ տեղավորվի, գրածս լուծումը կարելի ա հեշտությամբ ձևափոխել, որ հիշողության օգտագործումը O(1) լինի:


#include <iostream>
#include <time.h>

using namespace std;

#define MOD 1000000

double getTime()
{
return (double(clock())/CLK_TCK);
}

int F[2][40], N;

int main()
{
cin >> N;
double startTime = getTime();
F[0][15] = 1;
for (int i = 1, x = 1; i <= N; i++, x ^= 1)
{
int s = 0;
for (int j = 15; j < 35; j++)
s = (s + F[x ^ 1][j]) % MOD;
F[x][1] = s;
for (int j = 2; j <= 35; j++)
F[x][j] = F[x ^ 1][j - 1];
}
int ans = 0;
for (int i = 1; i <= 35; i++)
ans = (ans + F[x ^ 1][i]) % MOD;
cout << ans << endl;
cout << "Time: " << getTime() - startTime << endl;
return 0;
}

Իմ մոտ 450 վրկ. էր 1,000,000,000-ի համար:

soultaker
09.04.2012, 12:41
Երկար հանրահաշիվ գրելու հավես չկա, բայց դրա վրա մտածել կարելի ա: Իմ գրած լուծումը փաստորեն O(N) ա, նույնիսկ եթե n-րդ անդամի համար ինչ-որ բանաձև գտնեմ, չգիտեմ O(N)-ից ավելի լավ ժամանակում կլինի հաշվել, թե չէ:think : Իսկ եթե պետք ա, որ մի 10 րոպեի մեջ տեղավորվի, գրածս լուծումը կարելի ա հեշտությամբ ձևափոխել, որ հիշողության օգտագործումը O(1) լինի:


#include <iostream>
#include <time.h>

using namespace std;

#define MOD 1000000

double getTime()
{
return (double(clock())/CLK_TCK);
}

int F[2][40], N;

int main()
{
cin >> N;
double startTime = getTime();
F[0][15] = 1;
for (int i = 1, x = 1; i <= N; i++, x ^= 1)
{
int s = 0;
for (int j = 15; j < 35; j++)
s = (s + F[x ^ 1][j]) % MOD;
F[x][1] = s;
for (int j = 2; j <= 35; j++)
F[x][j] = F[x ^ 1][j - 1];
}
int ans = 0;
for (int i = 1; i <= 35; i++)
ans = (ans + F[x ^ 1][i]) % MOD;
cout << ans << endl;
cout << "Time: " << getTime() - startTime << endl;
return 0;
}

Իմ մոտ 450 վրկ. էր 1,000,000,000-ի համար:

Դե ամբողջ հարցը դրանում է, ես մեծ դեպքի համար առաջարկում եմ O(logN) լուծում O(N)-ի փոխարեն (N-ը տարիներ քանակն է):

MSGM
09.04.2012, 15:30
Եթե վերաձևակերպեմ լուծումը, F(i)-ով կարելի ա նշանակել ծնվածների թիվը i-րդ տարում: Վերջնական պատասխանը կլինի 1-ից 35 տարի առաջ ծնվածների գումարը: Իսկ i-րդ տարում ծնվածների գումարը կլինի 15-34 տարի առաջ ծնվածների գումարը` մոտավորապես.
F(i) = F(i - 34) + F(i - 33) + ... + F(i - 15)
Հիմա եթե ունենք առաջին 35 տարիների հաշվարկը (F(1)-ից F(35)), դրանից կարող ենք F(2)-ից F(36)-ը ստանալ {F(1);F(2);...;F(35)} վեկտորը մատրիցով բազմապատկելով.


0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
.
.
.
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0

կամ ինչ-որ սենց բան :D
Դե էս մատրիցն էլ O(logN)-ում կարանք N աստիճան բարձրացնենք:

soultaker
09.04.2012, 22:19
Եթե վերաձևակերպեմ լուծումը, F(i)-ով կարելի ա նշանակել ծնվածների թիվը i-րդ տարում: Վերջնական պատասխանը կլինի 1-ից 35 տարի առաջ ծնվածների գումարը: Իսկ i-րդ տարում ծնվածների գումարը կլինի 15-34 տարի առաջ ծնվածների գումարը` մոտավորապես.
F(i) = F(i - 34) + F(i - 33) + ... + F(i - 15)
Հիմա եթե ունենք առաջին 35 տարիների հաշվարկը (F(1)-ից F(35)), դրանից կարող ենք F(2)-ից F(36)-ը ստանալ {F(1);F(2);...;F(35)} վեկտորը մատրիցով բազմապատկելով.


0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
.
.
.
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0

կամ ինչ-որ սենց բան :D
Դե էս մատրիցն էլ O(logN)-ում կարանք N աստիճան բարձրացնենք:

Հենց դա էլ նկատի ունեի:

Varzor
10.04.2012, 11:06
Ժողովուրդ ինչի եք բարդացնում?
Բավարար է, որ պահեք մի հատ միաչափ զանգված, էլէմենտների քանակը նախապես չսահմանած` ցուցիչով, որտեղ ամեն էլէմենտի արժեքը կլինի տվյալ կենթադու տարիքը:
Հետո ըստ տարիների ցիկլով անցնում ենք էդ զանգվածի վրայով:
Եթե կենդանի սեռահասուն է (15<=k<=35), ապա զանգվ ածում մեկ տարր ավելացնում ենք ու իրա տարիքը դնում 1, քանակը մի հատով ավելացնում:
Եթե կենդանին 35 է, ուրեն տարիքը դնում ենք զրո` սատկել է ու քանակը մի հատ հանում:
Ցանկացած տարիների համար էլ աշխատում է` տրիվյալ լուծում է, բայց կարծում եմ կարելի է օպտիմիզացնել


#include <iostream>
using namespace std;
void main()
{
int tari, qanak, n, i, j;
int *k;
cout<<"tari=";
do
{cin>>tari;}
while(tari<=0);
k[0]=15;
qanak=1;
n=1;

for (i=0; i<tari; i++)
{
for (j=0; j<n; j++)
{
if (k[j]>0) //yete satkac che
{
if (k[j]<=35 && k[j]>=15) //yete der serahasun e
{
n=n+1;
k[n]=1;
qanak=qanak+1;
}
if (k[j]=35) // yete satkelu vra e :D
{
k[j]=0;
qanak=qanak-1;
}
k[j]=k[j]+1; //mek tarov mecacav
}
}
}
cout<<"qanak="<<qanak<<endl;
}
Ոնց լուծում ա?
Կհաշվի?

Հ.Գ.
Շատ մեծ թվերի պարագայում ճիշտ կլինի որոշ int-եր փոխարինել long-երով:
Baseic-ում նման խնդիրը շատ հեշտ լուծվում է Dictionary տիպի օբյեկտով` յուրաքանչյուր էլէմենտը կենդանի է: Ցիկլով ֆռում ես` հենց "վախտը հասավ" սատկացնում ես` էլեմենտը ջնում ես, իսկ ետե սեռահասուն է` էլէմէնտ ես ավելացնում:
C#-ում էդ Dictionary-ները օգտագործել եմ, բայց C++ում` ձևը չգիտեմ :oy

MSGM
10.04.2012, 11:38
Զանգվածի մեծությունը փաստորեն տվյալ տարվա դրությամբ երբևիցե ապրած կենդանիների քանակն ա, չէ? Բայց մի քանի 100 տարուց ապրող կենդանիների քանակը էնքան մեծ ա դառնում, որ 64 բիտանոց long long-ն էլ չի հերիքում քանակը պահելու համար: Այսինքն ուղղակի սիմուլյացիա ես անում ու պատասխանը շատ հեշտ ստացվում ա, բայց մի քիչ մեծ թվերի համար համ շատ երկար ա աշխատում, համ էլ էդքան հիշողություն չի գտնվի բոլորի տարիքները հիշելու համար:
Իմ վերջին լուծումը (կոդով), օրինակ, հիշողություն շատ քիչ ա օգտագործում ու օգտագործումն էլ N-ից կախված չի, բայց համեմատաբար դանդաղ ա աշխատում (N=1,000,000,000-ի համար մոտ 450 վրկ.): Իսկ էս ամենավերջին նկարագրածս լուծումը 0.5 վրկ.-ի մեջ կտեղավորվի նույնիսկ N=10^12-ի դեպքում:
Ի դեպ, էդ ցուցիչի հետ սխալ ես աշխատում: Ցուցիչը հայտարարելուց, իրա արժեքը ինչ-որ անկապ թիվ ա (հիշողության մեջ անկապ տեղ ա ցույց տալիս), հաշվի առնելով էլ, որ զանգվածի երկարությունը ուզում ես դինամիկ փոխել, լավ կլինի std::vector-ից օգտվես.
vector<int> vi;
vi.push_back(a);

Dictionary-ն էլ C++ ում std::map-ն ա`
map<string, int> m;
m["tandz"] = 121;
m["khndzor"] = 367;
cout << m["tandz"] + m["khndzor"] << endl;

Varzor
10.04.2012, 14:02
Զանգվածի մեծությունը փաստորեն տվյալ տարվա դրությամբ երբևիցե ապրած կենդանիների քանակն ա, չէ? Բայց մի քանի 100 տարուց ապրող կենդանիների քանակը էնքան մեծ ա դառնում, որ 64 բիտանոց long long-ն էլ չի հերիքում քանակը պահելու համար: Այսինքն ուղղակի սիմուլյացիա ես անում ու պատասխանը շատ հեշտ ստացվում ա, բայց մի քիչ մեծ թվերի համար համ շատ երկար ա աշխատում, համ էլ էդքան հիշողություն չի գտնվի բոլորի տարիքները հիշելու համար:
:))
Հա, ճիշտ ես հասկանում` գրածս ծրագրում n-ը (k զանգվածի տարրերի քանակը) երբևէ ապրած կենդանիների քանակն է:
Որպես օպտիմիզացիա կարելի է ընդամենը ամեն տարի 0-ական տարրերը զանգվածից հեռացնել` կմնան մենակ չսատկած կենդանիները:
Կարելի է երկրորդ զանգվածը պահել` ոչ սեռահասուն կենդանիների համար:
Եղբայր էդ ինչ թիվա, որ 64 բիտանոց long-ը չի հերիքի? 2-ի 63 Աստիճանից մեծ` 8x10246? էսի քո ասած 1012-ից հաստատ մեծ թիվ ա;)

Իմ վերջին լուծումը (կոդով), օրինակ, հիշողություն շատ քիչ ա օգտագործում ու օգտագործումն էլ N-ից կախված չի, բայց համեմատաբար դանդաղ ա աշխատում (N=1,000,000,000-ի համար մոտ 450 վրկ.): Իսկ էս ամենավերջին նկարագրածս լուծումը 0.5 վրկ.-ի մեջ կտեղավորվի նույնիսկ N=10^12-ի դեպքում:
Ի դեպ, էդ ցուցիչի հետ սխալ ես աշխատում: Ցուցիչը հայտարարելուց, իրա արժեքը ինչ-որ անկապ թիվ ա (հիշողության մեջ անկապ տեղ ա ցույց տալիս), հաշվի առնելով էլ, որ զանգվածի երկարությունը ուզում ես դինամիկ փոխել, լավ կլինի std::vector-ից օգտվես.
vector<int> vi;
vi.push_back(a);

Dictionary-ն էլ C++ ում std::map-ն ա`
map<string, int> m;
m["tandz"] = 121;
m["khndzor"] = 367;
cout << m["tandz"] + m["khndzor"] << endl;
Ցուցիչի հետ հեչ էլ սխալ չեմ աշխատում` դասական աշխատելու ձևն է: Ինչ կապ ունի, թե ինչ թիվա? փոփոխական է, կարևորը որ հետո արժեք տաս: Մի քանի գրառում առաջ (http://www.akumb.am/showthread.php/21029-C?p=2335283&viewfull=1#post2335283)Դեյտելի գրքից նույնիսկ մեջբերում եմ արել դրա հետ կապված ;)
Հեչ իմաստ չեմ տեսնում vector օբյեկտից օգտվելու մեջ` ցուցիչը լիովին բավարար է:
Dictionary-ն էլ հեչ էլ map-ը չի:
Dictionary-ն Microsoft Scripting Runtime գրադարանի օբյեկտ է` որ լեզուն հնարավորութուն ունի այդ գրադարանին դիմելու` կարող ես հայտարարել:
Կառուցվածքն էլ հետևյալն է.
D (key, value) ու value-ն կարող են լինել ցանկացած տիպի, նույնիսկ այլ օբյեկտ:
Չեմ կարծում, որ մատրիցաների բազմապատկումը մեծ թվերի պարագայում կարող է այդքան արագ լինել` 900 անգամ:
Ամեն դեպքում քո առաջարկած տարբերակը շատ հետաքրքիր ու ուսանելի տարբերակ է:
Ի դեպ 100 տարում կենդանիների քանակը ստացվում է 1703208 հատ` կենդանի, չսատկած: Ու հաշվում ա 73 վայրկյանում:
Էս էլ կոդը` VBA-ի համար, կարող ես Excel-ի կամ Word-ի մեջ աշխատացնել: Ընդ որում սա Dictionary-ով տարբերակը չի


Sub Test1()

Dim tari, qanak, n, i, j As Long
Dim k() As Variant
Dim StartTime As Date
Dim EndTime As Date
Dim delta As Date
Dim s As String

tari = 100
ReDim k(1) As Variant
k(0) = 15
qanak = 1
n = 1
StartTime = Now
For i = 1 To tari
For j = 0 To n - 1
If k(j) > 0 Then
If (k(j) >= 15 And k(j) <= 35) Then
n = n + 1
ReDim Preserve k(n) As Variant
k(n - 1) = 1
qanak = qanak + 1
ElseIf k(j) = 35 Then
k(j) = 0
qanak = qanak - 1
End If
k(j) = k(j) + 1
End If
Next j
Next i
EndTime = Now
delta = EndTime - StartTime
s = CStr(Hour(delta) * 3600 + Minute(delta) * 60 + Second(delta))
MsgBox (CStr(qanak) & " kendani <->" & s & " seconds")

End Sub

MSGM
10.04.2012, 14:59
Եղբայր էդ ինչ թիվա, որ 64 բիտանոց long-ը չի հերիքի? 2-ի 63 Աստիճանից մեծ` 8x10246? էսի քո ասած 1012-ից հաստատ մեծ թիվ ա:
N=360-ի համար, պատասխանը (այսինքն` 360-րդ տարում ապրողների քանակը) 8,508,275,536,357,516,150 ա: N=370-ի պատասխանը long long-ում տեղ չի անում: Էտքան հիշողություն էլ, բնականաբար, չկա: :))

Ցուցիչի հետ հեչ էլ սխալ չեմ աշխատում` դասական աշխատելու ձևն է: Ինչ կապ ունի, թե ինչ թիվա? փոփոխական է, կարևորը որ հետո արժեք տաս: Մի քանի գրառում առաջ Դեյտելի գրքից նույնիսկ մեջբերում եմ արել դրա հետ կապված
Հեչ իմաստ չեմ տեսնում vector օբյեկտից օգտվելու մեջ` ցուցիչը լիովին բավարար է:
Ո՞նց սխալ չես աշխատում, եթե իմ մոտ runtime error ա տալիս քո կոդը: Ասում եմ` քո ցուցիչ-փոփոխականին նույնիսկ արժեք չես տալիս, գոնե գրեիր.
int *k = new int[2000];
Բայց մեկ ա շատ շուտ ապրող կենդանիների քանակը 2000-ից անցնելու ա (ու հասնելու ա վերոհիշյալ long long-ում չտեղավորվող թվերի) ու էդ դեպքում k[j] արտահայտությունը, որտեղ j >= 2000 runtime error ա: Էդ դեպքում էլ պիտի նոր հիշողություն վերցնես ու հնից copy անես նորը.


int *t = k;
k = new int[4000];
memcpy(k, t, sizeof(int)*2000);
delete[] t;



Dictionary-ն էլ հեչ էլ map-ը չի:
Dictionary-ն Microsoft Scripting Runtime գրադարանի օբյեկտ է` որ լեզուն հնարավորութուն ունի այդ գրադարանին դիմելու` կարող ես հայտարարել:
Կառուցվածքն էլ հետևյալն է.
D (key, value) ու value-ն կարող են լինել ցանկացած տիպի, նույնիսկ այլ օբյեկտ:

Ես ի նկատի չունեի, որ std::map-ը Microsoft Scripting Runtime-ի Dictionary ա, այլ որ std::map-ը dictionary տեսակի data structure ա, էլի ունի map<key, value> տեսքը ցանկացած տիպի key-ի ու value-ի համար (պայմանով, որ key-ի վրա համեմատության օպերատոր կա սահմանած):


Չեմ կարծում, որ մատրիցաների բազմապատկումը մեծ թվերի պարագայում կարող է այդքան արագ լինել` 900 անգամ:

KxK չափի երկու մատրիցների բազմապատկումը տրիվիալ ալգորիթմով O(K^3) ժամանակային բարդություն ունի: Մեր խնդրում K-ն կոնստանտ ա (K=35), իսկ հենց "մատրիցի բազմապատկում" գործողությունների քանակը O(logN) ա (N=10^12-ի դեպքում մոտ 40): Այսինքն պետք ա լինում 40 անգամ (35^3)*ինչ-որ-ոչ-շատ-մեծ-կոնստանտ քանակի գործողություններ կատարել, որը հանգիստ կտեղավորվի 0.5 վրկ-ի մեջ: Իսկ եթե ի նկատի ունես կենդանիների քանակը նկարագրող թվերի մեծ լինելը, ապա soultaker-ի առաջարկած խնդրում պետք ա տալ (պատասխան MOD 1000003), ինչը նշանակում ա, որ բոլոր միջանկյալ բազմապատկումներից ու գումարումներից հետո կարելի ա MOD 1000003 անել ու չանհանգստանալ մեծ թվերի մասին:

Varzor
10.04.2012, 15:49
N=360-ի համար, պատասխանը (այսինքն` 360-րդ տարում ապրողների քանակը) 8,508,275,536,357,516,150 ա: N=370-ի պատասխանը long long-ում տեղ չի անում: Էտքան հիշողություն էլ, բնականաբար, չկա: :))
Հա, տենց մեծ թվերի պարագայում արդեն long-երը խիստ Short են դառնում :))
Բայց ստեղ մի ուրիշ հարց է գալիս` թե կուզ հիշողությունը հերիքի, էդ թիվը որպես ինչ փոփոխական պիտի հայտարարվի, որ մի հատ էլ հետո տպվի? :))
Օրինակ` հաջորդ փորձս` 110 տարվա համար 1020վրկ-ում հաշվեց 6,517,962 կենդանի


Ո՞նց սխալ չես աշխատում, եթե իմ մոտ runtime error ա տալիս քո կոդը: Ասում եմ` քո ցուցիչ-փոփոխականին նույնիսկ արժեք չես տալիս, գոնե գրեիր.
int *k = new int[2000];
Բայց մեկ ա շատ շուտ ապրող կենդանիների քանակը 2000-ից անցնելու ա (ու հասնելու ա վերոհիշյալ long long-ում չտեղավորվող թվերի) ու էդ դեպքում k[j] արտահայտությունը, որտեղ j >= 2000 runtime error ա: Էդ դեպքում էլ պիտի նոր հիշողություն վերցնես ու հնից copy անես նորը.
Ընգեր չգիտեմ դու որ միջավայրում ես գրում, բայց VS 6.0-ի տակ ոչ մի խնդիր էլ չունեմ` Console W32 ռեժիմով էլ աշխատում է :pardon

Ես ի նկատի չունեի, որ std::map-ը Microsoft Scripting Runtime-ի Dictionary ա, այլ որ std::map-ը dictionary տեսակի data structure ա, էլի ունի map<key, value> տեսքը ցանկացած տիպի key-ի ու value-ի համար (պայմանով, որ key-ի վրա համեմատության օպերատոր կա սահմանած):
Հաա, դե տենց էլ ասա :) Ուրիշ ձև էիր գրել ,ես էլ հասկացել էի, թե համարժեքության մասին ես գրել:

MSGM
10.04.2012, 18:18
Հա, տենց մեծ թվերի պարագայում արդեն long-երը խիստ Short են դառնում :))
Բայց ստեղ մի ուրիշ հարց է գալիս` թե կուզ հիշողությունը հերիքի, էդ թիվը որպես ինչ փոփոխական պիտի հայտարարվի, որ մի հատ էլ հետո տպվի? :))
Օրինակ` հաջորդ փորձս` 110 տարվա համար 1020վրկ-ում հաշվեց 6,517,962 կենդանի

Դե Hermsbir-ի ձևակերպած խնդրում պետք էր N=1000-ի համար պատասխան տալ, դրա համար պետք էր "երկար հանրահաշիվ" գրել (այսինքն` սահմանում ենք օբյեկտ, որը ունի թվանշանների կամայական երկարության զանգված, ու դրա վրա +,-,*,/ գործողությունները սահմանում ենք տարրական դպրոցի ձևերով, որոշ լեզուներում տենց պատրաստի օբյեկտ կա(Java, Python, ևն)): Իսկ soultaker-ի խնդրում, ինչպես ասացի, MOD 1000003-ով պատասխանը տալը ազատում ա մեծ թվերի հետ աշխատելու խնդրից: Թե չէ, N=1,000,000,000-ի պայմաններում նենց մեծ թվեր են ստացվում, որ էտ թվերով մի հատ բազմապատկման գործողությունն ա արդեն շատ երկար տևում:


Ընգեր չգիտեմ դու որ միջավայրում ես գրում, բայց VS 6.0-ի տակ ոչ մի խնդիր էլ չունեմ` Console W32 ռեժիմով էլ աշխատում է :pardon

Եթե debug ռեժիմ ա, կարող ա աշխատի, համ էլ էտ VS 6.0-ից ամեն ինչ սպասելի ա :D :

http://ideone.com/O9BoG
Հեսա, օնլայն բազմալեզու կոմպիլյատոր ա: N=100 եմ դրել, runtime error ա տալիս (ամենաներքևում): Դե համ էլ, իհարկե, էտ օգտագործումը անտրամաբանական ա ու պարզապես սխալ: Դու փաստորեն փորձում ես օգտագործել հիշողություն, որը նախօրոք չես ուզել ՕՀ-ից քո ծրագրի համար (օր. new օպերատորով կամ malloc ֆունկցիայով): Հլը հերիք չի, հենց քո ցուցիչին (որը հասցե ա` 4 կամ 8 բայթանով թիվ) ոչ մի արժեք չես տալիս, իսկ C++-ում ինիցիալիզացիա չարած լոկալ փոփոխականների արժեքը էտ պահին RAM-ի էտ դիրքում հայտնված ինչ-որ զիբիլ ա (դրան հակառակ` գլոբալ փոփոխականները, զանգվածները զրոյացվում են հայտարարելիս):

Varzor
10.04.2012, 19:44
Հեսա, օնլայն բազմալեզու կոմպիլյատոր ա: N=100 եմ դրել, runtime error ա տալիս (ամենաներքևում): Դե համ էլ, իհարկե, էտ օգտագործումը անտրամաբանական ա ու պարզապես սխալ: Դու փաստորեն փորձում ես օգտագործել հիշողություն, որը նախօրոք չես ուզել ՕՀ-ից քո ծրագրի համար (օր. new օպերատորով կամ malloc ֆունկցիայով): Հլը հերիք չի, հենց քո ցուցիչին (որը հասցե ա` 4 կամ 8 բայթանով թիվ) ոչ մի արժեք չես տալիս, իսկ C++-ում ինիցիալիզացիա չարած լոկալ փոփոխականների արժեքը էտ պահին RAM-ի էտ դիրքում հայտնված ինչ-որ զիբիլ ա (դրան հակառակ` գլոբալ փոփոխականները, զանգվածները զրոյացվում են հայտարարելիս):
Դե եթե Դեյտելն ու Ստրաուստրուպը սխալ են, ուերմն` սխալ ա ;)
Բնական է, որ սկզբից հայտարարագրված հիշողույթունն ավելի արագ է աշխատում (երեք մակարդակ կա` 1. պրոցի քեշի չափերից մեծ չի, 2. ծրագրի ստեկի չափերից մեծ չի, 3. RAM-ից մեծ չի ): Բայց դինամիկ հիշողության մասին լսած կլինես ;)
VS 6.0-ն լավ էլ երկար տարիներ ծառայել է ու որոշ հարեցրում շատ ավելի ռապիդ է, քան .NET-ը:
Բա ոնցա VBA-ի տաբերակում հստակ աշխատում?
Նույն կոդն ա, ուղղակի թարգմանած:

Հ.Գ.
Էդ հզումով նայում եմ` սխալ ա տալիս դեռ չաշխատած, նույնիսկ քո ասած դասական տարբերակով` ցուցիչը նախապես արժեք տալով http://ideone.com/NwXPG
Ոնց հասկացա gcc-ի տակ է անում:

MSGM
10.04.2012, 20:24
Դե եթե Դեյտելն ու Ստրաուստրուպը սխալ են, ուերմն` սխալ ա ;)
Բնական է, որ սկզբից հայտարարագրված հիշողույթունն ավելի արագ է աշխատում (երեք մակարդակ կա` 1. պրոցի քեշի չափերից մեծ չի, 2. ծրագրի ստեկի չափերից մեծ չի, 3. RAM-ից մեծ չի ): Բայց դինամիկ հիշողության մասին լսած կլինես ;)
VS 6.0-ն լավ էլ երկար տարիներ ծառայել է ու որոշ հարեցրում շատ ավելի ռապիդ է, քան .NET-ը:
Բա ոնցա VBA-ի տաբերակում հստակ աշխատում?
Նույն կոդն ա, ուղղակի թարգմանած:

Հ.Գ.
Էդ հզումով նայում եմ` սխալ ա տալիս դեռ չաշխատած, նույնիսկ քո ասած դասական տարբերակով` ցուցիչը նախապես արժեք տալով http://ideone.com/NwXPG
Ոնց հասկացա gcc-ի տակ է անում:
Ի՞նչ տարբերություն [] թե *, զանգված, ցուցիչ նույն բանն ա: Իմ ասածը էն ա, որ ՕՀ-ից քո ծրագրի համար չհատկացված հիշողությանը դիմել ա արգելվում ա (runtime error ա): Հիմա էս կոդում էլ արդեն ցուցիչին արժեք տալիս ես, բայց ցուցիչի արժեքով դիրքում (RAM-ի հասցեում) ընդամենը 1 էլեմենտ (4 բայթ) ա հատկացված ծրագրիդ, հետևաբար k[1]-ը runtime error ա: Իմ ասած ձևով, ՕՀ-ից պետք է վերցնես կոնկրետ քանակությամբ հիշողություն, նոր օգտագործես (այն, որ այդ քանակությունը կարող է որոշվել ծրագրիդ գործողության ընթացքում, այլ ոչ թե պետք է հայտնի լինի կոմպիլյացիայի պահին, հիմք է այդ հիշողությունը "դինամիկ" անվանելու համար):
http://ideone.com/rjMUj
Հեսա, իմ ասած ձևով նորմալ աշխատում ա (իհարկե եթե ապրող կենդանիների քանակը 2000-ից մեծ չի):
Ի դեպ, լուծմանդ մեջ սխալ կա վոնցոր: Ում սատկացնում ես, իրա տարիքը 0 ես դնում, բայց հետո 0 տարիք ունեցողներին էլ ես ամեն տարի մեծացնում ու վախտը գալիս ա` նորից սատկացնում :)): Օրինակ N=10-ի համար սխալ ա ստացվում (qanak=-18??):

soultaker
10.04.2012, 21:29
Ի դեպ, լուծմանդ մեջ սխալ կա վոնցոր: Ում սատկացնում ես, իրա տարիքը 0 ես դնում, բայց հետո 0 տարիք ունեցողներին էլ ես ամեն տարի մեծացնում ու վախտը գալիս ա` նորից սատկացնում :)): Օրինակ N=10-ի համար սխալ ա ստացվում (qanak=-18??):
Տենց առասպելական թռչուն կա` Ֆենիքս, մեռնելուց հետո վերակենդանանումա, փաստորեն Վարզորի լուծումը ֆենիքսների համարա :))

narek7007
10.04.2012, 22:23
c++ -ic մի հարց ունեմ :
ես ծրագիր եմ կազմում ,, որը բաղկացած է մի շարք տարբեր ֆորմատի ֆայլերից(*.txt , *.jpg ,..,..)
Երբ ես ծրագիրը ստեղծում եմ դրանք մի ֆայլում չեն պահպանվում:
Ինչպես կարող եմ այդ ֆայլերը պահպանել մի ՝ project.exe ֆայլում

Varzor
11.04.2012, 13:51
Հեսա, իմ ասած ձևով նորմալ աշխատում ա (իհարկե եթե ապրող կենդանիների քանակը 2000-ից մեծ չի):
Ի դեպ, լուծմանդ մեջ սխալ կա վոնցոր: Ում սատկացնում ես, իրա տարիքը 0 ես դնում, բայց հետո 0 տարիք ունեցողներին էլ ես ամեն տարի մեծացնում ու վախտը գալիս ա` նորից սատկացնում :)): Օրինակ N=10-ի համար սխալ ա ստացվում (qanak=-18??):
Դե կոմպիլյատորների տարբերություն ա` ուրիշ ոչինչ:
սխալ չկա` տարիքը մեծացնում եմ մենակ նրանց, ով որ արդեն սատկած չի` կոդը ուշադիր նայի ;) Պայման կա k[j]>0 էդ որ քանակը տալիս ա -18 ուղղակի նրա արդյունքն ա, որ հիշողությունում էդ պահին ինչ կա, էդա բերում` ծրագիրը իսկի չի էլ կատարում:

Varzor
11.04.2012, 13:52
Տենց առասպելական թռչուն կա` Ֆենիքս, մեռնելուց հետո վերակենդանանումա, փաստորեն Վարզորի լուծումը ֆենիքսների համարա :))
Մեռնելուց հետո չէ` վառվելուց հետո մոխիրներից վերակենդանանում ա :))
Կոդը սխալ ա նայել` մի պայման բացա թողել :)

Varzor
11.04.2012, 13:54
c++ -ic մի հարց ունեմ :
ես ծրագիր եմ կազմում ,, որը բաղկացած է մի շարք տարբեր ֆորմատի ֆայլերից(*.txt , *.jpg ,..,..)
Երբ ես ծրագիրը ստեղծում եմ դրանք մի ֆայլում չեն պահպանվում:
Ինչպես կարող եմ այդ ֆայլերը պահպանել մի ՝ project.exe ֆայլում
Էդ կոմպիլյացիայի ձևից ա` Project-ի տեսակից:
Որ վերսիայով ես սարքում?

MSGM
11.04.2012, 15:25
սխալ չկա` տարիքը մեծացնում եմ մենակ նրանց, ով որ արդեն սատկած չի` կոդը ուշադիր նայի ;) Պայման կա k[j]>0 էդ որ քանակը տալիս ա -18 ուղղակի նրա արդյունքն ա, որ հիշողությունում էդ պահին ինչ կա, էդա բերում` ծրագիրը իսկի չի էլ կատարում:
Հա ճիշտ ա, չէի նկատել, տեսա բացասական ա, ասի դրանից կլինի: Իրականում նույն տիպի սխալ եմ արել, ինչ որ քո մոտ ա: Պետք ա անպայման զրոյացնել զանգվածը.
http://ideone.com/f9kqs


Դե կոմպիլյատորների տարբերություն ա` ուրիշ ոչինչ:
Նայի դու ասում ես, որ Դեյտելի ու Ստրաուստրուպի ասածով ես անում, բայց էդ ոնց ա՞, որ gcc-ի նման կոմպիլյատորը (կամ իմ մոտի VS .NET-ի կոմպիլյատորը) runtime error-ով ծրագիր են սարքում:
http://codepad.org/PeJ1Dl1C
Էս կոմպիլյատորը սկի կոմպիլյացիա չի անում` ասում ա` k փոփոխականը ինիցիալիզացիա արած չի (էն վերևում նշած սխալս): Դա ո՞նց կբացատրես: Բացի դրանից դու կոդիդ մեջ դիմում ես հիշողության, որը քո ծրագրին հատկացված չի: Դա արգելվում ա, runtime error ա, հիշողության հետ աշխատելու պարզագույն սկզբունքի խախտում: Էլ ի՞նչ կոմպիլյատորների տարբերության մասին ա խոսքը:

Varzor
11.04.2012, 18:08
Նայի դու ասում ես, որ Դեյտելի ու Ստրաուստրուպի ասածով ես անում, բայց էդ ոնց ա՞, որ gcc-ի նման կոմպիլյատորը (կամ իմ մոտի VS .NET-ի կոմպիլյատորը) runtime error-ով ծրագիր են սարքում:
http://codepad.org/PeJ1Dl1C
Էս կոմպիլյատորը սկի կոմպիլյացիա չի անում` ասում ա` k փոփոխականը ինիցիալիզացիա արած չի (էն վերևում նշած սխալս): Դա ո՞նց կբացատրես: Բացի դրանից դու կոդիդ մեջ դիմում ես հիշողության, որը քո ծրագրին հատկացված չի: Դա արգելվում ա, runtime error ա, հիշողության հետ աշխատելու պարզագույն սկզբունքի խախտում: Էլ ի՞նչ կոմպիլյատորների տարբերության մասին ա խոսքը:
Եղբայր, սկզբից ես հայտարարում եմ int տիպի ցուցիչ փոփոխական: Դա նշանակում է, որ այդ k-ի համար հիշողությունում առանձին հասցե է հատկացվում, որի արժեքը դեռ հայտնի չէ` ինչպես հախասահմանված չափով զանգվածի բարագայում: Հետո ես այդ փոփոխականին վերագրում եմ արժեք` k-ին հատկացված բջջում գրանցում եմ x զանգվածի առաջին էլէմենտի հասցեն
Ես ոչ մի հիշողության էլ չեմ դիմում, ես դիմում եմ հասցեի` հաջորդ հասցեին, անկախ նրանից, թե դրանում ինչ է գրված ու փոխում եմ դրա արժեքը:
Ուղղակի որոշ կոմպիլյատորներ նախպապես են ստեկը սարքում ու չեն կարող դա անել դինամիկ, դրա համար էլ VS 6.0-ում սխալ չեմ ստանում:
Ոնց ա արգելվում, եթե դասագրքում գրված ա?

soultaker
11.04.2012, 20:29
Ես ոչ մի հիշողության էլ չեմ դիմում, ես դիմում եմ հասցեի` հաջորդ հասցեին, անկախ նրանից, թե դրանում ինչ է գրված ու փոխում եմ դրա արժեքը:

Իսկ ոչի՞նչ որ համակարգչի վրա ուրիշ ծրագրեր էլ են աշխատում ու կարողա տենց գնա իրանց բաժին հիշողությունը լրիվ վարի տա, եթե թույլատրված լիներ դա անել: Կամ ասենք էտ հասցեի արժեքը ի՞նչ թիվա իրանից ներկայացնում, կոնկրետ ինչի՞ վրայա ցույց տալիս: Բոլոր նորմալ օպերացիոն համակարգերում ամեն ծրագիր ունի իր բաժին հիշողությունը, ու դրանից դուրս հիշողության դիմելիս ՕՀ-ը ավտոմատ կերպով ծրագիրը ավարտում է Runtime Error-ով: Իսկ թե սկզբում հասցեն կոնկրետ որտեղ է ցույց տալիս, դա էլ ոչ ոք չի կարող ասել, որովհետև առանց սկզբնական արժեք տալու ուր ասես կարող է ցույց տալ:

narek7007
11.04.2012, 22:02
Էդ կոմպիլյացիայի ձևից ա` Project-ի տեսակից:
Որ վերսիայով ես սարքում?
Ես օգտագործում եմ Microsoft Visual Studio 2010

Varzor
12.04.2012, 18:53
Իսկ ոչի՞նչ որ համակարգչի վրա ուրիշ ծրագրեր էլ են աշխատում ու կարողա տենց գնա իրանց բաժին հիշողությունը լրիվ վարի տա, եթե թույլատրված լիներ դա անել: Կամ ասենք էտ հասցեի արժեքը ի՞նչ թիվա իրանից ներկայացնում, կոնկրետ ինչի՞ վրայա ցույց տալիս: Բոլոր նորմալ օպերացիոն համակարգերում ամեն ծրագիր ունի իր բաժին հիշողությունը, ու դրանից դուրս հիշողության դիմելիս ՕՀ-ը ավտոմատ կերպով ծրագիրը ավարտում է Runtime Error-ով: Իսկ թե սկզբում հասցեն կոնկրետ որտեղ է ցույց տալիս, դա էլ ոչ ոք չի կարող ասել, որովհետև առանց սկզբնական արժեք տալու ուր ասես կարող է ցույց տալ:
Բայց տալիս եմ չէ`
int x[]={0};
int *k=x;
Չնայած` համամիտ եմ քեզ հետ, երբ ծրագրին հատկացված ստեկից դուրս ես գալիս` Runtime Error-ը պատրաստ է: Սխալը հասկացա :ok Եթե գրեի
int x[10];
int *k=x;
ապա ոչ մի սխալ էլ չէր տա, քանի որ x-ի հայտարարման ժամանակ արդեն իսկ հասցեների տիրույթը ռեզերվացվում է, որն էլ չի ազդում արդեն k-ի վրա` նույն չափով էլ k-ին է հասնում:
Բայց փաստը մնում է փաստ` VS 6.0-ով աշխատում է :esim
Բա էդ պարագայում ինչի VBA-ն Runtime Error չի տալիս? Կարողա Redim-ը ուրիշ ձևա աշխատում:
Ի դեպ կհուշես C++-ում ոնց ենք միաչափ զանգվածի ինդեքսը մեծացնում/փոքրացնում? Redim-ի նման մի բան էլ ընդեղ կար ոնց որ: C-ից malloc-ն եմ հիշում, սա պիտի որ C++-ում էլ աշխատի: Բայց անկեղծ ասած` չեմ փորձել:
Ոնց են անում?

Varzor
12.04.2012, 18:55
Ես օգտագործում եմ Microsoft Visual Studio 2010
Դրան դեռ չեմ հասել` չեմ կարող օգտակար լինել:

Lusina
12.04.2012, 21:32
Ժող,մի հատ սենց հարց.Ի՞նչ ա նշանակում հղում հղման վրա. c++ -ի ստանդարտն ասում ա, որ չի թույլատրվում, ու տրամաբանական էլ ա, որովհետև հղումը օբյեկտի վրա պետք ա լինի, իսկ ինքը հղումը օբյեկտ չի,ուղղակի լրացուցիչ անուն ա օբյեկտի համար.Հիմա հարցն էն ա, թե որ դեպքերում ա հնարավոր ունենալ T&& տիպ, որովհետև boosti-i remove_reference-ի մեջ էդ տարբերակն էլ ա հաշվի առած.
Թարմացում՝ ոնց որ մի քանի &-ը մի հատ ա սարքում , օր.՝ int&& int& -ն ա, բայց մեկ ա ընդգծածս մասի հարցը մնում ա + թարմացած ինֆորմացիաս, խի՞ ա տենց արվում :))

soultaker
13.04.2012, 00:27
Ի դեպ կհուշես C++-ում ոնց ենք միաչափ զանգվածի ինդեքսը մեծացնում/փոքրացնում?

Զանգվածը C++ում իրենից ներկայացնում է ֆիքսված չափի տիրույթ, մեծացնել փոքրացնել հնարավոր է միայն անուղղակի կերպով` արդեն գոյություն ունեցող զանգվածը ջնջելով ու դրա փոխարեն նոր չափի զանգված վերցնելով (բնականաբար եթե զանգվածը դինամիկ կերպով է ստեղծվել, հակառակ դեպքում այն ջնջել հնարավոր չէ): Ընդհանրապես որոշ դեպքերում ավելի հարմար է վերցնել միանգամից մեծ չափի զանգված, այնպես որ ընթացքում մեծացնելու կարիք չլինի, իսկ եթե այնուամենայնիվ չափը ընթացքում փոխելը պետք է գալիս, ամենահարմար տարբերակը STL-ի վեկտորն է(vector): Այն իր մեջ պահում է դինամիկ զանգված, ու նոր էլեմենտներ ավելացնելիս հենց եղած տեղը վերջանում է, եղած հիշողությունը փոխարինում է նոր` ավելի մեծ հիշողությամբ, իսկ հինը ջնջում է(բնականաբար այդ ընթացքում հին հիշողության պարունակությունը տեղափոխում է նորի մեջ), և հակառակը` երբ որ օգտագործվող մասի չափը քչանում է վերցված հիշողության չափի ինչ-որ մասից, կատարվում է հակառակ գործողությունը, և վերցվում է նոր` ավելի փոքր չափի հիշողություն, իսկ հինը ջնջվում է: Եթե ավելի ցածր մակարդակի տեսանկյունից նայենք, vector-ը ինչքան գիտեմ օգտագործում է C++ի new/delete-ը, որոնք էլ իրենց հերթին հիմնված են C-ի malloc/free հրամանների վրա:

Varzor
13.04.2012, 12:07
Զանգվածը C++ում իրենից ներկայացնում է ֆիքսված չափի տիրույթ, մեծացնել փոքրացնել հնարավոր է միայն անուղղակի կերպով` արդեն գոյություն ունեցող զանգվածը ջնջելով ու դրա փոխարեն նոր չափի զանգված վերցնելով (բնականաբար եթե զանգվածը դինամիկ կերպով է ստեղծվել, հակառակ դեպքում այն ջնջել հնարավոր չէ): Ընդհանրապես որոշ դեպքերում ավելի հարմար է վերցնել միանգամից մեծ չափի զանգված, այնպես որ ընթացքում մեծացնելու կարիք չլինի, իսկ եթե այնուամենայնիվ չափը ընթացքում փոխելը պետք է գալիս, ամենահարմար տարբերակը STL-ի վեկտորն է(vector): Այն իր մեջ պահում է դինամիկ զանգված, ու նոր էլեմենտներ ավելացնելիս հենց եղած տեղը վերջանում է, եղած հիշողությունը փոխարինում է նոր` ավելի մեծ հիշողությամբ, իսկ հինը ջնջում է(բնականաբար այդ ընթացքում հին հիշողության պարունակությունը տեղափոխում է նորի մեջ), և հակառակը` երբ որ օգտագործվող մասի չափը քչանում է վերցված հիշողության չափի ինչ-որ մասից, կատարվում է հակառակ գործողությունը, և վերցվում է նոր` ավելի փոքր չափի հիշողություն, իսկ հինը ջնջվում է: Եթե ավելի ցածր մակարդակի տեսանկյունից նայենք, vector-ը ինչքան գիտեմ օգտագործում է C++ի new/delete-ը, որոնք էլ իրենց հերթին հիմնված են C-ի malloc/free հրամանների վրա:
Շնորհակալ եմ, էդ Vector օբյեկտը պրակտիկայում երբեք չեմ օգտագործել: Ոնց հասկանում եմ` դա class է:

Ruzanna Stepanyan
16.04.2012, 11:55
Խնդրում եմ, մի հատ նայեք ինչն եմ սխալ արել խնդրի մեջ, որ չի ստացվում.


Հաշվել և արտածել տրված n տարր պարունակող միաչափ զանգվածի այն տարրերի միջին թվաբանականը, որոնց ինդեքսը բազմապատիկ է տրված K ամբողջ թվին:

#include <iostream>
using namespace std;
void main()
{
int x[10], i,n,k, qanak;
double s;
cout<<"k=";
cin>>k;
do
{
cout<<"mutqagreq zangavtsi chapy"<<endl;
cin>>n;
}
while(1>n||n>10);
for(i=0; i<n; i++)
{
cout<<"x["<<i<<"]=";
cin>>x[i];
}
s=0;
qanak=0;
for(i=0; i<n; i++)
{
if(i%k==0)
{
s=s+x[i];
qanak++;
}
}
s=s/qanak;
cout<<"s="<<s<<endl;
}

Varzor
16.04.2012, 16:05
Իսկ ինչն ա սխալ անում?
Devision by zero ես ստանում?

Ruzanna Stepanyan
16.04.2012, 19:00
Իսկ ինչն ա սխալ անում?
Devision by zero ես ստանում?

Օրինակ գրում եմ
k=3
զանգվածի չափը վերցնում եմ 9
x[0]=1
x[1]=2
x[2]=2
x[3]=3
x[4]=4
x[5]=1
x[6]=5
x[7]=7
x[8]=8
ստացվում է
s=3

պիտի ստացվեր s=4

soultaker
16.04.2012, 19:30
Օրինակ գրում եմ
k=3
զանգվածի չափը վերցնում եմ 9
x[0]=1
x[1]=2
x[2]=2
x[3]=3
x[4]=4
x[5]=1
x[6]=5
x[7]=7
x[8]=8
ստացվում է
s=3

պիտի ստացվեր s=4

(x[0] + x[3] + x[6]) / 3 = (1 + 3 + 5) / 3 = 9 / 3 = 3

Lusina
16.04.2012, 21:52
Թարմացում՝ ոնց որ մի քանի &-ը մի հատ ա սարքում , օր.՝ int&& int& -ն ա, բայց մեկ ա ընդգծածս մասի հարցը մնում ա + թարմացած ինֆորմացիաս, խի՞ ա տենց արվում :))
Ավարտին հասցնեմ մենախոսությունս:))
Ուղղակի c++-ի նոր ստանդարտում մտցված ա rvalue reference գաղափարը, մանրամասն բնականաբար չեմ գրի, ուղղակի եթե ինչ-որ մեկի մոտ նույն հարցը ծագի, արդեն կիմանա, թե ինչ ա պետք փնտրել գուգլում.

Varzor
17.04.2012, 10:28
Օրինակ գրում եմ
k=3
զանգվածի չափը վերցնում եմ 9
x[0]=1
x[1]=2
x[2]=2
x[3]=3
x[4]=4
x[5]=1
x[6]=5
x[7]=7
x[8]=8
ստացվում է
s=3

պիտի ստացվեր s=4

Soultaker-ի գրածը հասկանալի՞ է:
x[0] էլէմենտի պարագայում 0%k=0 պայմանը տեղի է ունենում ու համ S-ն է աճում, համ qanak-ը:
Ու ցանկացած քանակի էլէմենտների պարագայում այդ պայամը միշտ աշխատելու է: Նույնիսկ եթե ընդամենը մեկ տարր ունենաս՝ x[0], ապա ցանկացած k-ի դեպքում միջին թվաբանականը կստանաս նույն x[0]-ի արժեքը:
Դրանից խուսափելու համար կա 2 տարբերակ.
1. կարող ես զանգվածի տարրերի ներմուծումն ու միջին թվաբանականի հաշվարկը սկսել x[1]-ից:
2. կարող ես լրացուցիչ պայման մտցնել` if(i>0) ու միայն այդ պայմանի կատարման դեպքում դիտարկել if(i%k=0) պայմանը:

Ruzanna Stepanyan
17.04.2012, 12:16
Soultaker-ի գրածը հասկանալի՞ է:
x[0] էլէմենտի պարագայում 0%k=0 պայմանը տեղի է ունենում ու համ S-ն է աճում, համ qanak-ը:
Ու ցանկացած քանակի էլէմենտների պարագայում այդ պայամը միշտ աշխատելու է: Նույնիսկ եթե ընդամենը մեկ տարր ունենաս՝ x[0], ապա ցանկացած k-ի դեպքում միջին թվաբանականը կստանաս նույն x[0]-ի արժեքը:
Դրանից խուսափելու համար կա 2 տարբերակ.
1. կարող ես զանգվածի տարրերի ներմուծումն ու միջին թվաբանականի հաշվարկը սկսել x[1]-ից:
2. կարող ես լրացուցիչ պայման մտցնել` if(i>0) ու միայն այդ պայմանի կատարման դեպքում դիտարկել if(i%k=0) պայմանը:


Շատ շնորհակալ եմ բացատրության համար:
Իսկ եթե հաշվարկը սկսեմ x[1]-ից , դա նշանակում է որ զանգվածի առաջին անդամը x[0]-ն է, թե x[1]-ը, որովհետև ընդունված է չէ առաջին անդամը համարել x[0]-ն

Varzor
17.04.2012, 17:49
Շատ շնորհակալ եմ բացատրության համար:
Իսկ եթե հաշվարկը սկսեմ x[1]-ից , դա նշանակում է որ զանգվածի առաջին անդամը x[0]-ն է, թե x[1]-ը, որովհետև ընդունված է չէ առաջին անդամը համարել x[0]-ն
Ոչ թե ընդունված է, այլ տենց էլ կա տեխնիկապես` զանգվածի ինդեքսների համարակալումը սկսվում է 0-ից:
Ավելի գագետ տարբերակ է ուղղակի i=0 դեպքը բացառելը` պայմանով ստուգելը:
Բանը նրանումն է, որ սովորաբար խնդիրներն ունիվերսալ են ու պարտադիր չի որ հենց C++-ով լուծվեն: Իսկ որոշ ծրագրավորման լեզուներում առաջին էլէմենտի ինդեքսը ոչ թե 0-ն է, այլ 1-ը:

Ի դեպ.
Որոշ դեպքերում հնարավոր է կամայականորեն որոշել առաջին էլեմենտի ինդեքսը: Այն կարող է լինել նաև բացասական:

armen9494
20.04.2012, 18:50
Ժողովուրդ ջան մոտս սենց մի "խնդիր" կա: Չնայած էս պահը էդքան շատ լուրջ կարևոր չի, ուղղակի որ ծրագիր գրելուց հանդիպեցի, ասեցի հարցնեմ, միգուցե ես մի բան էն չեմ անում:
C++-ում երկու հատ double տիպի մեծ երկչափ զանգված հայտարարելու դեպքում ծրագիրը չի աշխատում, գրում ա

Cpp1.exe has stopped working
Windows is checking for a solution to the problem...

Ի՞նչ ա C++-ում էդքան մեծ ծրագիր սարքել չի՞ կարելի:think

#include <iostream.h>

void main()
{
double y[100][1000], b[100][500];
cout<<"s=";
}

Փորձեք double-ի փոխարեն գրել int, float կամ long int՝ ճիշտ կաշխատի, բայց double-ի կամ long float-ի դեպքում "կախվում" ա:

Varzor
20.04.2012, 19:02
Ժողովուրդ ջան մոտս սենց մի "խնդիր" կա: Չնայած էս պահը էդքան շատ լուրջ կարևոր չի, ուղղակի որ ծրագիր գրելուց հանդիպեցի, ասեցի հարցնեմ, միգուցե ես մի բան էն չեմ անում:
C++-ում երկու հատ double տիպի մեծ երկչափ զանգված հայտարարելու դեպքում ծրագիրը չի աշխատում, գրում ա
Ի՞նչ ա C++-ում էդքան մեծ ծրագիր սարքել չի՞ կարելի:think
Փորձեք double-ի փոխարեն գրել int, float կամ long int՝ ճիշտ կաշխատի, բայց double-ի կամ long float-ի դեպքում "կախվում" ա:

Որ կոմպիլյատորով ես աշխատում?
Փորձել ես առանձին-առանձին նկարագրել?` double y[100][1000]; double b[100][500];
Բայց պիտի աշխատի` տենց սահմանափակում չկա: Մտածում ես հայտարարածդ փոփոխականի զբաղեցրած հիշողության չափերը գերազանցում են ծրագրի ստեկը?
կարող ես հաշվել` 150.000 հատ double տիպի արժեքների պահպանման համար անհրաժեշտ հիշողության ծավալը: Այն չի գերազանցում 1ՄԲ-ն: Ուստի հիշողության ծավալի խնդիր չի:
Ի դեպ, նույն քո կոդը գրում եմ MSGM-ի տված հղումով` նորմալ կատարվում է:
http://codepad.org/7qUslqjo

armen9494
20.04.2012, 19:36
Որ կոմպիլյատորով ես աշխատում?
Փորձել ես առանձին-առանձին նկարագրել?` double y[100][1000]; double b[100][500];
Բայց պիտի աշխատի` տենց սահմանափակում չկա: Մտածում ես հայտարարածդ փոփոխականի զբաղեցրած հիշողության չափերը գերազանցում են ծրագրի ստեկը?
կարող ես հաշվել` 150.000 հատ double տիպի արժեքների պահպանման համար անհրաժեշտ հիշողության ծավալը: Այն չի գերազանցում 1ՄԲ-ն: Ուստի հիշողության ծավալի խնդիր չի:
Ի դեպ, նույն քո կոդը գրում եմ MSGM-ի տված հղումով` նորմալ կատարվում է:
http://codepad.org/7qUslqjo
Microsoft Visual C++ 6.0
Փորձել եմ, նույնիսկ սենց եմ փորձել՝ double y[100][1000]; long float b[100][500];
Ծրագրի ստեկը մոտավորապես գիտեմ թե ինչ ա: Դե առաջին բանը որ մտքիս եկավ էն ա, որ C++-ը համակարգչիս մեջ չի կարողանում էդքան մեծ ծավալով տեղ վերցնի, բայց իրականում համակարգչիս մեջ էդ տեղը պիտի որ լինի, որովհետև էն լուրջ ծրագրերի համեմատ էս իմ գրածը ի՞նչ ա որ :esim
Վայ, էս ինչ նորություն ա, հեսա տեսնեմ էս ո՞նց են ուտում :nyam :))

armen9494
20.04.2012, 19:56
Ի դեպ, նույն քո կոդը գրում եմ MSGM-ի տված հղումով` նորմալ կատարվում է:
http://codepad.org/7qUslqjo

Բայց մի տեսակ տարօրինակ չի երևու՞մ աչքիդ էդ սարքած սայթը :unsure
Իսկ ես մտածում եմ, որ էս ծրագիրը էնքան որ ձև ա բռնում, որ մթոմ թե սարքել ա:
Ահա և ապացույցները, եթե իհարկե մի բան սխալ չեմ արել:
Հիմա նայի, ենթադրում եմ որ ինքը լավ ծրագիր ա ու արեց իմ ասածը՝ այսինքն վերցրեց տեղ էդ երկու երկչափ զանգվածների համար: Հետևաբար ես կարամ իրանց հետ գործ անեմ, այնպես չէ՞:
Դե հիմա նայի, ես գրում եմ ծրագիր, որը էն երկրորդ զանգվածի 100 հատ տարրի հետ "կզբաղվի" (դրանց արժեքներ կտա):
"Միջակայքը" գրում եմ 400,410
որից հետո տալիս եմ արտածի էդ միջակայքում գտնվող տարրերից ընդամենը մեկի արժեքը:

#include <iostream.h>

int main()
{
double y[100][1000], b[100][500];
int i,j;

for( i=400; i<410; i++)
for( j=400; j<410; j++)
b[i][j]=5*20;

cout<<b[405][405];


return 0;
}
Արդյունքում ծրագիրը լացում ա :)) Segmentation fault

Հիմա էդ նույն բանը անում եմ 0,10 միջակայքում:

#include <iostream.h>

int main()
{
double y[10][10], b[10][50];
int i,j;

for( i=0; i<10; i++)
for( j=0; j<10; j++)
b[i][j]=5*j;

cout<<b[5][5];


return 0;
}
Արդյունքում ուրախ ուրախ թռվռալով երգում ա :D 25

Տուտ չտո-տո նե տո...:think

Ruzanna Stepanyan
20.04.2012, 20:37
Կօգնեք ? տեսնեմ, ինչն եմ սխալ անում, որ չի ստացվում

Տրված n տարր պարունակող միաչափ զանգվածի դրական տարրերից նոր միաչափ զանգված ստանալ

#include <iostream>
using namespace std;
void main()
{
int x[10], i,n, y, k;
do
{
cout<<"mutqagreq zangavtsi chapy"<<endl;
cin>>n;
}
while(1>n||n>10);
for(i=0; i<n; i++)
{
cout<<"x["<<i<<"]=";
cin>>x[i];
}
k=0;
for(i=1; i<n; i++)
{
if(x[i]>0)
{
y[k]=x[i];
k++;
}
cout<<"nor zangvacy klini y[k]="<<y[k]<<endl;
}
}

armen9494
20.04.2012, 21:15
Կօգնեք ? տեսնեմ, ինչն եմ սխալ անում, որ չի ստացվում

Տրված n տարր պարունակող միաչափ զանգվածի դրական տարրերից նոր միաչափ զանգված ստանալ


#include <iostream>
using namespace std;
void main()
{
int x[10], i,n, y, k;
do
{
cout<<"mutqagreq zangavtsi chapy"<<endl;
cin>>n;
}
while(1>n||n>10);
for(i=0; i<n; i++)
{
cout<<"x["<<i<<"]=";
cin>>x[i];
}
k=0;
for(i=1; i<n; i++)
{
if(x[i]>0)
{
y[k]=x[i];
k++;
}
cout<<"nor zangvacy klini y[k]="<<y[k]<<endl;
}
}



Մոտավորապես ճիշտ ես արել, մի քանի թերություններով:
Առաջինը տող 5-ում ա: Դու ուզում ես նոր զանգվածը y-ի մեջ ստանաս, այնպես չէ՞: Բա ինչի՞ y-ը զանգված չի :esim
պիտի գրեիր սենց՝ y[10]
Կարծում եմ էս ուղղակի չես նկատել:
Էն տող 18-ի ցիկլում ինչի՞ ես i=1-ից սկսել, այլ ոչ թե i=0 :pardon
Բայց էսքանով չի ավարտվում: Ամենալուրջ սխալը վերջում ա: Տող 25-ում ուզումա արտածվի y զանգվածի տարրերը, դու խառնել ես ու նույն ցիկլի մեջ ես իրան գրել, ինչում որ հաշվում էիր: Արտածելու համար մի նոր ցիկլ արա՝
for(i=0; i<k; i++)
cout<<y[i]<<endl;

Կարաս և առանց նոր ցիկլի անես, բայց ընդունված բան ա, որ էս տիպի խնդիրներում պարզ հստակ երևա՝
ներմուծում
լուծում
արտածում

Թե չէ որ ճիշտը խոսանք, մի ցիկլով կլուծես էս խնդիրը, եթե հավես ունես մտածի, չստավելու դեպքում կօգնեմ;)

Հա, էս էլ վերջնական լուծումը:)


#include <iostream>
using namespace std;
void main()
{
int x[10], i,n, y[10], k;
do
{
cout<<"mutqagreq zangavtsi chapy"<<endl;
cin>>n;
}
while(1>n||n>10);
for(i=0; i<n; i++)
{
cout<<"x["<<i<<"]=";
cin>>x[i];
}
k=0;
for(i=0; i<n; i++)
if(x[i]>0)
{
y[k]=x[i];
k++;
}

cout<<"nor zangvacy klini "<<endl;
for(i=0; i<k; i++)
cout<<y[i]<<endl;

}

____

Ruzanna Stepanyan
20.04.2012, 21:49
շնորհակալ եմ շատ մանրամասն բացատրության համար :)

Ruzanna Stepanyan
20.04.2012, 21:56
Բայց ոնց որ թե մի բան անհասկանալի մնաց :)
նոր զանգվածը y[k]-ն էր, ինչի ենք գրում cout<<y[i]<<endl;

armen9494
20.04.2012, 22:19
Բայց ոնց որ թե մի բան անհասկանալի մնաց :)
նոր զանգվածը y[k]-ն էր, ինչի ենք գրում cout<<y[i]<<endl;

օօօ, էս ամենալուրջ սխալն ա:
Էս պահը ոնց որ թե մի փոքր սխալ եք հասկացել:
Բերեք էս մի հատը սենց սովորական, "գեղավարի" բառերով ասեմ :))
Ուրեմն զանգվածը դա y-ն ա:
Զանգվածի որևէ տարր ունենալու համար գրում ենք y[] ու էդ քառակուսի փակագծերի մեջ թիվ գրում:
Դե մեզ էս դեպքում պետք ա, որ y զանգվածի 0-ից մինչև k տարրերը տպվեն:
Հիշու՞մ եք, մենք որ ուզում ենք x զանգվածի դեպքում 0-ից մինչև n տարրերը ներմուծել, գրում ենք
for(i=0; i<n; i++)
cin>>x[i]

Դե հիմա նույն ձևով n-ը փոխարինում ենք k-ով (տարրերի քանակը): x-ը փոխարինում ենք y-ով (զանգվածը): cin-ը փոխարինում ենք cout-ով (արտածել):


Իսկ գիտական ձևով էսպես կլինի, չնայած չեմ կարծում, որ էս մի բացատրությունը ձեզ հետաքրքրի:
y-ը իրականում ցուցիչ է, այսինքն ցույց է տալիս հասցե (ցույց է տալիս մեր զանգվածի առաջին (0 ինդեքսով) տարրի հասցեն): Գրելով y[i] մենք ասում ենք գնա y+[i] հասցեի վրա: Էս գումարումը ուղիղ սովորական գումարում չի, i-ն գումարվում ա նախապես բազմապատկվելով հայտարարված զանգվածի տիպի զբաղեցրած ծավալի հետ:

Ruzanna Stepanyan
20.04.2012, 22:26
օօօ, էս ամենալուրջ սխալն ա:
Էս պահը ոնց որ թե մի փոքր սխալ եք հասկացել:
Բերեք էս մի հատը սենց սովորական, "գեղավարի" բառերով ասեմ :))
Ուրեմն զանգվածը դա y-ն ա:
Զանգվածի որևէ տարր ունենալու համար գրում ենք y[] ու էդ քառակուսի փակագծերի մեջ թիվ գրում:
Դե մեզ էս դեպքում պետք ա, որ y զանգվածի 0-ից մինչև k տարրերը տպվեն:
Հիշու՞մ եք, մենք որ ուզում ենք x զանգվածի դեպքում 0-ից մինչև n տարրերը ներմուծել, գրում ենք
for(i=0; i<n; i++)
cin>>x[i]

Դե հիմա նույն ձևով n-ը փոխարինում ենք k-ով (տարրերի քանակը): x-ը փոխարինում ենք y-ով (զանգվածը): cin-ը փոխարինում ենք cout-ով (արտածել):


Իսկ գիտական ձևով էսպես կլինի, չնայած չեմ կարծում, որ էս մի բացատրությունը ձեզ հետաքրքրի:
y-ը իրականում ցուցիչ է, այսինքն ցույց է տալիս հասցե (ցույց է տալիս մեր զանգվածի առաջին (0 ինդեքսով) տարրի հասցեն): Գրելով y[i] մենք ասում ենք գնա y+[i] հասցեի վրա: Էս գումարումը ուղիղ սովորական գումարում չի, i-ն գումարվում ա նախապես բազմապատկվելով հայտարարված զանգվածի տիպի զբաղեցրած ծավալի հետ:

ախր y[k]-ի փոխարեն գրել ենք y[i]: էդ պահը չեմ հասկանում

armen9494
20.04.2012, 22:27
ախր y[k]-ի փոխարեն գրել ենք y[i]: էդ պահը չեմ հասկանում

Մի վայրկյան մի բան հարցնեմ: Որ գրում ենք x[i] հասկանու՞մ եք: Բա ընդեղ ինչի՞ չենք գրում x[n] :

Ruzanna Stepanyan
20.04.2012, 22:32
Մի վայրկյան մի բան հարցնեմ: Որ գրում ենք x[i] հասկանու՞մ եք: Բա ընդեղ ինչի՞ չենք գրում x[n] :

լավ, մի քիչ ուշ, բայց գլխի ընկա :) :)

armen9494
20.04.2012, 22:42
լավ, մի քիչ ուշ, բայց գլխի ընկա :) :)

Դե լավ;)
Իսկ հիմա կարող եք փորձել հասկանալ էն ավելի "գիտական" լեզվով գրածը, հետագայում պետք կգա:

MSGM
23.04.2012, 14:17
Բայց մի տեսակ տարօրինակ չի երևու՞մ աչքիդ էդ սարքած սայթը :unsure
Իսկ ես մտածում եմ, որ էս ծրագիրը էնքան որ ձև ա բռնում, որ մթոմ թե սարքել ա:
Ահա և ապացույցները, եթե իհարկե մի բան սխալ չեմ արել:
Հիմա նայի, ենթադրում եմ որ ինքը լավ ծրագիր ա ու արեց իմ ասածը՝ այսինքն վերցրեց տեղ էդ երկու երկչափ զանգվածների համար: Հետևաբար ես կարամ իրանց հետ գործ անեմ, այնպես չէ՞:
Դե հիմա նայի, ես գրում եմ ծրագիր, որը էն երկրորդ զանգվածի 100 հատ տարրի հետ "կզբաղվի" (դրանց արժեքներ կտա):
"Միջակայքը" գրում եմ 400,410
որից հետո տալիս եմ արտածի էդ միջակայքում գտնվող տարրերից ընդամենը մեկի արժեքը:

Արդյունքում ծրագիրը լացում ա :)) Segmentation fault

Հիմա էդ նույն բանը անում եմ 0,10 միջակայքում:

Արդյունքում ուրախ ուրախ թռվռալով երգում ա :D 25

Տուտ չտո-տո նե տո...:think

Էտ որ գրում ես


b[100][500];

հետո էլ


for( i=400; i<410; i++)
for( j=400; j<410; j++)
b[i][j]=5*20;

դիմում ես քո ծրագրին չհատկացված հիշողությանը, որը (արդեն հազար անգամ ասել եմ :))) segmentation fault ա տալիս:

armen9494
23.04.2012, 22:57
Էտ որ գրում ես


b[100][500];

հետո էլ


for( i=400; i<410; i++)
for( j=400; j<410; j++)
b[i][j]=5*20;

դիմում ես քո ծրագրին չհատկացված հիշողությանը, որը (արդեն հազար անգամ ասել եմ :))) segmentation fault ա տալիս:

վայ :D

ashot_1987
27.04.2012, 14:42
http://s16.rimg.info/71c043d2fe5114510c43423a91c69072.gif (http://smayliki.ru/smilie-921247335.html)
<a target="_blank" href="http://smayliki.ru/smilie-921247335.html"><img src="http://s16.rimg.info/71c043d2fe5114510c43423a91c69072.gif" ></a>
http://s16.rimg.info/71c043d2fe5114510c43423a91c69072.gif (http://smayliki.ru/smilie-921247335.html)

armen9494
16.08.2012, 23:36
Ժողովուրդ ջան ինձ մի սայթ ա պետք, որի մեջ տրված լինեն c++-ի խնդիրներ (սկսած ամենապարզից, վերջացրած ամենաբարդ պռոեկտներով), լուծես խնդիրը ու գրես էդտեղ, ինքը ստուգի ու ասի՝ ճիշտ ա, թե չէ: Լավ կլինի, որ ֆոռումի նման լինի, որպեսզի ուրիշների հետ քննարկես, խորհուրդ հարցնես:
Շատ հաճելի կլինի, որ ամենապարզից լինի, որպեսզի հեշտ սկսեմ, թեկուզև գիտեմ: Ավելի լավ կլինի, որ ինչ-որ ռեյտինգային միավորներ հավաքեմ լուծելու ընթացքում:
Եվ մի բան էլ, հաճելի կլինի, եթե ռուսերեն լինի (դե հայերենից վաբշե հույսս կտրել եմ):
Նախապես շատ շատ շնորհակալություն:

soultaker
16.08.2012, 23:50
Ժողովուրդ ջան ինձ մի սայթ ա պետք, որի մեջ տրված լինեն c++-ի խնդիրներ (սկսած ամենապարզից, վերջացրած ամենաբարդ պռոեկտներով), լուծես խնդիրը ու գրես էդտեղ, ինքը ստուգի ու ասի՝ ճիշտ ա, թե չէ: Լավ կլինի, որ ֆոռումի նման լինի, որպեսզի ուրիշների հետ քննարկես, խորհուրդ հարցնես:
Շատ հաճելի կլինի, որ ամենապարզից լինի, որպեսզի հեշտ սկսեմ, թեկուզև գիտեմ: Ավելի լավ կլինի, որ ինչ-որ ռեյտինգային միավորներ հավաքեմ լուծելու ընթացքում:
Եվ մի բան էլ, հաճելի կլինի, եթե ռուսերեն լինի (դե հայերենից վաբշե հույսս կտրել եմ):
Նախապես շատ շատ շնորհակալություն:

acm.timus.ru (http://acm.timus.ru)
codeforces.ru (http://codeforces.ru)

tikfiz
17.08.2012, 13:27
Ժողովուրդ ջան ինձ մի սայթ ա պետք, որի մեջ տրված լինեն c++-ի խնդիրներ (սկսած ամենապարզից, վերջացրած ամենաբարդ պռոեկտներով), լուծես խնդիրը ու գրես էդտեղ, ինքը ստուգի ու ասի՝ ճիշտ ա, թե չէ: Լավ կլինի, որ ֆոռումի նման լինի, որպեսզի ուրիշների հետ քննարկես, խորհուրդ հարցնես:
Շատ հաճելի կլինի, որ ամենապարզից լինի, որպեսզի հեշտ սկսեմ, թեկուզև գիտեմ: Ավելի լավ կլինի, որ ինչ-որ ռեյտինգային միավորներ հավաքեմ լուծելու ընթացքում:
Եվ մի բան էլ, հաճելի կլինի, եթե ռուսերեն լինի (դե հայերենից վաբշե հույսս կտրել եմ):
Նախապես շատ շատ շնորհակալություն:

շատ լավ սայթ dl.gsu.by (http://dl.gsu.by) սկսնակների համար (սկսնակներից մինչև ամենապրոֆեսիոնալ մակարդակի խնդիրներ)(մուտք լինելուց լեզուն փոխեք ռուսերեն)
հայկական acm.am (http://acm.am)
spoj.pl (http://spoj.pl) խնդիրներ լուծելու համար

tikfiz
18.08.2012, 16:36
spoj.pl-ում կա հայերեն բաժին, որտեղ կա մոտ 70 հայերեն խնդիր: այն կարող եք մտնել am.spoj.pl (http://am.spoj.pl) հասցեով:
acm.timus.ru և codeforces.ru սայթերնել են լավը ուղղակի չկրկնվելու համար չեմ գրել: codeforces.ru-ում հաճախ անցկացվում են մրցույթներ:
Եթե ինչ-որ հարցեր առաջանան գրեք:

tikfiz
19.08.2012, 10:44
ևս մեկ լավ սայթ հիշեցի http://informatics.mccme.ru: Այնտեղ շատ լավ գրված է լեզուն 0-ից սկսողների համար և շատ բաներ իմացողների համար կան լուրջ թեմաներ: Ամեն թեմայի համար կան խնդիրներ: Եթե նոր եք սկսում սովորել ես խորհուրդ կտաի կամ այս սայթը կամ dl.gsu.by-ը:

Ruzanna Stepanyan
01.10.2012, 21:41
Խնդրում եմ օգնեք հասկանամ, ինչն եմ սխալ անում էս խնդրում, որ չի ստացվում:

Խնդիր:
Տրված են n և k ամբողջ թվերն ու nXn տարր պարունակող երկչափ զանգված: Հաշվել և արտածել k-րդ տողի մեծագույն տարրը:

#include <iostream>
using namespace std;
void main()
{
int xamyak[n][n], tox, syun, max, k, n;
cout<<"n="<<endl;
cin>>n;
cout<<"k="<<endl;
cin>>k;
cout<<"mutqagreq zangvaci arjeqnery"<<endl;
for (tox=0; tox<n; tox++)
{
for (syun=0; syun<n; syun++)
cin>>xamyak[tox][syun];
cout<<endl;
}

max=xamyak[k-1][0];
for (tox=0; tox<n; tox++)
{
for (syun=0; syun<n; syun++)
{
if(tox==k-1)
{
if(xamyak[tox][syun]>max)
max=xamyak[tox][syun];

}
}
cout<<"zangaci k-rd toxi max tarry klini"<<max<<endl;
}

}

Valentina
01.10.2012, 22:01
Տողերի համար արտաքին ցիկլը պետք չի, քանի որ k-ն մուտք է արվում, այսինքն հայտնի թիվ ա, մնում ա մի հատ սյուներով անցնել, մաքսիմումը գտնելու համար:



max=xamyak[k][0]; // վերցնում ենք k-րդ տողի 1-ին սյան էլէմենտը որպես մաքսիմում ու համեմատում նույն տողի մյուս էլեմենտների հետ:
for(syun=0; syun<n && syun+1<n; syun ++)
{
if( xamyak[k][syun]<xamyak[k][syun+1])
max= xamyak[k][syun+1];
}

Ruzanna Stepanyan
01.10.2012, 22:55
Տողերի համար արտաքին ցիկլը պետք չի, քանի որ k-ն մուտք է արվում, այսինքն հայտնի թիվ ա, մնում ա մի հատ սյուներով անցնել, մաքսիմումը գտնելու համար:



max=xamyak[k][0]; // վերցնում ենք k-րդ տողի 1-ին սյան էլէմենտը որպես մաքսիմում ու համեմատում նույն տողի մյուս էլեմենտների հետ:
for(syun=0; syun<n && syun+1<n; syun ++)
{
if( xamyak[k][syun]<xamyak[k][syun+1])
max= xamyak[k][syun+1];
}


Շնորհակալ եմ շատ, բայց էլի չի ստացվում: Էսպես եմ գրել

#include <iostream>
using namespace std;
void main()
{
int xamyak[n][n], tox, syun, max, k, n;
cout<<"n="<<endl;
cin>>n;
cout<<"k="<<endl;
cin>>k;
cout<<"mutqagreq zangvaci arjeqnery"<<endl;
for (tox=0; tox<n; tox++)
{
for (syun=0; syun<n; syun++)
cin>>xamyak[tox][syun];
cout<<endl;
}

max=xamyak[k][0];
for(syun=0; syun<n && syun+1<n; syun ++)
{
if( xamyak[k][syun]<xamyak[k][syun+1])
max= xamyak[k][syun+1];
}

cout<<"zangaci k-rd toxi max tarry klini"<<max<<endl;


}

Միքո
01.10.2012, 23:33
Շնորհակալ եմ շատ, բայց էլի չի ստացվում: Էսպես եմ գրել

#include <iostream>
using namespace std;
void main()
{
int xamyak[n][n], tox, syun, max, k, n;
cout<<"n="<<endl;
cin>>n;
cout<<"k="<<endl;
cin>>k;
cout<<"mutqagreq zangvaci arjeqnery"<<endl;
for (tox=0; tox<n; tox++)
{
for (syun=0; syun<n; syun++)
cin>>xamyak[tox][syun];
cout<<endl;
}

max=xamyak[k][0];
for(syun=0; syun<n && syun+1<n; syun ++)
{
if( xamyak[k][syun]<xamyak[k][syun+1])
max= xamyak[k][syun+1];
}

cout<<"zangaci k-rd toxi max tarry klini"<<max<<endl;


}

իսկ n-ը չպետքա const լինի՞ :)

Ruzanna Stepanyan
01.10.2012, 23:37
իսկ n-ը չպետքա const լինի՞ :)

ինչ կլինի մի հատ վերջնական տարբերակը գրեք էլի, չի ստացվում

DavitH
02.10.2012, 09:37
int xamyak[n][n], tox, syun, max, k, n; սրա տեղը
սենց գրի
int tox, syun, max, k;
const int n=10;
int xamyak[n][n];

կամ էլ
int tox, syun, max, k;
const int n=10;
int **mas = new int * [n];
for ( int i = 0; i < n; i ++ )
mas[i] = new int [n];


հ.գ. եթե իհարկե ճիշտ եմ հիշում :) 1000 տարի ա չեմ գրել c++ ով

MSGM
02.10.2012, 11:45
int xamyak[n][n], tox, syun, max, k, n; սրա տեղը
սենց գրի
int tox, syun, max, k;
const int n=10;
int xamyak[n][n];

Պետք կլինի գրել ասենք


int xamyak[100][100], syun, max, k, n;

ու n-ը կոնստանտ չսարքել, որովհետև հետո կա


cin >> n;

տողը:

Ամբողջությամբ կլինի.


#include <iostream>
using namespace std;
void main()
{
int xamyak[100][100], tox, syun, max, k, n;
cout<<"n="<<endl;
cin>>n;
cout<<"k="<<endl;
cin>>k;
cout<<"mutqagreq zangvaci arjeqnery"<<endl;
for (tox=0; tox<n; tox++)
{
for (syun=0; syun<n; syun++)
cin>>xamyak[tox][syun];
cout<<endl;
}

max=xamyak[k-1][0];
for (syun=0; syun<n; syun++)
{
if(xamyak[k-1][syun]>max)
max=xamyak[k-1][syun];

}
cout<<"zangaci k-rd toxi max tarry klini"<<max<<endl;

}

DavitH
02.10.2012, 17:28
դե բնականաբար հետո

cin >> n;

մասը պիտի հանվեր

Ruzanna Stepanyan
02.10.2012, 19:52
Պետք կլինի գրել ասենք


int xamyak[100][100], syun, max, k, n;

ու n-ը կոնստանտ չսարքել, որովհետև հետո կա


cin >> n;

տողը:

Ամբողջությամբ կլինի.


#include <iostream>
using namespace std;
void main()
{
int xamyak[100][100], tox, syun, max, k, n;
cout<<"n="<<endl;
cin>>n;
cout<<"k="<<endl;
cin>>k;
cout<<"mutqagreq zangvaci arjeqnery"<<endl;
for (tox=0; tox<n; tox++)
{
for (syun=0; syun<n; syun++)
cin>>xamyak[tox][syun];
cout<<endl;
}

max=xamyak[k-1][0];
for (syun=0; syun<n; syun++)
{
if(xamyak[k-1][syun]>max)
max=xamyak[k-1][syun];

}
cout<<"zangaci k-rd toxi max tarry klini"<<max<<endl;

}



շնորհակալ եմ շատ, որ Ձեր ժամանակը տրամադրեցիք ու պատասխանեցիք :)

Մի բան էլ հարցնեմ, կարող եմ սրա փոխարեն

max=xamyak[k-1][0];
for (syun=0; syun<n; syun++)
{
if(xamyak[k-1][syun]>max)
max=xamyak[k-1][syun];

}
cout<<"zangaci k-rd toxi max tarry klini"<<max<<endl;

}

գրել այսպես

max=xamyak[k][0];
for(syun=0; syun<n; syun ++)
{
if( xamyak[k][syun]>max)
max= xamyak[k][syun];
}
cout<<"zangaci k-rd toxi max tarry klini"<<max<<endl;
}

Chuk
02.10.2012, 20:07
Մի բան էլ հարցնեմ, կարող եմ սրա փոխարեն
...
գրել այսպես

Ռուզան ջան, C++-ում առաջին տողը համարակալվում ա զրոյով (0): Այսինքն եթե դու C++-ում գործ ես անում k-րդ տողի հետ, էդ մեր պատկերացրած k+1-րդ տողն ա: Այսինքն Եթե դու կանչում ես xamyak[k][0]-ն, իսկ որպես k ներմուծել ես ասենք 5 թիվը, դու էդտեղ գործ կունենաս իրականում 6-րդ տողի հետ ու քո խնդրի պահանջին ինքը չի համապատասխանի: Նույն 5 ներմուծման դեպքում «k-1»-ով դու գործ կունենաս ըստ C++-ի 4-րդ տողի հետ (որին նախորդել են 0, 1, 2, 3 տողերը) ու կլինի քո ուզած 5-րդ տողը:

Ruzanna Stepanyan
02.10.2012, 20:52
Ռուզան ջան, C++-ում առաջին տողը համարակալվում ա զրոյով (0): Այսինքն եթե դու C++-ում գործ ես անում k-րդ տողի հետ, էդ մեր պատկերացրած k+1-րդ տողն ա: Այսինքն Եթե դու կանչում ես xamyak[k][0]-ն, իսկ որպես k ներմուծել ես ասենք 5 թիվը, դու էդտեղ գործ կունենաս իրականում 6-րդ տողի հետ ու քո խնդրի պահանջին ինքը չի համապատասխանի: Նույն 5 ներմուծման դեպքում «k-1»-ով դու գործ կունենաս ըստ C++-ի 4-րդ տողի հետ (որին նախորդել են 0, 1, 2, 3 տողերը) ու կլինի քո ուզած 5-րդ տողը:

Արտակ ջան,

ես էլ էդպես գիտեմ, բայց խնդիրը աշխատացնելու դեպքում աշխատում է իմ առաջարկած տարբերակը, իսկ մյուս տարբերակը, չի աշխատում:



մի Օրինակ բերեմ
իմ գրած տարբերակով ստացվում է սենց
n=4 k=2
Mutqagreq zangvaci arjeqnery

1 2 3 58
5 3 2 6
9 10 15 200
10 5 1 98

zangaci k-rd toxi max tarry klini 200



իսկ դզեր գրած տարբերակով ստացվում է էսպես
n=4 k=2
Mutqagreq zangvaci arjeqnery

1 2 3 58
5 3 2 6
9 10 15 200
10 5 1 98

zangaci k-rd toxi max tarry klini 6

Chuk
02.10.2012, 20:59
Արտակ ջան,

ես էլ էդպես գիտեմ, բայց խնդիրը աշխատացնելու դեպքում աշխատում է իմ առաջարկած տարբերակը, իսկ մյուս տարբերակը, չի աշխատում:



մի Օրինակ բերեմ

n=4 k=2
Mutqagreq zangvaci arjeqnery

1 2 3 58
5 3 2 6
9 10 15 200
10 5 1 98

zangaci k-rd toxi max tarry klini 200
Բա դրա համար էլ պետք է դիմել (k-1) տողին :)

Lusina
02.10.2012, 21:07
Արտակ ջան,

ես էլ էդպես գիտեմ, բայց խնդիրը աշխատացնելու դեպքում աշխատում է իմ առաջարկած տարբերակը, իսկ մյուս տարբերակը, չի աշխատում:



մի Օրինակ բերեմ
իմ գրած տարբերակով ստացվում է սենց
n=4 k=2
Mutqagreq zangvaci arjeqnery

1 2 3 58
5 3 2 6
9 10 15 200
10 5 1 98

zangaci k-rd toxi max tarry klini 200



իսկ դզեր գրած տարբերակով ստացվում է էսպես
n=4 k=2
Mutqagreq zangvaci arjeqnery

1 2 3 58
5 3 2 6
9 10 15 200
10 5 1 98

zangaci k-rd toxi max tarry klini 6

Եթե խնդրի պահանջի մեջ k-րդ ասվածը հասկացվում ա հենց 0-ից հաշվելով , էդ դեպքում ձեր ասած տարբերակով պետք ա գրեք.
Հ.Գ. Ու ինձ թվում ա՝ տենց էլ հասկացվում ա, զանգվածի համարակալումը մենակ c++-ում չի , որ 0-ից ա սկսվում.Կարճ ասած՝ կախված պահանջից.

Lusina
02.10.2012, 21:10
Մոռացա ասել՝ լավ կլինի մուտքագրումից հետո ստուգում անել, որ k-ն n-1-ից մեծ չլինի.

MSGM
02.10.2012, 21:19
Սկզբնական տարբերակում k-1 էր գրած, դրա համար էլ ենթադրեցի, որ մուտքային k-ն 1-ով ա համարակալված, եթե k-ն 0-ականով ա, ուրեմն k-1ի փոխարեն k:

Ruzanna Stepanyan
02.10.2012, 21:21
Անչափ շանորհակալ եմ, որ ձեր ժամանակը չեք ափսոսում և պատասխաում եք: Ինձ շատ օգնեցիք, ապրեք:

Lusina
02.10.2012, 21:25
Երեխեք, առաջարկում հետաքրքիր խնդիրներ էլ դնենք էս թեմայում.
Եթե համաձայն եք՝ դրեք :))
Հ.Գ.Թե՞ էս թեման մենակ հարցերի համար ա նախատեսված:unsure

Chuk
02.10.2012, 21:31
Եթե խնդրի պահանջի մեջ k-րդ ասվածը հասկացվում ա հենց 0-ից հաշվելով , էդ դեպքում ձեր ասած տարբերակով պետք ա գրեք.
Հ.Գ. Ու ինձ թվում ա՝ տենց էլ հասկացվում ա, զանգվածի համարակալումը մենակ c++-ում չի , որ 0-ից ա սկսվում.Կարճ ասած՝ կախված պահանջից.
Ճիշտ ես ասում, Lusina: Բայց եթե հաշվի առնենք, որ խոսքը գնում է դպրոցական կուրսի մասին (Ռուզաննան ինֆորմատիկայի ուսուցչուհի է), որտեղ գրքի առաջին մասում pascal-ն է ներկայացվում (որտեղ եթե ճիշտ եմ հիշում զանգվածի համարակալումը սկսվում է 1-ից), հետո նոր անցնում են C++-ին, որտեղ զանգվածները բացատրում են առաջին տողի 1 համարակալմամբ, մեջբերում եմ.


Երկչափ զանգվածի ցանկացած տարրին դիմելու համար անհրաժեշտ է երկու ինդեքս կիրառել: Երկչափ զանգվածը ակնառու պատկերացնելու համար դիտենք դասարանի նստարանների շարքերը: Ենթադրենք դրանք դասավորված են 4 շարքով, իսկ յուրաքանչյուր շարքում կա 3-ական սեղան. համարակալենք սեղաններն այնպես, որ այդ համարներով միարժեքորեն որոշվի սեղանի գտնվելու շարքն ու շարքում դրա դիրքը:

S[1][1] S[1][2] S[1][3] S[1][4]
S[2][1] S[2][2] S[2][3] S[2][4]
S[3][1] S[3][2] S[3][3] S[3][4]

Ինչպես տեսնում եք` շարքը բնորոշող համարը քառակուսի փակագծերի մեջ առնված թվերից երկրորդն է, իսկ առաջինը` տվյալ շարքում նստարանի հերթական համարը: Նման եղանակով կարգավորված տվյալների համախումμն անվանում են երկչափ զանգված: Երկչափ զանգվածի տարրի առաջին ինդեքսը համարում են տարրի գտնվելու տողի, իսկ երկրորդը` սյան համարը: Նույն սկզբունքով կարելի է սահմանել նաև բազմաչափ զանգվածները:
(Մեջբերումն այստեղից (http://armedu.am/arm/files/material_files/bnagitakan.pdf))

ապա կարծում եմ, որ խնդիրների պահանջներն էլ 1-ով համարակալումը սկսելուն են վերաբերում: Բայց դե ինչ իմանաս, էդ գրքերը բավականին բառդակոտ են :)

Lusina
02.10.2012, 21:39
Ճիշտ ես ասում, Lusina: Բայց եթե հաշվի առնենք, որ խոսքը գնում է դպրոցական կուրսի մասին (Ռուզաննան ինֆորմատիկայի ուսուցչուհի է), որտեղ գրքի առաջին մասում pascal-ն է ներկայացվում (որտեղ եթե ճիշտ եմ հիշում զանգվածի համարակալումը սկսվում է 1-ից), հետո նոր անցնում են C++-ին, որտեղ զանգվածները բացատրում են առաջին տողի 1 համարակալմամբ, մեջբերում եմ.


(Մեջբերումն այստեղից (http://armedu.am/arm/files/material_files/bnagitakan.pdf))

ապա կարծում եմ, որ խնդիրների պահանջներն էլ 1-ով համարակալումը սկսելուն են վերաբերում: Բայց դե ինչ իմանաս, էդ գրքերը բավականին բառդակոտ են :)

Չգիտեմ՝ գրածս ինչ շեշտադրումով ա թվացել, բայց ես Ձեզ սխալ հանելու համար չէի տենց գրել, սենց հիմնավորելու կարիք չկար.
Հ.Գ. Ոնց որ թեմայից դուրս եկա :))

Chuk
02.10.2012, 21:40
Չգիտեմ՝ գրածս ինչ շեշտադրումով ա թվացել, բայց ես Ձեզ սխալ հանելու համար չէի տենց գրել, սենց հիմնավորելու կարիք չկար.
Հ.Գ. Ոնց որ թեմայից դուրս եկա :))

Չէ Lusina ջան, էդպես չէի ընկալել: Էդ բացատրությունը գրեցի, որ Ռուզաննայի կասկածներն էլ ցրվեն, թե խնդրի պահանջը որ համարակալմամբ է՝ զրոյո՞վ, թե՞ մեկով:)

Ruzanna Stepanyan
02.10.2012, 21:40
Ճիշտ ես ասում, Lusina: Բայց եթե հաշվի առնենք, որ խոսքը գնում է դպրոցական կուրսի մասին (Ռուզաննան ինֆորմատիկայի ուսուցչուհի է), որտեղ գրքի առաջին մասում pascal-ն է ներկայացվում (որտեղ եթե ճիշտ եմ հիշում զանգվածի համարակալումը սկսվում է 1-ից), հետո նոր անցնում են C++-ին, որտեղ զանգվածները բացատրում են առաջին տողի 1 համարակալմամբ, մեջբերում եմ.


(Մեջբերումն այստեղից (http://armedu.am/arm/files/material_files/bnagitakan.pdf))

ապա կարծում եմ, որ խնդիրների պահանջներն էլ 1-ով համարակալումը սկսելուն են վերաբերում: Բայց դե ինչ իմանաս, էդ գրքերը բավականին բառդակոտ են :)

Դու ճիշտ ես Արտակ ջան, դրա համար էլ էրեխեքը անընդհատ շփոթության մեջ են ընկնում խնդիր լուծելիս: Ապրես շատ:)

Varzor
03.10.2012, 01:29
(Մեջբերումն այստեղից (http://armedu.am/arm/files/material_files/bnagitakan.pdf))

Փաստորեն Ավետիսյանն ու Դանիելյանը արդեն դպրոցի համար են դասագրքեր գրում? :))
Ի դեպ լավ թարգմանություն էր:
Մենակ չեմ հասկանում, թե ինչի են համ Պասկալ անցնում համ էլ C++?? :think
Նախ խճճվելը շատ հեշտ է, երկրորդն էլ Pascal-ը ներկայումս պրակտիկորեն չկիրառվող լեզու է:

Chuk
03.10.2012, 01:32
Փաստորեն Ավետիսյանն ու Դանիելյանը արդեն դպրոցի համար են դասագրքեր գրում? :))
Ի դեպ լավ թարգմանություն էր:
Մենակ չեմ հասկանում, թե ինչի են համ Պասկալ անցնում համ էլ C++?? :think
Նախ խճճվելը շատ հեշտ է, երկրորդն էլ Pascal-ը ներկայումս պրակտիկորեն չկիրառվող լեզու է:

Որ հասկանայի՝ կբացատրեի :)) Չնայած ինձ բացատրել են, ասել են, որ իբր ամեն դպրոց ինքն ա ընտրում, որն անցնել: Էշություն, եթե իսկապես տենց ա, կարելի էր երկու տարբեր դասագրքեր հրատարակել, ծախսը քիչ կլիներ:

հ.գ. Եթե տենց չի, երկուսն էլ անցնում են, էլի էշություն ա:

Varzor
03.10.2012, 02:03
Որ հասկանայի՝ կբացատրեի :)) Չնայած ինձ բացատրել են, ասել են, որ իբր ամեն դպրոց ինքն ա ընտրում, որն անցնել: Էշություն, եթե իսկապես տենց ա, կարելի էր երկու տարբեր դասագրքեր հրատարակել, ծախսը քիչ կլիներ:
հ.գ. Եթե տենց չի, երկուսն էլ անցնում են, էլի էշություն ա:

Քեզ հետ լիովին համամիտ եմ:
Իսկ էդ պարագայում, ստացվում է, որ կարող են լինել դպրոցներ, որոնք կընտրեն Պասկալը կամ էլ երկուսն էլ?
Բայց էդ նույնն է, ոնց որ ասենք մարդուն հնարավորություն տան ընտրելու գունավոր թվային հեռուստացույցի և լամպային սև ու սպիտակ հեռուստացույցի միջև ու նա ընտրի վերջինը:
Ինչևէ` Նման դասագրքի առկայությունը իրոք որ էշություն է:

Հ.Գ.
Բայց բովանդակությունը վատը չի, C++-ի մասն էլ Դեյտելից են "թխել"

zulu
03.10.2012, 09:33
Քեզ հետ լիովին համամիտ եմ:
Իսկ էդ պարագայում, ստացվում է, որ կարող են լինել դպրոցներ, որոնք կընտրեն Պասկալը կամ էլ երկուսն էլ?
Բայց էդ նույնն է, ոնց որ ասենք մարդուն հնարավորություն տան ընտրելու գունավոր թվային հեռուստացույցի և լամպային սև ու սպիտակ հեռուստացույցի միջև ու նա ընտրի վերջինը:
Ինչևէ` Նման դասագրքի առկայությունը իրոք որ էշություն է:

Հ.Գ.
Բայց բովանդակությունը վատը չի, C++-ի մասն էլ Դեյտելից են "թխել"

Ծրագրավորումից ընդհանրապես գաղափար չունեցող մարդու համար Pascal-ից սկսելը շատ լավ տարբերակ է՝ այն թույլ է տալիս շատ հեշտ սովորեցնել հիմունքները եւ հիմնական գաղափարները։ Համեմատությունը լամպային սեւ ու սպիտակ հեռուստացույցի հետ տեղին չէ։ Իսկ Pascal-ի օգնությամբ հիմունքները հասկացած մարդուն հետագայում ավելի հեշտ կլինի ցանկացած լեզու սովորել։

Sent from my GT-P7310 using Tapatalk 2

Ruzanna Stepanyan
03.10.2012, 10:22
Որ հասկանայի՝ կբացատրեի :)) Չնայած ինձ բացատրել են, ասել են, որ իբր ամեն դպրոց ինքն ա ընտրում, որն անցնել: Էշություն, եթե իսկապես տենց ա, կարելի էր երկու տարբեր դասագրքեր հրատարակել, ծախսը քիչ կլիներ:

հ.գ. Եթե տենց չի, երկուսն էլ անցնում են, էլի էշություն ա:

Արտակ ջան, իսկակպես էդպես ա, մենք ենք որոշում, թե ինչ անցնենք:

Ruzanna Stepanyan
03.10.2012, 21:30
Խնդրում եմ մի հատ նայեք ինչն եմ սխալ անում, որ խնդիրը չի ստացվում:

Տրված է n բնական թիվը: Հաշվել 1-ից n միջակայքի այն թվերի միջին թվաբանականը, որոնք 7-ի բաժանվելիս տալիս են 2 մնացորդ:

sing namespace std;
void main()
{
int k,i,n,s;
double p;
cout<<"n="<<endl;
cin>>n;
s=0;
k=0;
for(i=1; i<=n; i++)
{
if(i%7==2)
{
s=s+i;
k++;
}
}
p=s/k;
cout<<"p="<<p<<endl;
}

One_Way_Ticket
03.10.2012, 21:42
p=s/k;
Քանի որ s-ը և k-ն int տիպի են, ապա նրանց բաժանման արդյունքը ևս int է (վերցվում է ամբողջ մասը): Հետո այն double-ի վերագրելիս միևնույնն է, ամբողջ մասն է մնում: Մինչև բաժանումը բաժանարարը կամ բաժանելին պետք է cast անել double տիպի: Ասենք, սենց.
p = (double)s / k;

Lusina
03.10.2012, 21:48
Խնդրում եմ մի հատ նայեք ինչն եմ սխալ անում, որ խնդիրը չի ստացվում:

Տրված է n բնական թիվը: Հաշվել 1-ից n միջակայքի այն թվերի միջին թվաբանականը, որոնք 7-ի բաժանվելիս տալիս են 2 մնացորդ:

sing namespace std;
void main()
{
int k,i,n,s;
double p;
cout<<"n="<<endl;
cin>>n;
s=0;
k=0;
for(i=1; i<=n; i++)
{
if(i%7==2)
{
s=s+i;
k++;
}
}
p=s/k;
cout<<"p="<<p<<endl;
}
Առաջին հայացքից սխալ բան չեմ նկատում. Իսկ " խնդիրը չի ստացվում" ասելով ի՞նչ նկատի ունեք, սխա՞լ ա հաշվում միջին թվաբանականը.
Մեկ էլ մի փոքր կարելի ա օպտիմիզացնել, n<9 դեպքում միանգամից 0 տպել ու ցիկլն էլ 9-ից սկսել (Կոնկրետ տրված թվերի դեպքում).
Հ.Գ. sing namespace std; ենթադրում եմ , որ վրիպակ ա, ամեն դեպքւմ՝ դիմացի "u-ն մոռացել եք

Ruzanna Stepanyan
03.10.2012, 22:09
Առաջին հայացքից սխալ բան չեմ նկատում. Իսկ " խնդիրը չի ստացվում" ասելով ի՞նչ նկատի ունեք, սխա՞լ ա հաշվում միջին թվաբանականը.
Մեկ էլ մի փոքր կարելի ա օպտիմիզացնել, n<9 դեպքում միանգամից 0 տպել ու ցիկլն էլ 9-ից սկսել (Կոնկրետ տրված թվերի դեպքում).
Հ.Գ. sing namespace std; ենթադրում եմ , որ վրիպակ ա, ամեն դեպքւմ՝ դիմացի "u-ն մոռացել եք

Լուսինա ջան, օրինակ ես գրում եմ n=25, պատասխանը ստացվում է p=12,5

sing namespace std; վրիպակ ա

Ruzanna Stepanyan
03.10.2012, 22:10
Քանի որ s-ը և k-ն int տիպի են, ապա նրանց բաժանման արդյունքը ևս int է (վերցվում է ամբողջ մասը): Հետո այն double-ի վերագրելիս միևնույնն է, ամբողջ մասն է մնում: Մինչև բաժանումը բաժանարարը կամ բաժանելին պետք է cast անել double տիպի: Ասենք, սենց.
p = (double)s / k;

շնորհակալ եմ , իսկ կարող եմ էսպես նկարագրել սկզբում
int k,i,n;
double s,p;

One_Way_Ticket
03.10.2012, 22:25
շնորհակալ եմ , իսկ կարող եմ էսպես նկարագրել սկզբում
int k,i,n;
double s,p;
Կարելի է և այդպես։

Ruzanna Stepanyan
09.10.2012, 21:32
Խնդրում եմ օգնեք, չի ստացվում խնդիրը.

Հաշվել և արտածել այն ամենամեծ երկնիշ թիվը, որին նախորդող ամբողջ դրական թվերի արտադրյալը չի գերազանցում 10 000-ը:

#include <iostream>
using namespace std;
void main()
{
int i, p, n;
p=1;
for(i=10; i<=99; i++)
{
p=p*i;
if(p>10000)
{
n=i-1;
}

}
cout<<"n="<<n<<endl;
}

One_Way_Ticket
09.10.2012, 21:37
Հաշվել և արտածել այն ամենամեծ երկնիշ թիվը, որին նախորդող ամբողջ դրական թվերի արտադրյալը չի գերազանցում 10 000-ը:
Խնդիրը ի սկզբանե սխալ է ձևակերպված, քանի որ այդպիսի երկնիշ թիվ գոյություն չունի: Մեկից ութ թվերի արտադրյալն արդեն իսկ գերազանցում է տասը հազարը:

Ruzanna Stepanyan
09.10.2012, 21:40
Խնդիրը ի սկզբանե սխալ է ձևակերպված, քանի որ այդպիսի երկնիշ թիվ գոյություն չունի: Մեկից ութ թվերի արտադրյալն արդեն իսկ գերազանցում է տասը հազարը:

շնորհակալ եմ շատ, ես էլ էի էդպես մտածում, բայց կարծեցի ես չեմ հասկանում խնդիրը :)

իսկ այս խնդիրը ինչպես կարող եմ փոխել, որ լուծում ունենա:

Ruzanna Stepanyan
09.10.2012, 21:49
կլինի էսպես դարձնեմ պահանջը

Հաշվել և արտածել այն ամենամեծ բնական թիվը, որին նախորդող բոլոր բնական թվերի արտադրյալը չի գերազանցում 10 000 թիվը:

One_Way_Ticket
09.10.2012, 22:38
կլինի էսպես դարձնեմ պահանջը

Հաշվել և արտածել այն ամենամեծ բնական թիվը, որին նախորդող բոլոր բնական թվերի արտադրյալը չի գերազանցում 10 000 թիվը:
Հա, բայց դրա լուծումը շատ պարզ է․ std::cout << 7; :D
Ավելի լավ է, դարձրեք այսպես․ հաշվել և արտածել այն ամենամեծ բնական թիվը, որին նախորդող բոլոր բնական թվերի արտադրյալը չի գերազանցում տրված N-ը։

Ruzanna Stepanyan
09.10.2012, 23:16
Հա, բայց դրա լուծումը շատ պարզ է․ std::cout << 7; :D
Ավելի լավ է, դարձրեք այսպես․ հաշվել և արտածել այն ամենամեծ բնական թիվը, որին նախորդող բոլոր բնական թվերի արտադրյալը չի գերազանցում տրված N-ը։

փորձեցի լուծել ձեր առաջարկած խնդիրը, բայց ոնց որ թե էլի չի ստացվում One_Way_Ticket ջան :) ինչն եմ սխալ անում

#include <iostream>
using namespace std;
void main()
{
int i, p, n, k;
cout<<"n="<<endl;
cin>>n;
p=1;
for(i=1; i<=n; i++)
{
p=p*i;
if(p>n)
{
k=i-1;
}

}
cout<<"k="<<k<<endl;
}

One_Way_Ticket
09.10.2012, 23:27
k=i-1;
Սրանից հետո պետք է ցիկլից դուրս գալ break-ով։

Ruzanna Stepanyan
10.10.2012, 00:14
Սրանից հետո պետք է ցիկլից դուրս գալ break-ով։

էլի չի ստեցվում: Խնդրում եմ մի հատ գրեք էլի ծրագիրը լրիվ

One_Way_Ticket
10.10.2012, 00:32
էլի չի ստեցվում:
Ի՞նչ է տպում

Ruzanna Stepanyan
10.10.2012, 12:57
Ի՞նչ է տպում
Այս տարբերակով , այսինքն առանց break-i, տպում է 30
#include <iostream>
using namespace std;
void main()
{
int i, p, n, k;
cout<<"n="<<endl;
cin>>n;
p=1;
for(i=1; i<=n; i++)
{
p=p*i;
if(p>n)
{
k=i-1;
}

}
cout<<"k="<<k<<endl;
}


իսկ այս տարբերակով ընդհանրապես սև էկրանը չի բերում
#include <iostream>
using namespace std;
void main()
{
int i, p, n, k;
cout<<"n="<<endl;
cin>>n;
p=1;
for(i=1; i<=n; i++)
{
p=p*i;
if(p>n)
{
k=i-1;
break
}

}
cout<<"k="<<k<<endl;
}

zulu
10.10.2012, 13:08
Ավելի ճիշտ կլինի while-ով անել:


Այս տարբերակով , այսինքն առանց break-i, տպում է 30
#include <iostream>
using namespace std;
void main()
{
int i, p, n, k;
cout<<"n="<<endl;
cin>>n;
p=1;
for(i=1; i<=n; i++)
{
p=p*i;
if(p>n)
{
k=i-1;
}

}
cout<<"k="<<k<<endl;
}


իսկ այս տարբերակով ընդհանրապես սև էկրանը չի բերում
#include <iostream>
using namespace std;
void main()
{
int i, p, n, k;
cout<<"n="<<endl;
cin>>n;
p=1;
for(i=1; i<=n; i++)
{
p=p*i;
if(p>n)
{
k=i-1;
break
}

}
cout<<"k="<<k<<endl;
}

One_Way_Ticket
10.10.2012, 13:38
իսկ այս տարբերակով ընդհանրապես սև էկրանը չի բերում
#include <iostream>
using namespace std;
void main()
{
int i, p, n, k;
cout<<"n="<<endl;
cin>>n;
p=1;
for(i=1; i<=n; i++)
{
p=p*i;
if(p>n)
{
k=i-1;
break
}

}
cout<<"k="<<k<<endl;
}
Աչքիս break-ից հետո կետ-ստորակետը մոռացել եք:

Ruzanna Stepanyan
10.10.2012, 19:31
Աչքիս break-ից հետո կետ-ստորակետը մոռացել եք:

Վայ էս ինչ ամոթ սխալ եմ արել: Հազար անգամ ներեղություն: Անչափ շնորհակալ եմ :)

Ruzanna Stepanyan
13.10.2012, 23:19
Խնդրում եմ մի հատ կբացատրեք այս խնդիրը ոնց լուծեմ, մենակ թե խնդրում եմ քայլերով, եթե հնարավոր է: Նախապես շնորհակալ եմ:

n հատ տարր պարունակող միաչափ զանգվածը կարգավորել ըստ նվազման:

Varzor
14.10.2012, 02:57
Խնդրում եմ մի հատ կբացատրեք այս խնդիրը ոնց լուծեմ, մենակ թե խնդրում եմ քայլերով, եթե հնարավոր է: Նախապես շնորհակալ եմ:
n հատ տարր պարունակող միաչափ զանգվածը կարգավորել ըստ նվազման:
Ստանդարտ խնդիր է:
Եթե քայլերով, ապա սենց.
0. Ստանդարտ կարգով կազմակերպում ենք n թվի և զանգվածի n տարրերի ներմուծումը: Այս մասը արդեն քաջածանոթ է, առանձին չանդրադառնամ
1. մի փոփոխականի (օր` tmp) վերագրում ենք զանգվածի առաջին տարրի արժեքը
2. մեկ այլ փոփոխականի (օր` ind) վերագրում ենք զանգվածի առաջին տարրի ինդեքսը (C++ ում` 0)
3. կազմակերպում ենք ցիկլ` սկսած զանգվածի 2-րդ տարրից (C++ ում` 1ից )
4. Ցիկլի ամեն քայլում համեմատում ենք ընթացիկ տարրը 1-ին տարրի հետ.
4.1. եթե ընթացիկ տարրը մեծ է լինում 1-ինից, ապա ընթացիկ տարրի արժեքը պահում ենք` tmp-ին վերագրում ենք ընթացիկ տարրի արժեքը, կազմակերպում ենք ցիկլ մինչև ընթացիկ տարրի ինդեքսը և զանգվածի տարրերը տեղաշարժում ենք դեպի աջ` ինդեքսները մեծացնում ենք, զանգվածի առաջին տարրի արժեքին վերագրումենք պահած արժեքը` tmp-ն:
4.2. Եթե ընթացիկ տարրը փոքր է լինում առաջին տարրից, ապա այն համեմատում ենք իր նախորդ տարրի հետ.
4.2.1. Եթե իր նախորդ տարրից փոքր է, ապա տեղերով փոխում ենք նախորդի հետ:

Ծրագի օրինակը, առանց ներմուծման հետևյալն է`


#include <iostream>
using namespace std;
void main()
{
int n, i, j;
double x[n], tmp;

cout<<"n="<<endl;
cin>>n;
//զանգվածի ներմուծում
for (i=0; i<n; i++)
{
cin>>x[i];
cout<<endl;
}
for (i=1; i<n; i++)
{
//ստուգում ենք արդյոք ընթացիկ տարրը մեծ է առաջին տարրից
if (x[i]>=x[0])
{
//պահում ենք ընթացիկ տարրը
tmp=x[i];
//նախորդ տարրերը տեղաշարժում ենք աջ
for (j=i; j=1; j--)
{
x[j]=x[j-1];
}
//առաջին տարրին վերագրում ենք ընթացիկի պահված արժեքը:
x[0]=tmp;
}
else
{
//ստուգում ենք, արդյոք ընթացիկ տարրը նախորդ տարրից մեծ է
if(x[i]>=x[i-1])
{
//պահում ենք ընթացիկ տարրը
tmp=x[i];
//նախորդ տարրի հետ տեղերով փոխում ենք
x[i]=x[i-1];
x[i-1]=tmp;
}
}
}
}

Ruzanna Stepanyan
14.10.2012, 19:38
Ստանդարտ խնդիր է:
Եթե քայլերով, ապա սենց.
0. Ստանդարտ կարգով կազմակերպում ենք n թվի և զանգվածի n տարրերի ներմուծումը: Այս մասը արդեն քաջածանոթ է, առանձին չանդրադառնամ
1. մի փոփոխականի (օր` tmp) վերագրում ենք զանգվածի առաջին տարրի արժեքը
2. մեկ այլ փոփոխականի (օր` ind) վերագրում ենք զանգվածի առաջին տարրի ինդեքսը (C++ ում` 0)
3. կազմակերպում ենք ցիկլ` սկսած զանգվածի 2-րդ տարրից (C++ ում` 1ից )
4. Ցիկլի ամեն քայլում համեմատում ենք ընթացիկ տարրը 1-ին տարրի հետ.
4.1. եթե ընթացիկ տարրը մեծ է լինում 1-ինից, ապա ընթացիկ տարրի արժեքը պահում ենք` tmp-ին վերագրում ենք ընթացիկ տարրի արժեքը, կազմակերպում ենք ցիկլ մինչև ընթացիկ տարրի ինդեքսը և զանգվածի տարրերը տեղաշարժում ենք դեպի աջ` ինդեքսները մեծացնում ենք, զանգվածի առաջին տարրի արժեքին վերագրումենք պահած արժեքը` tmp-ն:
4.2. Եթե ընթացիկ տարրը փոքր է լինում առաջին տարրից, ապա այն համեմատում ենք իր նախորդ տարրի հետ.
4.2.1. Եթե իր նախորդ տարրից փոքր է, ապա տեղերով փոխում ենք նախորդի հետ:


Շնորհակալ եմ շատ պարզ և մատչելի բացատրելու համար, ապրեք :)

բայց ծրագիրը պատճենեցի Microsoft Visual Studio 2010-ի մեջ, չաշխատեց

Varzor
15.10.2012, 09:56
Շնորհակալ եմ շատ պարզ և մատչելի բացատրելու համար, ապրեք :)

բայց ծրագիրը պատճենեցի Microsoft Visual Studio 2010-ի մեջ, չաշխատեց
Քանի որ ծրագիը չեմ գրել ոչ մի միջավայրում` որպես սովորական տեքստ եմ գրել, ապա հնարավոր է չաշխատելու երկու պատճառ.
1. ինչ-որ տեղ սինտաքսիսի սխալ եմ արել:
2. հայերեն եկնաբանություններս յունիկոդ են:

Իսկ ինչ սխալ տվեց?

zulu
15.10.2012, 11:48
Քանի որ ծրագիը չեմ գրել ոչ մի միջավայրում` որպես սովորական տեքստ եմ գրել, ապա հնարավոր է չաշխատելու երկու պատճառ.
1. ինչ-որ տեղ սինտաքսիսի սխալ եմ արել:
2. հայերեն եկնաբանություններս յունիկոդ են:

Իսկ ինչ սխալ տվեց?

int n, i, j;
double x[n], tmp;

հաստատ այ սրա վրա ա սխալ տվել :)

Միքո
15.10.2012, 13:57
int n, i, j;
double x[n], tmp;

հաստատ այ սրա վրա ա սխալ տվել :)

ու արդեն երկրորդ անգամ :)

էտ անտեր ստատիկ մասիվի չափը պետքա հաստատուն լինի, անփոփոխ ու տենց :))

DavitH
15.10.2012, 16:50
Զարմանում եմ ինչ գործ ունի C++ դպրոցում ու ընդհանրապես ինչի են պարտադրում դպրոցականին ծրագրավորում?
միայն տարրական համակարգչային գիտելիքներ են պետք ու վերջ

Varzor
15.10.2012, 18:06
int n, i, j;
double x[n], tmp;
հաստատ այ սրա վրա ա սխալ տվել :)

Ինչ մեղքս թաքցնեմ` copy-past եմ արել էդ առաջին մասը, որ նորից չգրեմ ու թարսի պես հենց սխալ պարունակող գրառումից եմ արել :D
Իհարկե հենց էդ մեկը հաստատ սխալ է:

Varzor
15.10.2012, 18:09
Զարմանում եմ ինչ գործ ունի C++ դպրոցում ու ընդհանրապես ինչի են պարտադրում դպրոցականին ծրագրավորում?
միայն տարրական համակարգչային գիտելիքներ են պետք ու վերջ
Համամիտ չեմ: Քանի որ ինֆորմատիկայի ոլորտը գլոբալ բաժանվում է երկու մասին` ծրագրային ապահովման ստեղծում և կիրառում, ապա անհրաժեշտ են տարրական գիտելիքներ երկու մասից էլ: Թե չեմ մեկն ու մեկից բան չսովորեցնելը հավասարազոր է նրան, որ ասենք մաթեմատիկայի պարագայում հանրահաշիվ անցնես, իսկ երկրաչափություն` ոչ: կամ մենակ անօրգանական քիմիա անցնեն, իսկ օրգանականը` ոչ:
Տվյալ պարագայում C++-ի դասական տարրական խնդիրները, ինչպես նաև ստանդարտ պարզագույն ալգորիթմերն ուղղակի անհրաժեշտ են դպրոցականին, որպեսզի կարողանա պատկերացում կազմել ոչ միայն իր ունակություների, այլև հակումների վերաբերյալ: Հետո ստեղ մի բան էլ կա: որպես կանոն տարրական համակարգչային գիտելիքները երեխաները ստանում են սեփական տանը համակարգչի առջև նստած: Ինչ էլ չգիտեն ֆորուներում են կարդում ու հարցնում :)

Varzor
15.10.2012, 18:12
ու արդեն երկրորդ անգամ :)
էտ անտեր ստատիկ մասիվի չափը պետքա հաստատուն լինի, անփոփոխ ու տենց :))
Ու հենց նախորդ անգամից էլ "պլեճ" եմ արել :))
Այո, պետք է մասիվի չափը հաստատուն լինի, բայց պարտադիր չի, որ անփոփոխ լինի: Ի դեպ կարող է սկզբնապես նույնիսկ չափը հայտարարված չլինել: բայց դա արդեն ուրիշ թեմա է:

DavitH
15.10.2012, 21:06
Համամիտ չեմ: Քանի որ ինֆորմատիկայի ոլորտը գլոբալ բաժանվում է երկու մասին` ծրագրային ապահովման ստեղծում և կիրառում, ապա անհրաժեշտ են տարրական գիտելիքներ երկու մասից էլ: Թե չեմ մեկն ու մեկից բան չսովորեցնելը հավասարազոր է նրան, որ ասենք մաթեմատիկայի պարագայում հանրահաշիվ անցնես, իսկ երկրաչափություն` ոչ: կամ մենակ անօրգանական քիմիա անցնեն, իսկ օրգանականը` ոչ:
Տվյալ պարագայում C++-ի դասական տարրական խնդիրները, ինչպես նաև ստանդարտ պարզագույն ալգորիթմերն ուղղակի անհրաժեշտ են դպրոցականին, որպեսզի կարողանա պատկերացում կազմել ոչ միայն իր ունակություների, այլև հակումների վերաբերյալ: Հետո ստեղ մի բան էլ կա: որպես կանոն տարրական համակարգչային գիտելիքները երեխաները ստանում են սեփական տանը համակարգչի առջև նստած: Ինչ էլ չգիտեն ֆորուներում են կարդում ու հարցնում :)

թեմայից շեղվում ենք բայց ոչինչ:)

Այ ստեղ էլ ես համամիտ չեմ քո հետ Մաթեմատիկան մի համեմատի ծրագրավորման հետ դրանք տարբեր բաներ են ու տարբեր նշանակություն ունեն
մաթեմատիկան էտ բոլորին ա պետք իսկ c++ ոչ բոլորին

Ruzanna Stepanyan
15.10.2012, 22:54
ու արդեն երկրորդ անգամ :)

էտ անտեր ստատիկ մասիվի չափը պետքա հաստատուն լինի, անփոփոխ ու տենց :))


շատ լավ, շնորհակալ եմ, բայց մի զայրացեք պարոն գայլ ձեզնից ցածր եմ քանի քայլ :D

Ruzanna Stepanyan
15.10.2012, 22:55
Զարմանում եմ ինչ գործ ունի C++ դպրոցում ու ընդհանրապես ինչի են պարտադրում դպրոցականին ծրագրավորում?
միայն տարրական համակարգչային գիտելիքներ են պետք ու վերջ

բոլորը չեն անցնում , անցնում են միայն բնագիտամաթեմատիկական հոսքի երեխաները

Ruzanna Stepanyan
15.10.2012, 23:01
int n, i, j;
double x[n], tmp;

հաստատ այ սրա վրա ա սխալ տվել :)

բայց ես x[n]-ի փոխարեն գրեցի x[10], բայց էլի չի ստացվում

zulu
16.10.2012, 02:01
for (j=i; j=1; j--)
{
x[j]=x[j-1];
}


for-ի մեջ էլ պետք ա ստուգել j>=1, այլ ոչ թե j=1

Sent from my GT-P7310 using Tapatalk HD

Ruzanna Stepanyan
16.10.2012, 09:53
for-ի մեջ էլ պետք ա ստուգել j>=1, այլ ոչ թե j=1

Sent from my GT-P7310 using Tapatalk HD


Մեկա չի ստացվում :(

DavitH
16.10.2012, 10:00
Խնդրում եմ մի հատ կբացատրեք այս խնդիրը ոնց լուծեմ, մենակ թե խնդրում եմ քայլերով, եթե հնարավոր է: Նախապես շնորհակալ եմ:

n հատ տարր պարունակող միաչափ զանգվածը կարգավորել ըստ նվազման:

Ավելի կարճ ու հասկանալի լուծում

ինչքան հիշում եմ պղպջակների ալգորիթմ ա կոչվում :)


#include <iostream>
using namespace std;
void main()
{
int i, j;
double x[10], tmp;


//զանգվածի ներմուծում
for (i=0; i<10; i++)
{
cin>>x[i];
cout<<endl;
}
for (i=1; i<n; i++)
{
for(j=i+1;j<n;j++)
{
if(x[i] < x[j])
{
tmp = a[j];
x[j]= x[i];
x[i]= tmp;
}
}
}



//հիմա տպենք ու տեսնենք որ նվազման կարգով ա
for (i=0; i<10; i++)
{
cout << x[i] << " ";

}
}

Varzor
16.10.2012, 12:56
թեմայից շեղվում ենք բայց ոչինչ:)
Այ ստեղ էլ ես համամիտ չեմ քո հետ Մաթեմատիկան մի համեմատի ծրագրավորման հետ դրանք տարբեր բաներ են ու տարբեր նշանակություն ունեն
մաթեմատիկան էտ բոլորին ա պետք իսկ c++ ոչ բոլորին
Հաստատ քեզ հետ համամիտ չեմ: Միգուցե բոլորին պետք է թվաբանությունը, բայց ոչ մաթեմատիկան` շատ լայն հասկացողություն է:
Նույն կերպ բոլորին պետք չի կենսաբանությունը կամ քիմիան, կամ ֆիզիկան, օտար լեզուն, ինչու չէ նաև հայոց լեզուն: Բայց անցնում են չէ դրանք?
Միջնակարգ կրթական հաստատությունը ակադեմիական կրթության առումով լուծում է 3 խնդիր.
1. Տարրական գիտելիքների ուսուցանում: Գիտելիքներ, որոնք անհրաժեշտ են քաղաքացիներին մինիմալ առումով` թվաբանություն, տառա և գրաճանաչություն:
2. Ընդհանուր կրթական ոլորտի վերաբերյալ համառոտ տեղեկացվածություն և համառոտ գիտելիքների ձեռքբերում:
3. Ելնելով ընդհանուր տեղեկացվածության մակարդակից կողմնորոշում և նախապատրաստում ԲՈՒՀ-ական կամ մասնագիտական այլ կրթություն ստանալու համար:

Ոնց տեսնում են 2-րդ խնդիրը ամենածավալունն է ու կախված է ժամանակի և միջավայրի պահանջներից: Ու էս առումով դպրոցում C++ դաավանդումը կոնկրետ ինձ համար լիովին համարժեք է անօրգանական քիմիայի կամ ասենք աստղագիտության դասավանդմանը` ծրագրավորումը նույնպես մասնագիտություն է և գիտության մի ճյուղ, որի մասին ընդհանուր և հիմնարար գտելիքներ պետք է ապահովի դպրոցը:
Բնականաբար այդ առարկան, որպես ավելի բարդ և կոնցեպտուալ, պետք է անցնեն բարձր դասարաններում, և ցանկալի է ըստ աշակերտի ընտրության: Որովհետև եթե աշակերտը մաթեմատիկայից կաղում է, ապա նրան տանջել ծրագրավորումով ուղղակի մարդկային մոտեցում չէ :))

Varzor
16.10.2012, 13:05
Ավելի կարճ ու հասկանալի լուծում

ինչքան հիշում եմ պղպջակների ալգորիթմ ա կոչվում :)


#include <iostream>
using namespace std;
void main()
{
int i, j;
double x[10], tmp;


//զանգվածի ներմուծում
for (i=0; i<10; i++)
{
cin>>x[i];
cout<<endl;
}
for (i=1; i<n; i++)
{
for(j=i+1;j<n;j++)
{
if(x[i] < x[j])
{
tmp = a[j];
x[j]= x[i];
x[i]= tmp;
}
}
}



//հիմա տպենք ու տեսնենք որ նվազման կարգով ա
for (i=0; i<10; i++)
{
cout << x[i] << " ";

}
}

Լավ լուծում է, կոդը գրելու տեսանկյունից կարճ է, բայց քայլերի տեսանկյունից կարճ չէ` համեմատությունների քանակը շատ է:
Համ էլ մի երկու վրիպում կա.
1. n-ի ներմուծումը չկա
2. քանի որ for (i=1; i<n; i++), ապա for(j=i+1;j<n;j++)` համեմատությունը սկսվում է արդեն 2-րդ տարրից ու հետևաբար առաջին տարրի ստուգում չի կատարվում
3. tmp = a[j] - a զանգվածը հայտարարված չէ:

Ruzanna Stepanyan
16.10.2012, 20:43
Ես լուծեցի հետևյալ ձևով.

using namespace std;
void main()
{
int x[10], i, j, k, n, max;
cout<<"mutqagreq zangavtsi chapy"<<endl;
do{cin>>n;}while(1>n||n>10);
for(i=0; i<n; i++)
{
cout<<"x["<<i<<"]=";
cin>>x[i];
}
for(i=0; i<n-1; i++)
{
max=x[i];
k=i;
for(j=i+1; j<n; j++)
if(x[j]>max)
{
max=x[j];
k=j;
}
x[k]=x[i];
x[i]=max;
}
for(i=0; i<n; i++)
cout<<x[i];
}

DavitH
17.10.2012, 09:44
Լավ լուծում է, կոդը գրելու տեսանկյունից կարճ է, բայց քայլերի տեսանկյունից կարճ չէ` համեմատությունների քանակը շատ է:
Համ էլ մի երկու վրիպում կա.
1. n-ի ներմուծումը չկա
2. քանի որ for (i=1; i<n; i++), ապա for(j=i+1;j<n;j++)` համեմատությունը սկսվում է արդեն 2-րդ տարրից ու հետևաբար առաջին տարրի ստուգում չի կատարվում
3. tmp = a[j] - a զանգվածը հայտարարված չէ:

ինձ թվում ա պարզ պիտի լինի որ էտ a չպիտի լիներ այլ x
երկեորդն ել ինչի եմ տարրը առաջինից համեմատում ինձ պետք չի տենց դրա համար էլ for(j=i+1;j<n;j++) սենց եմ գրել
n-ի համար էլ մոռացել եմ հանեմ պիտի 10 լինի
էս ստից վրիպակները կան որորվհետև միանգամից ստեղ եմ գրում կամպիլյացիա չեմ անում

համենայն դեպս ես էս լուծումն եմ ընդունում քոնը շատ խուճուճ ա ու ոնց որ թե երկուսի կարգն ել n քառակուսի ա

DavitH
17.10.2012, 09:49
Ես լուծեցի հետևյալ ձևով.

using namespace std;
void main()
{
int x[10], i, j, k, n, max;
cout<<"mutqagreq zangavtsi chapy"<<endl;
do{cin>>n;}while(1>n||n>10);
for(i=0; i<n; i++)
{
cout<<"x["<<i<<"]=";
cin>>x[i];
}
for(i=0; i<n-1; i++)
{
max=x[i];
k=i;
for(j=i+1; j<n; j++)
if(x[j]>max)
{
max=x[j];
k=j;
}
x[k]=x[i];
x[i]=max;
}
for(i=0; i<n; i++)
cout<<x[i];
}

լուծման միտքը նույնն ա ինչ որ իմ մոտ

էս տիպի խնդիրները սկսնակ ծրագրավորողների համար դասական օրինակներ են

ձեզ խորհուրդ կտամ ուսումնասիրեք, եթե իհարկե արդեն չեք կարդացել, «Как программировать на C++ - Дейтел Х., Дейтел П.» գրիքը

Varzor
17.10.2012, 10:04
Ես լուծեցի հետևյալ ձևով.

using namespace std;
void main()
{
int x[10], i, j, k, n, max;
cout<<"mutqagreq zangavtsi chapy"<<endl;
do{cin>>n;}while(1>n||n>10);
for(i=0; i<n; i++)
{
cout<<"x["<<i<<"]=";
cin>>x[i];
}
for(i=0; i<n-1; i++)
{
max=x[i];
k=i;
for(j=i+1; j<n; j++)
if(x[j]>max)
{
max=x[j];
k=j;
}
x[k]=x[i];
x[i]=max;
}
for(i=0; i<n; i++)
cout<<x[i];
}
Նույն ալգորիթմն է, ինչ DavitH-ի առաջարկածը, ուղղակի մի քանի հրաման ավել, որոնք որ կարելի է չգրել: Բացի այդ փոփոխականների նկարագրությունը չի համապատասանում խնդրի դրվածքին` խնդրի պայմանում նշված չէ, որ զանգվածի տարրերը ամբողջ թվեր են:
Մասնավորապես տարրերի տեղափոխությունը կատարվում է պայմանից դուրս, ապա կատարվում են ավելորդ քայլեր:
Նույն ծրագիրը կարելի է որոշ ձևափոխությունների ենթարկել և օպտիմիզացնել Ու էդ դեպքում կստացվի DavitH-ի գրած կոդը, որոշ սուբյեկտիվ տարբերություններով:

Varzor
17.10.2012, 10:17
ինձ թվում ա պարզ պիտի լինի որ էտ a չպիտի լիներ այլ x
երկեորդն ել ինչի եմ տարրը առաջինից համեմատում ինձ պետք չի տենց դրա համար էլ for(j=i+1;j<n;j++) սենց եմ գրել
n-ի համար էլ մոռացել եմ հանեմ պիտի 10 լինի
էս ստից վրիպակները կան որորվհետև միանգամից ստեղ եմ գրում կամպիլյացիա չեմ անում
համենայն դեպս ես էս լուծումն եմ ընդունում քոնը շատ խուճուճ ա ու ոնց որ թե երկուսի կարգն ել n քառակուսի ա
Դե բնականաբար առանց կոմպիլյացիայի գրելուց, մանավանդ որ ռեգուլյար էդ գործով չես զբաղվում, սխալներն անխուսափելի են :)
Ախր ոնց էս ասում, որ առաջինից պետք չի? Չպիտի առաջին տարրը համեմատես 2-րդ ի հետ? Քո ասածով բոլորը կարող ես տեղերով փոխել, բացի առաջինից: իսկ ինչ գիտես, որ առաջինը ամենամեծ տարրն է ու ճիշտ իր տեղում է գտնվում?
Իսկ ինչ վերաբերվում է իմ տարբերակի "խուճուճ" լինելուն, ապա էդ տարբերակը մի քանի նախադասությամբ նկարագրել եմ :esim ու հեչ էլ խուճուճ չի, բայց պրոցեսորի կողմից ավելի արագ պիտի կատարվի, քանի որ քո տված ալգորիթմում զանգվածի ամեն տարր համեմատվում է իրեն հաջորդող բոլոր տարրերի հետ, իսկ իմ բերած տարբերակում զանգվածի ամեն տարր համեմատվում է միայն առաջին տարրի և իր նախորդ տարրի հետ:
Եթե մենակ պայմամնների ստուգման քանակը հաշվենք, ապա իմ մոտ դա վատագույն դեպքում 2n է, սիկ քո տարբերակում n*(n+1)/2~n2/2: Մեծ n-ների պարագայում ուղղակի անհամեմատելի է` 2n<<n2/2
Բայց ասեմ, որ քո բերած ալգորիթմը համարվում է դասականը, իսկ իմ բերած տարբերակը դասական չի, ուղղակի ռեսուրսների տեսանկյունից օպտիմիզացված է ;)

DavitH
17.10.2012, 16:59
Դե բնականաբար առանց կոմպիլյացիայի գրելուց, մանավանդ որ ռեգուլյար էդ գործով չես զբաղվում, սխալներն անխուսափելի են :)
Ախր ոնց էս ասում, որ առաջինից պետք չի? Չպիտի առաջին տարրը համեմատես 2-րդ ի հետ? Քո ասածով բոլորը կարող ես տեղերով փոխել, բացի առաջինից: իսկ ինչ գիտես, որ առաջինը ամենամեծ տարրն է ու ճիշտ իր տեղում է գտնվում?
Իսկ ինչ վերաբերվում է իմ տարբերակի "խուճուճ" լինելուն, ապա էդ տարբերակը մի քանի նախադասությամբ նկարագրել եմ :esim ու հեչ էլ խուճուճ չի, բայց պրոցեսորի կողմից ավելի արագ պիտի կատարվի, քանի որ քո տված ալգորիթմում զանգվածի ամեն տարր համեմատվում է իրեն հաջորդող բոլոր տարրերի հետ, իսկ իմ բերած տարբերակում զանգվածի ամեն տարր համեմատվում է միայն առաջին տարրի և իր նախորդ տարրի հետ:
Եթե մենակ պայմամնների ստուգման քանակը հաշվենք, ապա իմ մոտ դա վատագույն դեպքում 2n է, սիկ քո տարբերակում n*(n+1)/2~n2/2: Մեծ n-ների պարագայում ուղղակի անհամեմատելի է` 2n<<n2/2
Բայց ասեմ, որ քո բերած ալգորիթմը համարվում է դասականը, իսկ իմ բերած տարբերակը դասական չի, ուղղակի ռեսուրսների տեսանկյունից օպտիմիզացված է ;)

for (i=1; i<n; i++)
{
for(j=i+1;j<n;j++)
{
if(x[i] < x[j])
{
tmp = a[j];
x[j]= x[i];
x[i]= tmp;
}
}
}

էէէ ախր ուշադիր չես եղել է
տես վերցնում եմ ամենասկզբից
առաջինըx[i] ու երկրորդը x[j]
դրա համար j -ն սկսում եմ i+1 որ իքը իրա հետ չհամեմատեմ


գիտեմ որ դասական տարբերակ ա դրա համար միշտ առաջինը էս եմ ասում :)) արագության հարցում էլ դեմ չեմ ճիշտ ես ասում քոնը արագ ա

Ruzanna Stepanyan
17.10.2012, 19:32
Հարգելիներս,

շատ շնորհակալ եմ, որ որ արձագանքում եք ու օգնում եք ինձ, բայց իմ ինքնագործունեության արդյուքում գրած խնդրի թերությունների պատճառը այն էր, որ դուք շատ սիրուն քննակրկում եք ծավալել իմ խնդրի շուրջ, բայց վերջնական ինչ որ տարբերակ, որը կաշխատի ու ինձ կօգնի, էդպես էլ չտվեցիք: Իհարկե շնորհակալ եմ, որ օգնում եք, կարող էիք էսքանն էլ չանել:

Չնայած ես որոշել եմ հանուն իմ աշակերտների խորանալ ու լավ սովորել :), բայց երբ գրում եք բացատրությունը, խնդրում եմ խղճացեք ինձ, ու մի քիչ հասարակ տերմիններով բացատրեք, եթե իհարկե ժամանակ ունեք կամ ուզում եք ինձ օգնել: :)

DavitH
17.10.2012, 22:26
Հարգելիներս,

շատ շնորհակալ եմ, որ որ արձագանքում եք ու օգնում եք ինձ, բայց իմ ինքնագործունեության արդյուքում գրած խնդրի թերությունների պատճառը այն էր, որ դուք շատ սիրուն քննակրկում եք ծավալել իմ խնդրի շուրջ, բայց վերջնական ինչ որ տարբերակ, որը կաշխատի ու ինձ կօգնի, էդպես էլ չտվեցիք: Իհարկե շնորհակալ եմ, որ օգնում եք, կարող էիք էսքանն էլ չանել:

Չնայած ես որոշել եմ հանուն իմ աշակերտների խորանալ ու լավ սովորել :), բայց երբ գրում եք բացատրությունը, խնդրում եմ խղճացեք ինձ, ու մի քիչ հասարակ տերմիններով բացատրեք, եթե իհարկե ժամանակ ունեք կամ ուզում եք ինձ օգնել: :)

հենց հիմա հատուկ Ձեր ու Ձեր աշակերտների համար չեմ ալարի ու կգրեմ ու կուղարկեմ 100 % աշխատող տարբերակ :)

DavitH
17.10.2012, 22:37
#include <iostream>

using namespace std;

void main()
{
int i, j;
double x[10], tmp;


//զանգվածի ներմուծում
for (i=0; i<10; i++)
{
cin >> x[i];
cout << endl;
}

for (i=0; i<10; i++)
{
for(j=i+1;j<10;j++)
{
if(x[i] < x[j])
{
tmp = x[j];
x[j]= x[i];
x[i]= tmp;
}
}

}

for (i=0; i<10; i++)
{
cout << x[i] << " ";
}

}

Varzor
18.10.2012, 19:56
for (i=1; i<n; i++)
{
for(j=i+1;j<n;j++)
{
if(x[i] < x[j])
{
tmp = a[j];
x[j]= x[i];
x[i]= tmp;
}
}
}

էէէ ախր ուշադիր չես եղել է
տես վերցնում եմ ամենասկզբից
առաջինըx[i] ու երկրորդը x[j]
դրա համար j -ն սկսում եմ i+1 որ իքը իրա հետ չհամեմատեմ


գիտեմ որ դասական տարբերակ ա դրա համար միշտ առաջինը էս եմ ասում :)) արագության հարցում էլ դեմ չեմ ճիշտ ես ասում քոնը արագ ա
Եղբայր, C++ում զանգվածնեը համարակալվում են 0-ից, հետևաբար i-ի ցիկլը պիտի սկսես 0-ից, որպեսզի յ=i+1 -ի պարագայում x[i] < x[j] պայմանի կատարման դեպքում 0 և 1 ինդեքսով տարրերը տեղերով փոխես ;)
Ու ինչպես տեսնում եմ արդեն գլխի ես ընկել, որ տենց պիտի լինի: Դրա ապացույցն է կոդի նոր տարբերակը :)

Ruzanna Stepanyan
18.10.2012, 20:41
#include <iostream>



using namespace std;

void main()
{
int i, j;
double x[10], tmp;


//զանգվածի ներմուծում
for (i=0; i<10; i++)
{
cin >> x[i];
cout << endl;
}

for (i=0; i<10; i++)
{
for(j=i+1;j<10;j++)
{
if(x[i] < x[j])
{
tmp = x[j];
x[j]= x[i];
x[i]= tmp;
}
}

}

for (i=0; i<10; i++)
{
cout << x[i] << " ";
}

}

DavitH ջան շատ շնորհակալ եմ: :)Բայց նեղություն քաշեք, ինձ բացատրեք, բոլդ արած մասը տողերով, թե էդ j-ն ինչի համար է և այլն: Նախապես շատ մերսի:

Varzor
18.10.2012, 20:52
DavitH ջան շատ շնորհակալ եմ: :)Բայց նեղություն քաշեք, ինձ բացատրեք, բոլդ արած մասը տողերով, թե էդ j-ն ինչի համար է և այլն: Նախապես շատ մերսի:
Եթե DavitH-ն չի նեղանա, ապա ես կբացատրեմ:
j-ով ցկլը կազմվում է նրա համար, որպեսզի զանգվածի տարրը համեատվի իրեն հաջորդող բոլոր տարրերի հետ: Եթե հաջորդող տարրերից որևէ մեկը ավելի մեծ է, ապա այդ տարրի հետ տեղերով փոխում ենք, որպեսզի ավելի մեծ տարրը ավելի առաջ գա:
Բնականաբար, քանի որ զանգվածի բոլոր տարրերը իրար հետ համեմատվում են, ապա ամեն j-ով ցիկլի ավարտից հետո i-երորդ տարրի արժեքը ամենամեծն է լինում i+1-ից մինչև n-1 տարրերի մեջ և փոքր է լինում i-1 տարրից, ինչն էլ ապահովում է, որ տարրերը նվազման կարգով դասավորված լինեն:

Ըստ էության, եթե պահանջվեր տարրերը դասավորել աճման կարգով, ապա բավական է փոխել պայմանի տողում նշանը և խնդիրը կլուծվեր:

DavitH
19.10.2012, 10:04
Եթե DavitH-ն չի նեղանա, ապա ես կբացատրեմ:
j-ով ցկլը կազմվում է նրա համար, որպեսզի զանգվածի տարրը համեատվի իրեն հաջորդող բոլոր տարրերի հետ: Եթե հաջորդող տարրերից որևէ մեկը ավելի մեծ է, ապա այդ տարրի հետ տեղերով փոխում ենք, որպեսզի ավելի մեծ տարրը ավելի առաջ գա:
Բնականաբար, քանի որ զանգվածի բոլոր տարրերը իրար հետ համեմատվում են, ապա ամեն j-ով ցիկլի ավարտից հետո i-երորդ տարրի արժեքը ամենամեծն է լինում i+1-ից մինչև n-1 տարրերի մեջ և փոքր է լինում i-1 տարրից, ինչն էլ ապահովում է, որ տարրերը նվազման կարգով դասավորված լինեն:

Ըստ էության, եթե պահանջվեր տարրերը դասավորել աճման կարգով, ապա բավական է փոխել պայմանի տողում նշանը և խնդիրը կլուծվեր:

Չէ չեմ նեղանա :))
են i=1-ի համար էլ ճիշտ ես, էտ դրա պատճառը անուշադիր գրելն ա :))

Ruzanna Stepanyan
19.10.2012, 20:45
Դե լավ է, բոլորս էլ գոհ մնացինք :) Ապրեք շատ, ինձ օգնելու համար:

Բայց ես մտածում եմ ճիշտ կլինի մասնագետի մոտ պարապեմ, որ ավելի խորությամբ սովորեմ, որպեսզի աշակերտներիս պատրաստեմ օլիմպիադայի:

DavitH
19.10.2012, 23:11
Դե լավ է, բոլորս էլ գոհ մնացինք :) Ապրեք շատ, ինձ օգնելու համար:

Բայց ես մտածում եմ ճիշտ կլինի մասնագետի մոտ պարապեմ, որ ավելի խորությամբ սովորեմ, որպեսզի աշակերտներիս պատրաստեմ օլիմպիադայի:

ավելի լավ ա ուղակի վերցնեք C++-ի գիրքը ու կարդաք
ինձ թվում ա ինքնուրույն էլ կարող էք սովորել մանավանդ, որ մի քիչ հիմք ունեք

Ruzanna Stepanyan
29.10.2012, 23:05
Խնդիրս չի ստացվում, խնդրում եմ օգնեք.

Խնդիր
Տրված են հարթության երեք կետերի կոորդինատները: Հաշվել և արտածել այն կետի կոորդինատների գումարը, որն ամենից մոտ է գտնվում կոորդինատների սկզբնակետին:

#include <iostream>
#include <math.h>
using namespace std;
void main()
{
double x1, y1, x2, y2, x3, y3, d1, d2, d3, min, k, h;
cout<<"x1="; cin>>x1;
cout<<"y1="; cin>>y1;
cout<<"x2="; cin>>x2;
cout<<"y2="; cin>>y2;
cout<<"x3="; cin>>x3;
cout<<"y3="; cin>>y3;
d1=sqrt((pow(x1,2))+(pow(y1,2)));
d2=sqrt((pow(x2,2))+(pow(y2,2)));
d3=sqrt((pow(x3,2))+(pow(y3,2)));
if(d1<d2)
{
min=d1;
h=1;
}
else
{
min=d2;
h=2;
}
if(d3<min)
{
min=d3;
h=3;
}
if(h=1)
{
k=x1+y1;

}
else
if(h=2)
{
k=x2+y2;

}
else
k=x3+y3;
cout<<"k="<<k<<endl;
}

MSGM
29.10.2012, 23:51
if(h=1)
{
k=x1+y1;

}
else
if(h=2)
{
k=x2+y2;

}
else
k=x3+y3;

Պետք է լինի ==

zulu
29.10.2012, 23:52
Խնդիրս չի ստացվում, խնդրում եմ օգնեք.

Խնդիր
Տրված են հարթության երեք կետերի կոորդինատները: Հաշվել և արտածել այն կետի կոորդինատների գումարը, որն ամենից մոտ է գտնվում կոորդինատների սկզբնակետին:

#include <iostream>
#include <math.h>
using namespace std;
void main()
{
double x1, y1, x2, y2, x3, y3, d1, d2, d3, min, k, h;
cout<<"x1="; cin>>x1;
cout<<"y1="; cin>>y1;
cout<<"x2="; cin>>x2;
cout<<"y2="; cin>>y2;
cout<<"x3="; cin>>x3;
cout<<"y3="; cin>>y3;
d1=sqrt((pow(x1,2))+(pow(y1,2)));
d2=sqrt((pow(x2,2))+(pow(y2,2)));
d3=sqrt((pow(x3,2))+(pow(y3,2)));
if(d1<d2)
{
min=d1;
h=1;
}
else
{
min=d2;
h=2;
}
if(d3<min)
{
min=d3;
h=3;
}
if(h=1)
{
k=x1+y1;

}
else
if(h=2)
{
k=x2+y2;

}
else
k=x3+y3;
cout<<"k="<<k<<endl;
}

Պայմանների ստուգումը ճիշտ չի. ոչ թե if(h=1) եւ if(h=2), այլ if(h==1) եւ if(h==2)։

Sent from my GT-P7310 using Tapatalk HD

Ruzanna Stepanyan
10.11.2012, 20:56
Խնդրում եմ ասեք, թե ինչն եմ սխալ արել այս խնդրում, որ երկու պատասխան է ստացվում:

Հաշվել և արտածել այն ամենամեծ քառնիշ թիվը, որը հանդիսանում է 3-ի աստիճան:

#include <iostream>
#include <math.h>
using namespace std;
void main()
{
int i;
double k;
for(i=9999; i>=1000; i--)
{
for(k=0; k<=100; k++)
{
if((pow(3,k)==i))
{
cout<<"i="<<i<<endl;
break;
}
}
}
}

MSGM
10.11.2012, 22:21
#include <iostream>
#include <math.h>
using namespace std;
void main()
{
int i;
double k;
bool s=false;
for(i=9999; i>=1000; i--)
{
for(k=0; k<=100; k++)
{
if((pow(3,k)==i))
{
cout<<"i="<<i<<endl;
s=true;
break;
}
}
if (s) break;
}
}


Առաջարկում եմ ավելի կարճ լուծելու ձև


#include <iostream>
using namespace std;
void main()
{
int ans = 1;
while (ans * 3 < 10000) ans *= 3;
cout << ans << endl;
}

Ruzanna Stepanyan
10.11.2012, 22:55
#include <iostream>
#include <math.h>
using namespace std;
void main()
{
int i;
double k;
bool s=false;
for(i=9999; i>=1000; i--)
{
for(k=0; k<=100; k++)
{
if((pow(3,k)==i))
{
cout<<"i="<<i<<endl;
s=true;
break;
}
}
if (s) break;
}
}


Առաջարկում եմ ավելի կարճ լուծելու ձև


#include <iostream>
using namespace std;
void main()
{
int ans = 1;
while (ans * 3 < 10000) ans *= 3;
cout << ans << endl;
}


շնորհակալ եմ շատ:

Ձեր առաջարկած տարբերակը շատ հավանեցի, բայց մի հարց տամ, չեմ կարող while (ans * 3 < 10000)-ի փոխարեն գրել while (ans < 10000)


մեկ էլ խնդրում եմ ձեր կարմիր գրածները բացատրեք, դրանք ինձ շատ անծանոթ են :)

MSGM
11.11.2012, 10:12
Ձեր առաջարկած տարբերակը շատ հավանեցի, բայց մի հարց տամ, չեմ կարող while (ans * 3 < 10000)-ի փոխարեն գրել while (ans < 10000)


Եթե պայմանը while (ans < 10000) լինի, ապա ans *= 3 գործողությունը կկատարվի նաև ans-ի՝ փնտրվող 3-ի աստիճանին հավասար լինելու դեպքում, ու ans-ը կդառնա 10000-ից մեծ թիվ: Դրա փոխարեն կարելի է գրել.


do
{
ans *= 3;
} while ( ans < 10000);




մեկ էլ խնդրում եմ ձեր կարմիր գրածները բացատրեք, դրանք ինձ շատ անծանոթ են :)
Քանի որ երկու ներդրված ցիկլ կա, ներսի ցիկլում break; անելը ընդհատում է միայն ներսի ցիկլը, դրա համար առաջին ավելացրած տողում հայտարարում եմ փոփոխական, որը false է, եթե պատասխանը դեռ չի գտնվել, ու true՝ հակառակ դեպքում: Երբ պատասխանը գտնվում է, երկրորդ ավելացված տողով փոփոխականը true եմ դարձնում, իսկ արտաքին ցիկլում՝ ներքինի ավարտից հետո, ստուգում եմ. եթե պատասխանը գտնվել է, ապա ընդհատում եմ արտաքին ցիկլը, եթե ոչ ցիկլը շարունակվում է:

Ruzanna Stepanyan
11.11.2012, 22:53
do
{
ans *= 3;
} while ( ans < 10000);



Շնորհակալ եմ բացատրության համար, բայց ձեր գրած այս տրաբերակի պատասխանը սխալ է ստացվում, այսինքն` 19683 :

MSGM
12.11.2012, 17:25
Շնորհակալ եմ բացատրության համար, բայց ձեր գրած այս տրաբերակի պատասխանը սխալ է ստացվում, այսինքն` 19683 :
Շփոթել եմ, նույն բանն է տեղի ունենում, ինչ որ while(){}-ով տարբերակում: Չգիտեմ ինչի ինձ թվացել էր, որ եթե do while-ով գրեմ, ans < 10000-ով կլինի:

ITFox
30.04.2013, 14:43
Ժողովուրդ մի անհասկանալի խնդիր կա, ով կարող է իմանալ ինչից է, կյանքիս մեջ հլա եսպիսի տափակ խնդրի չեմ հանդիպել:
ուրեմն եսպիսի խնդիր կապված while օպերատորի հետ:
Երբ գրում եմ ծրագիր որ որևէ գործողություն անվերջ կատարի, while-ի մեջ սահմանում եմ մի պայման որ միշտ ճիշտ է, առաջ առանց խնդրի աշխատում էր իսկ հիմա խնդիր կա: ուրեմն սենց, ենթադրենք ուզում եմ եսպիսի մի բան ասենք X և Y թվերը գումարի իրար, այսինքն ներմուծեմ արժեքներն կատարի գումարում և գումարում կատարելուց հետո հնարավորություն տա որ կրկին ներմուծեմ: Նման դեպքերում այսպես էի անում

while(1>0)
{ ծրագրի կոդ }
return 0;

իսկ հիմա որ while-ի մեջ տենց եմ գրում ասենք 1>0 կամ 0=0 ոչ մի տարբերություն չի լինում while գրել եմ թե չէ, գործողությունն կատարումա մեկ անգամ ու վերջ: պիտի սենց անեմ որ աշխատի

int cicle=1;
while(cicle>0)
{ ծրագրի կոդ }
return 0;

չեմ հասկանում թե ինչից կլինի որ առաջին դեպքում չի ստացվում, բայց ես միշտ առաջին տարբերակով եմ աշխատել, վերջերս եմ նկատել որ ետպիսի խնդիր կա: Որևէ մեկը կարող է ասել ինչից կլինի

ITFox
30.04.2013, 14:51
իհարկե խոսքն ետ գումարման ծրագրին չի, դա ուղղակի օրինակ ասեցի. առհասարակ while-ի ետ տարօրինակ "պահվածքն" է անբացատրելի :(


while (1>0)
{ ծրակրի կոդ }
return 0;
-------------------------
int cicle=1;
while (cicle>0)
{ ծրակրի կոդ }
return 0;


Առաջին հայացքից նույն բաներն են: Բայց արի ու տես որ առաջի դեպքում կոպիտ ասաց 1>0 չի հասկանում

One_Way_Ticket
01.05.2013, 02:53
Չաշխատող ծրագրի կոդը եթե ամբողջությամբ տեղադրեք, կօգնենք:

Արամ
05.08.2013, 23:54
Ժողովուրդ մի անհասկանալի խնդիր կա, ով կարող է իմանալ ինչից է, կյանքիս մեջ հլա եսպիսի տափակ խնդրի չեմ հանդիպել:
ուրեմն եսպիսի խնդիր կապված while օպերատորի հետ:
Երբ գրում եմ ծրագիր որ որևէ գործողություն անվերջ կատարի, while-ի մեջ սահմանում եմ մի պայման որ միշտ ճիշտ է, առաջ առանց խնդրի աշխատում էր իսկ հիմա խնդիր կա: ուրեմն սենց, ենթադրենք ուզում եմ եսպիսի մի բան ասենք X և Y թվերը գումարի իրար, այսինքն ներմուծեմ արժեքներն կատարի գումարում և գումարում կատարելուց հետո հնարավորություն տա որ կրկին ներմուծեմ: Նման դեպքերում այսպես էի անում

while(1>0)
{ ծրագրի կոդ }
return 0;

իսկ հիմա որ while-ի մեջ տենց եմ գրում ասենք 1>0 կամ 0=0 ոչ մի տարբերություն չի լինում while գրել եմ թե չէ, գործողությունն կատարումա մեկ անգամ ու վերջ: պիտի սենց անեմ որ աշխատի

int cicle=1;
while(cicle>0)
{ ծրագրի կոդ }
return 0;

չեմ հասկանում թե ինչից կլինի որ առաջին դեպքում չի ստացվում, բայց ես միշտ առաջին տարբերակով եմ աշխատել, վերջերս եմ նկատել որ ետպիսի խնդիր կա: Որևէ մեկը կարող է ասել ինչից կլինի

void AnverjGumarum ()
{
int x, y;
while(1>0)
{
cin >> x >> y;
cout << x+y << endl;
}
}
Այս ֆունկցիան առանց խնդիր աշխատում է, միգուցե {ծրագրիդ կոդ} -ի մեջ սխալ կա՞: Իսկ ընդհանրապես ավելի գրագետ է գրել այսպես

while(1)
{
}

Արամ
30.08.2013, 21:40
Կարտերի կալոդը ուզում եմ երկչափ զանգվածի մեջ պահեմ, դրանից ավելի օպտիմալ տարբերակ կա՞

Արամ
11.09.2013, 08:30
Մեկը կա, որ ինձ կբացատրի, թե rand() ֆունկցիան, ո՞նց ա աշխատում:

Արամ
18.10.2013, 16:10
Մեկը կա, որ ինձ կբացատրի, թե rand() ֆունկցիան, ո՞նց ա աշխատում:

Էլ ինձ մենակ էք թողել :(

armen9494
20.10.2013, 20:27
Մեկը կա, որ ինձ կբացատրի, թե rand() ֆունկցիան, ո՞նց ա աշխատում:

Շուտվանից c++-ով ոչ մի բան չեմ արել, կոմպիս մեջ հիմա չկա էլ, որ փորձեմ ու 100%-անոց ասեմ, ինտերնետում նայեցի ու սենց հասկացա: Ինքը 0-ից 32000 միջակայքում ընկած պատահական թիվ ա տալիս:
Օրինակ, եթե ուզում ես 0-ից 10 սահմանում ընկած պատահական թիվ ստանաս, պիտի գրես
rand()%10

Իսկ օրինակ, եթե 5-ից 20 սահմանում ես ուզում՝
5+rand()%15

Հ.Գ. մի տեղ տեսա գրած էր, որ մինչև rand()-ը օգտագործելը պիտի srand()-ը օգտագործես: Այ էդ պահը չգիտեմ ինչքանով ա ճիշտ, եթե c++ ունես, փորձի, տես ոնց ա:

Միքո
20.10.2013, 20:31
Էլ ինձ մենակ էք թողել :(

կոնկրետ ինչա՞ պետք բացատրել :)
rand() -ը պատահական ամբողջ թիվա վերադարձնում 0-ից մինչև 32767-ը, օգտագործելուց առաջ srand() ֆունկցիան պետքա կանչես ու իրան ինչ որ քայլի երկարություն տաս, ըստ որի նա փոխելուա rand()-ի հաջորդ անդամը
թե՞ քեզ ալգորիթմնա պետք իմանալ

Արամ
20.10.2013, 20:40
կոնկրետ ինչա՞ պետք բացատրել :)
rand() -ը պատահական ամբողջ թիվա վերադարձնում 0-ից մինչև 32767-ը, օգտագործելուց առաջ srand() ֆունկցիան պետքա կանչես ու իրան ինչ որ քայլի երկարություն տաս, ըստ որի նա փոխելուա rand()-ի հաջորդ անդամը
թե՞ քեզ ալգորիթմնա պետք իմանալ
Արմեն ջան քեզ էլ եմ շնորհակալ: Մերսի Միք ջան, բայց դե գիտեմ դա:) Ես ալգորիթմն եմ ուզում հասկանամ, թեկուզ շատ մանրամասն չէ, բայց ընդհանուր պրինցիպը:

Արամ
20.10.2013, 20:41
Շուտվանից c++-ով ոչ մի բան չեմ արել, կոմպիս մեջ հիմա չկա էլ, որ փորձեմ ու 100%-անոց ասեմ, ինտերնետում նայեցի ու սենց հասկացա: Ինքը 0-ից 32000 միջակայքում ընկած պատահական թիվ ա տալիս:
Օրինակ, եթե ուզում ես 0-ից 10 սահմանում ընկած պատահական թիվ ստանաս, պիտի գրես
rand()%10

Իսկ օրինակ, եթե 5-ից 20 սահմանում ես ուզում՝
5+rand()%15

Հ.Գ. մի տեղ տեսա գրած էր, որ մինչև rand()-ը օգտագործելը պիտի srand()-ը օգտագործես: Այ էդ պահը չգիտեմ ինչքանով ա ճիշտ, եթե c++ ունես, փորձի, տես ոնց ա:

Srand-ը ընտրումես, որ կետից սկսի հաշվել, հիմնականում time-ը կարելի ա որպես srand-ի միավոր վերցնել:

Միքո
20.10.2013, 20:50
Արմեն ջան քեզ էլ եմ շնորհակալ: Մերսի Միք ջան, բայց դե գիտեմ դա:) Ես ալգորիթմն եմ ուզում հասկանամ, թեկուզ շատ մանրամասն չէ, բայց ընդհանուր պրինցիպը:

մոտավոր ռանդ ալգորիթմներ կարող եմ բացատրել, բայց հաստատ չեմ կարողանա ասել rand()-ը տենցա աշխատում թե չէ

Արամ
20.10.2013, 20:52
մոտավոր ռանդ ալգորիթմներ կարող եմ բացատրել, բայց հաստատ չեմ կարողանա ասել rand()-ը տենցա աշխատում թե չէ

Հա թեկուզ, ինձ հետաքրքիրա ուղղակի էդ պատահակն թիվ գտնելը ոնց ա լինում, ես մի 5-6 օր տանջվել էի տենց ալգորիտմ գրեի, բայց մեկ ա կարում էի հաշվեի ինչ պետք ա տա...:(

Միքո
20.10.2013, 20:59
Հա թեկուզ, ինձ հետաքրքիրա ուղղակի էդ պատահակն թիվ գտնելը ոնց ա լինում, ես մի 5-6 օր տանջվել էի տենց ալգորիտմ գրեի, բայց մեկ ա կարում էի հաշվեի ինչ պետք ա տա...:(

X0 = սկզվբական ինչ որ թիվա, որը մի ձև պետքա ինիցիալիզացվի, հիմնականում օգտագործում են տվյալ ժամը վայրկյաններով, ու ամեն հաջորդ անդամ ստացվումա նախորդը ինչ որ գործակցով բազմապատկելով ու գումարելով ուրիշ ինչ որ գործակից (կամ ցանկացած այլ արտահայտություն օգտագործելով)
Xn+1 = P1 * X n + P2 , որտեղ P1-ն ու P2-ը նախորոք որոշածդ գործակիցներդ են.

armen9494
20.10.2013, 21:00
Հա թեկուզ, ինձ հետաքրքիրա ուղղակի էդ պատահակն թիվ գտնելը ոնց ա լինում, ես մի 5-6 օր տանջվել էի տենց ալգորիտմ գրեի, բայց մեկ ա կարում էի հաշվեի ինչ պետք ա տա...:(

Իմ կարծիքով ոչ մի բանից պատահական թիվ ստանալ հնարավոր չի: Այսինքն պիտի գտնես համակարգչի մեջ մի բան, որի արժեքը անընդհատ փոխվում ա, (օրինակ պրոցեսորի նագռուզկեն), ու ըստ դրա գրել ալգորիթմը: Իսկ ավելի "հուսալի" տարբերակ գտնելու համար, մի քանի բաների հետ կապել՝ օրինակ նաև օպերատիվ հիշողության:

Մնում ա գտնել, թե C++-ով ո՞նց կարելի ա նման ինֆորմացիա վերցնել:

Արամ
20.10.2013, 21:01
X0 = սկզվբական ինչ որ թիվա, որը մի ձև պետքա ինիցիալիզացվի, հիմնականում օգտագործում են տվյալ ժամը վայրկյաններով, ու ամեն հաջորդ անդամ ստացվումա նախորդը ինչ որ գործակցով բազմապատկելով ու գումարելով ուրիշ ինչ որ գործակից (կամ ցանկացած այլ արտահայտություն օգտագործելով)
Xn+1 = P1 * X n + P2 , որտեղ P1-ն ու P2-ը նախորոք որոշածդ գործակիցներդ են.
Հա բայց սենց պատահական չի լինում....ինչ որ բանից կախված ա լինում...

Արամ
20.10.2013, 21:03
Իմ կարծիքով ոչ մի բանից պատահական թիվ ստանալ հնարավոր չի: Այսինքն պիտի գտնես համակարգչի մեջ մի բան, որի արժեքը անընդհատ փոխվում ա, (օրինակ պրոցեսորի նագռուզկեն), ու ըստ դրա գրել ալգորիթմը: Իսկ ավելի "հուսալի" տարբերակ գտնելու համար, մի քանի բաների հետ կապել՝ օրինակ նաև օպերատիվ հիշողության:

Մնում ա գտնել, թե C++-ով ո՞նց կարելի ա նման ինֆորմացիա վերցնել:

Հա դե ժամանակից է՞լ հուսալի բան:

Միքո
20.10.2013, 21:05
Հա բայց սենց պատահական չի լինում....ինչ որ բանից կախված ա լինում...

ցանկացած դեպքում էլ ինչ որ բանից կախված պետքա լինի, դա քո ալգորիթմնա ու մենակ դու գիտես իրա բանաձևը

մոռացա ասեի ընտրում են ինչ որ թիվ ու ստացածդ արդյունքը բաժանում են դրա վրա ու վերցնում մնացորդը.
օրինակ հիմա unixtime-ով ժամը՝ 1382292199, էս վերցնում ենք որպես X0, P1-ը թող լինի 2, իսկ P2-ը 3.
ասենք X1 = (2 * 1382292199 + 3) % 1024.
ու ամեն անգամ ստանում ենք ինչ որ պատահական թիվ ընկած 0-ից 1023-ը