Forum: Diğer Konular RSS
C++ girişten gelen en uzun ve en kısa kelimeleri bulmak
erdem (Moderatör) #1
Üye Tem 2009 tarihinden beri · 978 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: C++ girişten gelen en uzun ve en kısa kelimeleri bulmak
 
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
 
using std::endl;    using std::vector;
using std::string;  using std::cin;
using std::cout;
 
bool uzunMu (const string & birinci, const string & ikinci)
{
    return birinci.size () < ikinci.size ();
}
 
int main ()
{
    string kelime;
 
    vector<string> kelimeler;
 
    while (cin >> kelime)
    {
        kelimeler.push_back (kelime);
    }
 
    const string enUzunKelime = *max_element(kelimeler.begin (),
                                       kelimeler.end(),
                                       uzunMu);
    const string enKisaKelime = *min_element(kelimeler.begin(),
                                       kelimeler.end(),
                                       uzunMu);
    cout << "En uzun kelime: " << enUzunKelime << '\n';
    cout << "En uzun kelime uzunluk: " << enUzunKelime.size() << '\n';
    cout << "En kısa kelime: " << enKisaKelime << '\n';
    cout << "En kısa kelime uzunluk: " << enKisaKelime.size() << '\n';
    return 0;
}

Girişten gelen en uzun ve en kısa kelimeleri bulan bir örnek yapmaya çalışıyorum.

Örneğin girişte türkçe karakterler kullanılmadığı zaman

En uzun kelime corbayapanlar diye düşünüyor 

program doğru çalışıyor ama çorbayapanlar yapınca en uzun kelimenin uzunluğunu 14 olarak gösteriyor.

Bunu nasıl düzeltebiliriz acaba. Teşekkürler.
erdem (Moderatör) #2
Üye Tem 2009 tarihinden beri · 978 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Sanırım bu çalıştı  ;-)
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
 
using std::endl;    using std::vector;
using std::string;  using std::wcin;
using std::wcout;   using std::wstring;
 
 
bool uzunMu (const wstring & birinci, const wstring & ikinci)
{
    return birinci.size () < ikinci.size ();
}
 
int main ()
{
    setlocale(LC_ALL, "tr_TR.UTF-8");
 
    wstring kelime;
 
    vector<wstring> kelimeler;
 
    while (wcin >> kelime)
    {
        kelimeler.push_back (kelime);
    }
 
    const wstring enUzunKelime = *max_element(kelimeler.begin (),
                                       kelimeler.end(),
                                       uzunMu);
 
    const wstring enKisaKelime = *min_element(kelimeler.begin(),
                                       kelimeler.end(),
                                       uzunMu);
    wcout << "En uzun kelime: " << enUzunKelime << '\n';
    wcout << "En uzun kelime uzunluk: " << enUzunKelime.size() << '\n';
    wcout << "En kısa kelime: " << enKisaKelime << '\n';
    wcout << "En kısa kelime uzunluk: " << enKisaKelime.size() << '\n';
 
    return 0;
}
Mengu (Moderatör) #3
Kullanıcı başlığı: NONSERVIAM
Üye Tem 2009 tarihinden beri · 347 mesaj · Konum: Dersaadet
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
erdem on 2016-02-06, 03:19:
Sanırım bu çalıştı  ;-)
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
 
using std::endl;    using std::vector;
using std::string;  using std::wcin;
using std::wcout;   using std::wstring;
 
 
bool uzunMu (const wstring & birinci, const wstring & ikinci)
{
    return birinci.size () < ikinci.size ();
}
 
int main ()
{
    setlocale(LC_ALL, "tr_TR.UTF-8");
 
    wstring kelime;
 
    vector<wstring> kelimeler;
 
    while (wcin >> kelime)
    {
        kelimeler.push_back (kelime);
    }
 
    const wstring enUzunKelime = *max_element(kelimeler.begin (),
                                       kelimeler.end(),
                                       uzunMu);
 
    const wstring enKisaKelime = *min_element(kelimeler.begin(),
                                       kelimeler.end(),
                                       uzunMu);
    wcout << "En uzun kelime: " << enUzunKelime << '\n';
    wcout << "En uzun kelime uzunluk: " << enUzunKelime.size() << '\n';
    wcout << "En kısa kelime: " << enKisaKelime << '\n';
    wcout << "En kısa kelime uzunluk: " << enKisaKelime.size() << '\n';
 
    return 0;
}

