HackerRank — Java Datatypes
Java veri tipleri neler? Java Datatypes sorusunun çözümü
HackerRank üzerindeki Java problemlerini çözüyoruz. Bu sekizinci problem. Eğer diğer problem çözümlerini okumadıysanız önce onlara bakmanızı tavsiye ederim, hepsinin toplu hali:
Önce problemi anlayalım sonra da çözümüne geçelim. Problemi anlama kısmını okuduktan sonra problemi çözmeyi denemenizi sonra da buradaki çözümle karşılaştırmanızı şiddetle tavsiye ederim :)
Problemin linki 👇
Problemi anlayalım
Java programlama dili statik olarak yazılmıştır, bu tüm değişkenlerin kullanılmadan önce bildirilmesi gerektiği anlamına gelir. Bir değişkeni kullanmadan önce onu tanımlamanız gerekir, bu tanımlama ise bir veri tipi içerir. Aşağıdaki örnekte programa “sayi” adında bir değişkenimiz olduğunu ve default değeri 1 olan bir integer değer olduğunu bildirdik:
int sayi= 1;
Java’da 8 primitive veri tipi vardır: char, boolean, byte, short, int, long, float, ve double. Primitive veri tipi, bir anahtar kelime ile dilde sabit tanımlı olan tiplerdir.
- byte: 8-bit signed integer, [-128, 127] arası değer alabilir. Özellikle bellek tasarufu sağlamamız gereken büyük sayılarda veri içeren array’lerde byte kullanmak faydalı olacaktır.
- short: 16-bit signed integer, [-32,768, 32,767] arası değer alabilir. byte’da söylediğimiz gibi memory kullanımı konusunda tasarruf sağlamamız gerektiğinde kullanılabilir.
- int: 32-bit signed integer, [(-2³¹), (2³¹)–1] arası değer alabilir. Eğer unsigned olarak int kullanmak istiyorsanız Integer sınıfını kullanabilirsiniz.
- long: 64-bit signed integer, [(-2⁶³), (2⁶³)–1] arası değer alabilir. int tipinden daha büyük değerler depolanamanız gerektiğinde long tipi kullanılır.
- float: 32-bit floating point, memory sıkıntısı olduğunda double yerine kullanmanız önerilir. Para gibi kesin olan veriler için float kullanmayın, bunun yerine BigDecimal sınıfı önerilir.
- double: 64-bit floating point, decimal sayılarda default veri tipidir. Para gibi kesin olan veriler için double kullanmayın, bunun yerine BigDecimal sınıfı önerilir.
- char: 6-bit Unicode character, değeri minimum
'\u0000'
(0) ve maximum'\uffff'
(65,535). - boolean: true/false değerini tutan bir flag veri tipidir. Bir bitlik bir veriyi tutar ama veri tipinin boyutu kesin tanımlı değildir.
Bunlara ek olarak “String” sınıfı vardır, dilde primitive tip olarak kabul edilmez ama dil tarafından sağlanan desteğe baktığımızda diğer primitive tipler kadar temel bir sınıftır. String objesi immutable’dır, yani değer bir kez verildi mi değiştirilmez. Bu kavram çok önemli ileriki yazılarda immutable-mutable farkına bakacağız.
Değişken tanımı yapılırken ilk değerini atamazsanız default olarak veri tipine göre dil tarafından 0-null-false atanır. Ama ilk değer atamamak kötü bir programlama yöntemi olarak kabul edilir.
- Primitive tipler, new anahtar sözcüğü ile ilklendirilmezler, direkt değer atanır.
- long verisi int değerle karıştırılmaması için sonunda “L” ya da “l” eklenir, “l” eklenmesi 1 ile karıştırılacağı için genelde “L” tercih edilir.
- Integer sayı sistemleri:
- Decimal: 10'luk sistemdedir. Rakamları 0–9 arasıdır. Günlük hayatta kullandığımız sayı sistemi aslında. Örnek bir değer: “int decVal = 26;”
- Hexadecimal: 16'lık sistemdir. 0–9 arası rakamları içerdiği gibi A-F arası harfleri de içerir. Örnek bir değer: “int hexVal = 0x1a;”
- Binary: 2'lik sistemdir. 0–1 rakamları vardır sadece. Örnek bir değer: “int binVal = 0b11010;”
- Floating point bir değer sonu “f” veya “F” ile bitiyorsa float bir değerdir. Normalde ondalıklı sayıların defaultu double’dır.
double d1 = 123.4;
// d1 ve d2 aynı değerlerdir, d2 bilimsel gösterimdir
double d2 = 1.234e2;
float f1 = 123.4f;
- Değer char ise ‘c’ şeklinde tanımlanır, string ise “c” şeklinde.
- Büyük sayılarda basamakları ayırmak için “_” kullanılabilir:
long creditCardNumber = 1234_5678_9012_3456L;
long socialSecurityNumber = 999_99_9999L;
float pi = 3.14_15F;
long hexBytes = 0xFF_EC_DE_5E;
long hexWords = 0xCAFE_BABE;
long maxLong = 0x7fff_ffff_ffff_ffffL;
byte nybbles = 0b0010_0101;
long bytes = 0b11010010_01101001_10010100_10010010;
Bu problemde integer değer tutan veri tipleri(byte, short, int, and long) ile çalışacağız.
Problem Beklentisi
Problem için HackerRank üzerinden sağlanan altyapısı aşağıdaki gibi:
public static void main(String []argh)
{
Scanner sc = new Scanner(System.in);
int t=sc.nextInt();
for(int i=0;i<t;i++)
{
try
{
long x=sc.nextLong();
System.out.println(x+" can be fitted in:");
if(x>=-128 && x<=127)System.out.println("* byte");
//Complete the code
}
catch(Exception e)
{
System.out.println(sc.next()+" can't be fitted anywhere.");
}
}
}
Kaç tane sayı girileceği “t” değerinde tutulur. Girilecek sayılar integer tipinde herhangi bir veri tipi olabilir. Girilen sayıların hangi veri tipinde olduğunu print etmemiz gerekiyor. Eğer girilen sayı birden çok veri tipine uyuyorsa hepsini print edeceğiz. Eğer herhangi birine uymuyorsa “n can’t be fitted anywhere.” print edilecek.
byte < short < int < long
Örnek Input:
5
-150
150000
1500000000
213333333333333333333333333333333333
-100000000000000
Örnek Output:
-150 can be fitted in:
* short
* int
* long
150000 can be fitted in:
* int
* long
1500000000 can be fitted in:
* int
* long
213333333333333333333333333333333333 can't be fitted anywhere.
-100000000000000 can be fitted in:
* long
- 150 değeri hem short hem int hem de long veri tipiyle depolanabilir.
- 2133…33 değeri çok büyük olduğu için sadece long veri tipiyle depolanabilir.
Problem Çözümü
İlk çözümde veri tiplerinin alabileceği değerleri direkt yazıp sınır kontrolü yapıyoruz. try-catch yapısı eğer longdan farklı bir değer girildiyse yani integer bir veri tipi girilmediyse catch içerisine girip veri tipine uymadı yazmasına yarıyor.
public static void solutionOne() {
Scanner scannerIn = new Scanner(System.in);
int t = scannerIn.nextInt();
for (int i = 0; i < t; i++) {
try {
long x = scannerIn.nextLong();
System.out.println(x + " can be fitted in:");
if (x >= -128 && x <= 127)
System.out.println("* byte");
if (x >= -32768 && x <= 32767)
System.out.println("* short");
if (x >= -2147483648 && x <= 2147483647)
System.out.println("* int");
if (x >= -9223372036854775808L && x <= 9223372036854775807L)
System.out.println("* long");
} catch (Exception e) {
System.out.println(scannerIn.next() + " can't be fitted anywhere.");
}
}
}
İkinci sunduğum çözümde aslında genel mantığı değiştirmedim. Sınır kontrolü yapılırken direkt değerleri yazmak yerine Byte, Short, Integer ve Long sınıflarından yararlanıp MAX-MIN tanımlı static değerleri kullanıyoruz. Bu değerler sayesinde int değerinin max-min değerini ezberlemek ya da sürekli araştırmak zorunda kalmıyoruz :)
public static void solutionTwo() {
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
for (int i = 0; i < t; i++) {
try {
long x = sc.nextLong();
System.out.println(x + " can be fitted in:");
if (x >= Byte.MIN_VALUE && x <= Byte.MAX_VALUE) System.out.println("* byte");
if (x >= Short.MIN_VALUE && x <= Short.MAX_VALUE) System.out.println("* short");
if (x >= Integer.MIN_VALUE && x <= Integer.MAX_VALUE) System.out.println("* int");
if (x >= Long.MIN_VALUE && x <= Long.MAX_VALUE) System.out.println("* long");
} catch (Exception e) {
System.out.println(sc.next() + " can't be fitted anywhere.");
}
}
}
İki çözümde de bir for loop içerdiği için complexity O(n).
“ Java Datatypes” problemini de çözmüş olduk! Bol kodlu ama bug’sız günler dilerim :)
Tüm problemlerin çözümleri 👇
Bu yazıda kullandığım kaynak: “https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html”