Jump to page: 1 2
Thread overview
February 09, 2013

Merhaba

Elimde c adında bir char* var. ve bunun son elemanı da size adında char*.

İsteğim c ile size arasında string find işlemi yapmak. Bunu nasıl yapabilirim

Zekeriya

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

February 09, 2013

Veya başka bir soru sorarsam eğer. Bir for döngüsü içerisinde tek tek karakterleri kontrol ettirmekten bir farkı var mı?

Zekeriya

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

February 09, 2013

/* yorum alanı */

Ali hocam aslında yapmak istediğim üstteki */ yazan yere kadarki yorum alanı yazısını almak.

Bunu her karakteri tek tek kontrol ederek de yapabilirim ama find fonksiyonunu kullanmak kadar hızlı olur mu sorusu kafamı karıştırıyor.

Zekeriya

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

February 09, 2013

Bu konuda sana yardımcı olabilirim. Çünkü bir dönem bitFind üzerinde yoğun bir şekilde çalıştım. Eğer veriyi 2 char olacak şekilde uint dizisi içine yerleştirirsek ben sana çok hızlı bir şekilde /* ile */ ifadelerini temizleyip saf metin olarak geri döndürebilirim. Hocamın dediği gibi denemek lazım...:)

Gerçi RegExp var ama hızlı bulursan onu kullanırsın...

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

February 09, 2013
import std.stdio;
import std.algorithm;
import std.string;

void main()
{
   char[] s = "abcdef".dup;

   // Elinde böyle şeyler var:
   char* c = &s[0];
   size_t size = s.length;

   // Önce göstergeden dilim elde edilir:
   char[] dilim = c[0..size];

   // Sonra find kullanılabilir
   auto sonuç = find(dilim, 'c');

   // Dikkat: find, bulduğu yerden sonraki aralığı döndürür
   assert(sonuç == "cdef");

   // Özel bir koşula göre aramak:
   sonuç = find!(c => c == 'e')(dilim);
   assert(sonuç == "ef");
}

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

February 09, 2013

Denemeden bilemeyiz tabii ama senin yöntemin de olur. Sonuçta find da sırayla arıyor. Asıl önemli olan, char'ın UTF-8 kod birimi olduğunu hatırlamak. Eğer yorumlarda ASCII dışında karakter kullanılıyorsa find daha kolay olur.

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

February 09, 2013

Hocam lexer da birkaç iyileştirme yapıyordum. Bu onun için gerekli oldu.

string tmp;
atla:
while(c < size){
	foreach(i,l; "arananmetin"){
		if(*(c+i) != l) {tmp ~= *c;c++; goto atla;}
	}
	c+="arananmetin".length-1;
	goto atla2;
}
atla2:
writeln(tmp);

şeklinde bir kod yazdım. Ne kadar doğrudur ne kadar başarılıdır orasını tartışabiliriz sanırım :)

Aranılan metinler

auto lexmap = [
'/': LexMap(DIVIDE,[
	'=': LexMap(DIVEQUAL),
	'*': LexMap(COMMENT,"*/"),
	'/': LexMap(COMMENT,"\n")
])
];

şeklinde oluşturduğum yapıdan geliyor.

Alıntı:

>

Bu konuda sana yardımcı olabilirim. Çünkü bir dönem bitFind üzerinde yoğun bir şekilde çalıştım. Eğer veriyi 2 char olacak şekilde uint dizisi içine yerleştirirsek ben sana çok hızlı bir şekilde /* ile */ ifadelerini temizleyip saf metin olarak geri döndürebilirim. Hocamın dediği gibi denemek lazım...

Salih hocam mümkünse bunun basit bir örneğini hazırlayabilir misiniz? Ve bir sorum var üstteki yapıdan daha mı hızlı?

Alıntı:

>

Gerçi RegExp var ama hızlı bulursan onu kullanırsın...

Burada RegExp kullanamam maalesef.

Zekeriya

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

February 10, 2013

Merhaba Zekeriya,

Öncelikle kusura bakma, senin soruyla çok ilgilenemedim ve günün büyük bir çoğunluğu gereksiz işlerle geçti, gitti! Hatta ifadelerin bit karşılıkları aranırken uint türe çevrilmesi gerektiğinden bahsetmiştim; yanılmışım çünkü, 16 bit ushort demek olduğunu bir an için unutmuşum.

