PDA

Tam Sürümünü Görmek İçin : :(((((


elzapo
19/12/2004, 21:30
slm arkadaşlar ben bir programda takıldım:(
dışardan girilen sayının farklı toplamlarını veren program....
mesela dışardan 6 sayısı girildi
çıktıda.......:
1+1+1+1+1+1
2+1+1+1+1
3+1+1+1
4+1+1
5+1
2+2+1+1
2+2+2
3+2+1
4+2
3+3
.
.
.
böyle bir programda nasıl bir mantık izlemeliyim?
(turbo c)


ceeyt
20/12/2004, 01:59
'1 + 1 +.....+ 1 = n' cozumu tum pozitif tamsayi n degerleri icin gecerli olacaktir.

Sayiyi bu forma soktuktan sonra 1 leri gruplayip, her gruptaki 1 lerin toplami seklinde ifade edebilirsin.

Toplam icindeki sayilarin negatif olmasi ihtimalini yok sayiyorum, malum sonsuz tane cozum cikar :)

kolay gelsin...

myavuzselim
20/12/2004, 04:29
Rekursif bir fonksiyonla yapabilirsin:
private static ArrayList<String> bolumlereAyir(int sayi, String str) {
ArrayList<String> list = new ArrayList<String>();
list.add(sayi + str);
for (int i=1; i<sayi; i++) {
ArrayList<String> altBolum = bolumlereAyir(sayi-i, "+" + i);
for (String s : altBolum)
list.add (s + str);
}
return list;
}
public static ArrayList<String> bolumlereAyir(int sayi) {
return bolumlereAyir(sayi, "");
}
Yukaridaki kodu java için yazdim. Herseyi buluyor mu tam test etmedim.

Euclides
20/12/2004, 09:12
yukarıdaki kod çatlar...
memory leak var.
ayrıca öz yinelemeli fonksiyonlar sadece lisp,sheme vb... gibi dillerde iyi sonuç verir.
C gibi dillerde çoğu zaman stack overflow'la sonuçlanır.

myavuzselim
20/12/2004, 09:51
En az 20'ye kadar sorunsuz hesapliyor. Zaten problemin kendisi buyuk bir ihtimalle exponansiyel, sonunda ha oyle ha boyle catlayacak.
Memory leak ile ne kastettigini tam anlamadim, galiba 1'den cok defa hesaplanmak zorunda kalan sayilar hakkinda soyledin bunu. Ama ozyinelemeli fonksiyonlarla ilgili dediginde haklisin. n buyuklugunde bir array yapip yine ayni mantikla 1'den n'e kadar bolumler hesaplanabilir. Ama bu sekilde hafizaya cok yuk binebilir. Veya stack falan kullanilip recursif fonksiyon simule edilebilir, ama o zaman tekrar hesaplama sorunu cozulmus olmuyor.

Euclides
20/12/2004, 12:39
memory leak = "ArrayList<String> list = new ArrayList<String>();"
devamlı yeni hafıza istiyorsun ama hiç bırakmıyorsun.....

myavuzselim
20/12/2004, 14:11
Ama yukaridaki kod c degil, java. Algoritmik bir soru oldugu için dil pek fark etmez diye yazdim buraya.
Java'da garbage collector var, o kendisi gerektiginde kulanilmayan nesneleri siliyor.

elzapo
21/12/2004, 19:51
saolun arkadaşlar ama istediim cevabı alamadım:(

Volkan Uzun
21/12/2004, 19:52
baska bir sorunda, sorunun konu kisminda yazan ":((( " ibare yuzunden kimsenin ilgisini cekmiyor bence.

elzapo
21/12/2004, 19:57
ya kusura bakma onun ":(" amacı sorunun cvbını öğrenmek için fazla vaktim yok demeye çalıştım.merak etmeyin bidaha olmaz

Mahmut Yılmaz
02/06/2005, 16:25
:)
Aşağıdaki VB kodu bu sorunu çözüyor:

***

n = Val(txtTamsayi.Text)
ReDim x(n) As Integer
For i = 1 To n
x(i) = 1
Next
x(1) = n
m = 1
h = 1
lblSonuc.Caption = x(1) & vbCrLf
While x(1) <> 1
If x(h) = 2 Then
m = m + 1
x(h) = 1
h = h - 1
Else
r = x(h) - 1
t = m - h + 1
x(h) = r
While t >= r
h = h + 1
x(h) = r
t = t - r
Wend
If t = 0 Then
m = h
Else
m = h + 1
If t > 1 Then
h = h + 1
x(h) = t
End If
End If
End If
For i = 1 To m - 1
lblSonuc.Caption = lblSonuc.Caption & " " & x(i) & " +"
Next
lblSonuc.Caption = lblSonuc.Caption & " " & x(m) & vbCrLf
Wend

Euclides
02/06/2005, 18:21
@Mahmut Yılmaz:
sadece 1-2 yıl geç kaldın :)

myavuzselim
20/08/2005, 05:06
Ben daha da geç kaldim :)
Eski konulara bakarken bu konuyu gordum ve bu probleme daha duzgun bir cozum yok mu diye dusundum. Ortaya bu cikti. Soyle bir bakinca Mahmut Yilmaz'inkinden daha az karmasik degil ama olsun. Harddisk'imde kaybolacagina burada dursun, belki bir ise yarar.
#include <vector>
#include <iostream>

using namespace std;

class SayiBolumleyici {
int n;
int enSol;
vector<int> v;
public:
SayiBolumleyici(int n_) : n(n_), enSol(1) {
for(int i=0; i<n; ++i) v.push_back(1);
}
~SayiBolumleyici() {};
void print() {
for(vector<int>::iterator i=v.begin(); i!=v.end(); ++i)
cout<<*i<<",";
cout << endl;
}
bool sonraki() {
int len = v.size();
if(len==1) return false;

// soldan baslayarak, bir elemandan 1 eksiltip
// sola vermeyi dene
// a <= b <= ... <= e <= f esitsizligi bozulmamali
for(; enSol < len; ++enSol) {
if(v[enSol]-1 >= v[enSol-1]+1) {
--v[enSol];
++v[enSol-1];
return true;
}
}

// yukaridaki dongu basarisiz oldu
// bir eksik elemanla yenidan basla: 1<=1<=...<=1<=e
for(int i = 0; i<len-2; ++i) {
v[i]=1;
}
v[len-2] = n-len+2;
v.pop_back();
enSol=1;
return true;
}
};

int main() {
SayiBolumleyici sb(100);
sb.print();
while(sb.sonraki()) sb.print();
return 0;
}
Mesela 5:

1<=1<=1<=1<=1
Sola kaydiramiyoruz, bir eksik elemanla yeniden baslayalim:
1<=1<=1<=2
Sola kaydiramiyoruz, 3 elemanla yeniden:
1<=1<=3
3'u sola kaydirabiliyoruz:
1<=2<=2
Sola kaydiramiyoruz, 2 elemanla yeniden:
1<=4
4'u sola kaydir:
2<=3
Sola kaydiramiyoruz, 1 elemanla:
5

myavuzselim
21/08/2005, 20:53
Hmm, ilk basta enSol yerine 1'den basliyordum. Sonra hizlandirmak icin enSol'u uydurmustum ama bir hata olmus. Su sekilde duzelmesi lazim:
--v[enSol];
++v[enSol-1];
if(enSol>1) enSol--;
return true;
Bir soldaki elemani arttirdigimiz icin o da yeniden sola aktarabilme sansi kazaniyor.