31 Ekim 2015 Cumartesi

Range

Range Temsili
Range ile ilgili en önemli konu alt ve üst sınırın dahil olup olmadığı. Buna en baştan karar vermek gerekiyor. Matematikçiler genelde alt sınır dahil, üst sınır hariç belirtimini kullanıyorlar.

-open range
-closed range
-left open
-right open

Çeşitli gösterim şekilleri şöyle
[5, 10)         # interval notation
5 <= x < 10     # inequality notation
5, 6, 7, 8, 9   # list notation
XML ve JSON ile şöyle gösterilebilir.
<range low="5" high="10"/>   # XML
[5, 10]                      # simple list (brackets are data delimiters, 
                                            not mathematical interval notation)
{ "low": 5, "high": 10 }     # JSON fragment 
Algoritmalar
Aşağıda range'ler ile kullanılan algoritmalarla ilgili notlarım var.

Range'i Bölümlere Ayırma (Partition a Range of Numbers)
Rastgele Büyüklükte Bölümlere Ayırma
Örnek algoritma

İlk elemanını bir header gibi her bölümün başına ekleyerek bölümlere ayırma örneği
List list = ...;
int partitionLength = ...
Group g = new Group();
AddInitial (g,list);

int groupLenth = partitionLength - 1;
int lastIndex = list.Count - 1;
for (int index = 1; index < list.Count; index++){
 AddGroup (g,list [ index ] );
 if (IsRepeatBoundary (groupLenth, index)){
   groupList.Add (g);
   g = new Group ();
   if (! LastMessage (lastIndex, index)){
     AddInitial (g,list);
   }
 }//Boundary
}//For

if (g.Count != 0)
{
  groupList.Add (g);
}

C++
iota
std::iota yazısına taşıdım.

Kendi Range Kodum
Örnek
Elimizde şöyle bir kod olsun.

template <typename T> 
struct range {
    T from, to;
    range(T from, T to): from(from), to(to) {}
    struct iterator {
        const T to; // iterator knows its bounds
        T current;
        T operator*() { 
            return current; 
        }
        iterator& operator++() { 
            ++current;
            if(current > to)
                // make it an end iterator
                // (current being exactly equal to 'current' of other end iterators)
                current = to;
            return *this;
        }
        bool operator==(const iterator& other) {
            return current == other.current;
        }
        bool operator!=(const iterator& other) {
            return !(*this == other); // this is how we do !=
        }
    };
    iterator begin() const { return iterator{to, from}; }
    iterator end()   const { return iterator{to, to}; }
};
Şöyle yaparız.
or (auto i: range(5,9))
    cout << i << ' ';    // prints 5 6 7 8 
boost::irange
boost range yazısına taşıdım.

boost::make_iterator_range
boost range yazısına taşıdım.

Guava RangeSet
TreeRangeSet Sınıfı yazısına taşıdım.

Guava Ranges
Ranges sınıfı boost::irange sınıfını andırıyor.RangesExplained başlıklı sayfada kullanım örnekleri mevcut.
Does guava provide any support for defining ranges of characters? sorusuna verilen cevap ise aşağıda.

hasLowerBound
Verilen range nesnesinin alt sınırı olup olmadığını döner.

lowerBoundType
Verilen range nesnesinin alt sınırı varsa, sınırın dahil olup olmadığını döner. Örnekte alt sırın kontrolü gösterilmiş.

    
Apache Commons
Range Sınıfı yazısına taşıdım.
Range.between(100, 200);
C#
Repeat metodu
Örnekte array aynı nesne ile dolduruluyor.
var columns = Enumerable.Repeat(new MyClass(), 10).ToArray();

RepeatIndefinitely
Sürekli aynı değerleri veren bir metod örneği. source ["a", "b", "c"] değerlerine sahipse ["a", "b", "c","a", "b", "c"... ] şeklinde hep başa döner.
public static IEnumerable<T> RepeatIndefinitely<T>(this IEnumerable<T> s)
{
    var list = s.ToList();
    while (true)
    {
        foreach (var item in list)
        {
            yield return item;
        }
    }
}

Range metodu
var nums = Enumerable.Range(0, 10).ToArray();
var rnd = new Random();

// Shuffle the array
for (int i = 0;i < nums.Length;++i) {...} 
DateRange
Örnek:
public interface IRange<T>
{
    T Start { get; }
    T End { get; }
    bool Includes(T value);
    bool Includes(IRange<T> range);
}

public class DateRange : IRange<DateTime>         
{
    public DateRange(DateTime start, DateTime end)
    {
        Start = start;
        End = end;
    }

    public DateTime Start { get; private set; }
    public DateTime End { get; private set; }

    public bool Includes(DateTime value)
    {
        return (Start <= value) && (value <= End);
    }

    public bool Includes(IRange<DateTime> range)
    {
        return (Start <= range.Start) && (range.End <= End);
    }
}