Şimdi benim şurada bitDerle isminde basit bir proje (http://ddili.org/forum/post/5433) var. Elektronikçi olduğum için bitler ile oynaşmak (evet, oynaşmak!) hoşuma gidiyor. Üniversitede diğer bölümler, bizim bölümdeki arkadaşlar sayısal elektronik sınavlarına çalışıyorlarken (hep 1 ve 0'ları telafuz ettiklerinden!) bir garip bakarlardı. Bu dünyada adeta uzaylı havası hakim...:)

Neyse, az önce aşağıdaki çalışan işlevleri pratik bir şekilde yazıp deneme fırsatım oldu. Eniyileştirme (optimization) yapılabilir, hatalar olabilir, hatta işimize yaramayacak kadar kötü ve gereksiz de olabilir! Şimdi senin ve geleneksel sözcük arama yöntemelerini inceleyeceğim. Bakalım bitDerle hızlı bir çözüm olabilecek mi?

import std.stdio;

union ushort2char {
 ushort bilgi;
 char[2] p;
}

auto ushort2str (ushort veri[]) {
 string rslt;
 auto veriler = ushort2char(0);
 // veriyi parçalayıp ters sırada birleştirir:
 foreach(v; veri[]) {
   veriler.bilgi = v;
   rslt ~= veriler.p[1];
   rslt ~= veriler.p[0];
 }
 return rslt;
}

auto str2ushort (string veri) {
 ushort[] rslt;

 for(size_t i; i < veri.length - 2; i+=2) {
   rslt ~= cast(ushort)veri[i] << 8;
   rslt[$-1] |= cast(ushort)veri[i+1];
 }

 if(veri.length % 2 == 0) {
   rslt ~= cast(ushort)veri[$-2] << 8;
   rslt[$-1] |= cast(ushort)veri[$-1];
 } else { // veri uzunluğu tek ise son bitleri 0 ile doldur:
   rslt ~= cast(ushort)veri[$-1] << 8;
 }
 return rslt;
}

void main(){
 string yorumÖrneği1 = q{
                           module sdb.algorithm;
                        /* burası algorithm.d modülü
                         * olarak tanımlanır
                         */
 };

 string yorumÖrneği2 = "/* abc */";

 ushort[] veri = str2ushort(yorumÖrneği1);
          veri.writeln;            // kodlanmış veri,
          veri.ushort2str.writeln; // burada çözülür...
}

Dip Not: Eğer, bitDerle ilgini çekerse ve kullanımı zor gelmezse, lütfen denemelerini yorumÖrneği2 ile yapalım. Çünkü yapının içindeki print() işlevi uzun verilerde işlevsiz kalabiliyor. Tabi konsol ekranını genişletebiliyorsun ama 80 satırlı standartlarda garip gelebilir. Çünkü görsel bir şekilde verinin bulunduğu yeri, alt satırda oklu şekilde gösterebiliyor. Hatta bu sistem script dillerde hatanın olduğu yeri göstermekte çok kullanılır. Belki ileride Rhodeus Script de bu olayı destekler, ne dersin?

Başarılar...

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

February 10, 2013

Tekrar merhaba..:)

Şimdi önce D'nin std/algorithm sınıfındaki find işlevlerine bir bakalım. Eğer işimize yarıyorsa, sonrasını gerektiği kadar hızlı mı diye test ederiz, hepsi o kadar...

 auto s1 = std.algorithm.findSplitAfter(yorumÖrneği2, "/*");
 s1[1].writeln; // => abc */

 auto s2 = std.algorithm.findSplitBefore(s1[1], "*/");
 s2[0].writeln; // => abc

Yukarıda, herhangi bir yerde çalışabilecek iki işlem görmekteyiz. İşlevler, çokuzlu (Tuples) olarak sonuç döndürüyor ama tıpkı bir diziymiş gibi her bir elemana (string) erişebiliyoruz. Belki tek satırda da yazılabilirdi ama açık şekilde yazarak anlaşılır olmasını istedim.

İlk sonuçtan görüleceği üzere, aranan ifade dahil öncesini s1[0]'a bölüyor ki diğer parçası s1[1]'de kalıyor. Böylece kesmek istediğimiz bölümün fazlasıyla birlikte ekranda görüyoruz. Elbette, dilim mahareti ile sondan ikisini kesebilirdik ama aranan metnin boyutlarını ve kesilecek bölümün sonda olup olmadığını bilmiyoruz...:)