bunun d karsiligi da asagi yukari soyle bir sey:

import std.stdio : writefln;
import std.algorithm : sort;
 
void main(string[] args) {
  auto words = args[1..$];
  words.sort!((a, b) => a.length > b.length);
  writefln("en uzun kelime %s ve en kisa kelime %s", words[0], words[$-1]);
}

rdmd test.d systems and infrastructure administration specialist
ile calistirdigimizda da soyle bir cikti veriyor:

en uzun kelime infrastructure ve en kisa kelime and

senin yaptigin da aslinda asagi yukari boyle bir sey ancak. bir kere max_element icin sort ettigin listeyi min_element icin tekrar sort ediyorsun. max_element icin sort ettiginde eline gecen verinin son elemani zaten min element olacagi icin ona direkt oradan erisebilirsin. yuz bin kayit var diyelim takir takir sort ediyorsun ve bir miktar vakit aliyor bu. sonra gidiyorsun tekrar sort ediyorsun. buna gerek yok.
http://www.mengu.net - some kind of monster
erdem (Moderatör) #4
Üye Tem 2009 tarihinden beri · 978 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Programı inceleyorum ama ilk görebildiğim şey:

./dene2 bir iki üç derken çoğalmışlardı
en uzun kelime çoğalmışlardı ve en kisa kelime iki


en kısa kelime üç olacak.
acehreli (Moderatör) #5
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
(Mengu, tabii ki önemli bir konu değil ama senin yanıtların yanıt yazdığın mesajları da olduğu gibi içeriyor. Ben çoğu durumda "Alıntı yap" yerine en alttaki "Yanıtla"yı seviyorum. ;) )

  • "iki" ve "üç" aynı uzunluktalar çünkü ikisi de UTF-8 nedeniyle 3 bayttan oluşuyor. ;)

  • Burada konuşmadığımız bir diğer konu, aynı uzunlukta birden fazla kelime bulunduğunda hangisini döndürelim? İlkini, sonuncusunu, herhangi birisini, vs? Bu kavram, elemanların yerlerine değiştiren sort gibi algoritmalarda stable ve unstable olarak açıklanır: stable algoritmalar elemanların yerlerini değiştirirken elemanların yerlerini göreceli olarak korurlar: Örneğin bütün 3 uzunluktaki kelimeler bir araya gelirler ama kendi aralarında asıl dizideki sıradadırlar.

std.sort ne tür sıralama istediğimizi ikinci şablon parametresi olarak alır. Örnek:
    dizi.sort(/* ... */, SwapStrategy.unstable)

  • Kısa diziler için önemli değildir ama genel olarak, eğer dizinin sıralanması daha sonraki işlemler için de önemli değilse, gereksizce yavaş olabilir: O(N logN). Onun yerine, diziyi hem en kısa ve hem en uzun için bir kere ilerlemek daha hızlı olacaktır: O(N). Hatta, önce min() sonra max() için iki kere ilerlesek bile sıralamaktan daha hızlı olur: 2xO(N).

Ali
erdem (Moderatör) #6
Üye Tem 2009 tarihinden beri · 978 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
O zaman şimdi iki ve üç'ü nasıl sıralayacağız :)

Benim üstte yazdığım program C++ programı ama kaya gibi çalışıyor.  ;-)  Yerelleri dikkate alıyor.

Ali bey bir de C++ için  Mengü'nün bahsettiği gibi tek seferde hem küçük hem de büyük elemanı bulabilrmiydik.

*max_element topluluğun tüm elemanları için sıralama yapıyor mu?
erdem (Moderatör) #7
Üye Tem 2009 tarihinden beri · 978 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Haksızlık olmasın diye C++11 sürümünü de yazdım.
 
#include <algorithm>
#include <iostream>
#include <vector>
 
using namespace std;
 
int main()
{
    setlocale(LC_ALL, "tr_TR.UTF-8");
    wstring kelime;
    vector<wstring> kelimeler;
 
    while (wcin >> kelime)
        kelimeler.push_back(kelime);
    auto sonuc = minmax_element(kelimeler.begin(), kelimeler.end(),
                                [](wstring a, wstring b){ return a.size() < b.size(); });
 
    wcout << L"En uzun kelime: " << (*sonuc.second) << '\n';
    wcout << L"En uzun kelime uzunluk: " << (*sonuc.second).size() << '\n';
 
    wcout << L"En kısa kelime: " << (*sonuc.first) << '\n';
    wcout << L"En kısa kelime uzunluk: " << (*sonuc.first).size() << '\n';
}