O halde, ikincisin de bu sefer findSplitBefore()'u kullanarak aranan ifade hariç bir şekilde dizgeyi tekrar bölüyoruz. Bu sefer ilk parçayı aldığımızda istediğimizi elde etmiş oluyoruz. Hızı ne olur, onu bilemiyorum ama ileride alternatiflerini tartışarak anlarız inşaallah.

Bu arada Zekeriya'nın yazdığını şu şekilde denedim ama bir sonuç elde edemedim. Nerede hata yapıyoruz?
Alıntı:

>
>   char[] s = yorumÖrneği2.dup;
>   char* c = &s[0];
>   size_t size = s.length;
>
>   string tmp;
>   atla:// v--- tür uyumsuzluğu vardı * ekledim...
>     while(*c < size){
>         foreach(i,l; s){
>             if(*(c+i) != l) {
>               tmp ~= *c;
>               c++;
>               goto atla;
>             }
>         }
>         c += s.length-1;
>         goto atla2;
>     }
>
>   atla2:
>     writeln(tmp); // sanki tmp boş, sadece satır başı yapıyor...
> ```

>

-- 
[ Bu gönderi, <http://ddili.org/forum>'dan dönüştürülmüştür. ]
February 10, 2013

Sanırım artık teste ve hız karşılaştırmalarına geçebiliriz. Çünkü aynı sonucu (tabi görünüşe göre çok çok fazla basamak ile!) alabiliyorum...:)

Aşağıdaki kodun çalışması için bitDerle sınıfı sdb.algorithm içerisine yerleştirilmesi gerekiyor. Ancak dilerseniz sınıfı, main()'nin bulunduğu yere kopyalayabilirsiniz:

import std.stdio,
      sdb.algorithm;
void main() {
   enum anahtarSözcükler : ushort {
      yorumAç   = 12074, // "/*"
      yorumKapa = 10799  // "*/"
   }

   // bitDerle sınıfının, BS yapısı, ushort türü ile tanımlanır:
   bitDerle.BS!(ushort) bit;

   // tanımlanan bit değişkeni üzerinden veri aktarılır:
   bit.init(
             str2ushort("/* abc */")
           );

   // aranan sözcüğün konumunu öğreniliyor:
   auto offset1 = bit.find(anahtarSözcükler.yorumAç);
   auto offset2 = bit.find(anahtarSözcükler.yorumKapa);

   // konuma göre biçimli bir şekilde verileri ekrana yazıyoruz:
   //bit.print(offset1);

   offset1 /= bit.bl; // bulunan her iki sınırda
   offset2 /= bit.bl; // bitLength (bl)'e bölünüyor...

   /* yorumAç'ın döndürdüğü bir arttırılarak (++)
    * dilim sırasında kesilip string ifadeye çevrilerilir...
    * böylece istenen netice ekrana yazılır:
    */
   bit.xData[++offset1..offset2].ushort2str.writeln;
}

Notlar:

  • Bir yerlerde patlak verebilecek 2 önemli böcük (bug) ortalıklarda dolaşıyor olmalı...:)
  • İlki string ifadelerdeki eleman sayısının (length) tek/çift olması durumuna bağlı olarak gelişmesi yüksek ihtimal. Çünkü en basitten length == 'tek' olması durumunda, defalarca str2ushort() <=> ushort2str() işlevlerini çalıştırarak verinin birer bayt büyüdüğü (sanırım sadece null character) gözlemlenecektir. Denemedim ama kesin gibi!
  • Bunun dışında benzer şekilde bitsel offset değerleri dilim için oranlandığında bazı sıkıntılar yaşması da muhtemel görünüyor...
  • Son olarak, olası hatalara rağmen büyük bir dosyadan metin okutturup bunun içeriğindeki yorumları başka dosyaya yazması istenerek karşılaştırma yapabiliriz. Çünkü std'deki algoritma her ne kadar iki komutluk gibi görünse de içeriğinde quicksort dahil bir çok algoritma koşuyor olabilir. Oysa sdb'deki algoritmalar en amatöründen basit şekilde ele alındı... :-p

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

« First   ‹ Prev
1 2