Derlerken g++ -std=c++11 şeklinde derlemek gerekiyor.

Yalnız programda ufak bir hata var. Programın doğru çalışmasına etki etmiyor ama En ksa kelime yazıyor.
Bu mesaj erdem tarafından değiştirildi; zaman: 2016-02-09, 11:05.
erdem (Moderatör) #8
Üye Tem 2009 tarihinden beri · 978 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
D sürümünü de şu şekilde yazdım.

import std.stdio;
import std.algorithm;
import std.array;
 
void main()
{
    auto words = array(readln().splitter(" "));
    words.sort!((a, b) => array(a).length > array(b).length);
    writeln("En uzun kelime : ", words[0]);
    writeln("En uzun kelime uzunluk : ", array(words[0]).length);
    writeln("En kısa kelime : ", words[$-1]);
    writeln("En kısa kelime uzunluk : ", array(words[$-1]).length);
}

Gene burada ufak bir hata var. O da şu okunan kelimeleri parçalayınca büyük ihtimal \n karakterini de alıyor.
acehreli (Moderatör) #9
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #6
erdem:
O zaman şimdi iki ve üç'ü nasıl sıralayacağız :)

std.utf.count'tan yararlanmak gerek.

(Ama o yalnızca kod noktalarını sayar. Daha usta bir sonuç istiyorsak std.uni modülünden yararlanmak gerekecektir. Örneğin, "üç" Unicode'da çok sayıda farklı biçimde kodlanmış olabilir: 'ü' ve 'ç' olarak; 'u', '  ̈' (U+0308 COMBINING DIAERESIS), 'c', ve '  ̧' (U+0327 COMBINING CEDILLA) olarak; vs.)

Aşağıdaki yöntem kelimeler için yer ayırmadan (ve dolayısıyla sıralamadan) tembel olarak işliyor:
import std.stdio;
import std.algorithm;
import std.typecons;
 
// Verilen giriş akımını kelimelere ayırır.
auto byWord(File giriş) {
    return giriş.byLine.map!(satır => satır.splitter).joiner;
}
 
// Verilen aralıktaki elemanların uzunluklarının en kısa ve en uzununu çokuzlu
// olarak döndürür.
auto minMax(Range)(Range giriş) {
    // Sonucu tutan değişkenler
    size_t kısa = size_t.max;
    size_t uzun = size_t.min;
 
    // Kelimeye bakarak mevcut sonucu günceller
    void güncelle(R)(R kelime) {
        import std.utf : count;
 
        const uzunluk = kelime.count;
 
        kısa = min(kısa, uzunluk);
        uzun = max(uzun, uzunluk);
    }
 
    // Her kelimeyi güncelle'ye gönderir
    giriş.each!(kelime => güncelle(kelime));
 
    return tuple(kısa, uzun);
}
 
// Yukarıdakinin reduce'tan yararlananı
auto minMax_2(Range)(Range giriş) {
    const başlangıçDeğeri = tuple(size_t.max, size_t.min);
 
    return reduce!((mevcutSonuç, kelime) =>
                   tuple(min(mevcutSonuç[0], kelime.count),
                         max(mevcutSonuç[1], kelime.count)))
        (başlangıçDeğeri, giriş);
}
 
void main() {
    const sonuç = minMax(stdin.byWord);
 
    writefln("Kelime uzunlukları %s ile %s arasında.", sonuç[0], sonuç[1]);
}
Ali
erdem (Moderatör) #10
Üye Tem 2009 tarihinden beri · 978 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Çok teşekkürler! Tabi usta programcıların yazdığı kod kendini belli ediyor :)

Dikkat ettiyseniz yukarıda yazdığım C++, C++11 ve D örnekleri de doğru çalışıyor.

Mengü'ye de teşekkürler :) Yazdığım örnekteki ufak hatayı farkettim.

Bu arada bunlar Accelerated C++ kitabının örnekleri.
Doğrulama Kodu: VeriCode Lütfen resimde gördüğünüz doğrulama kodunu girin:
İfadeler: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Özel Karakterler:
Bağlı değilsiniz. · Şifremi unuttum · ÜYELİK
This board is powered by the Unclassified NewsBoard software, 20100516-dev, © 2003-10 by Yves Goergen
Şu an: 2017-11-19, 04:29:38 (UTC -08:00)