29 กรกฎาคม 2556

[Android Code] การ Random ตัวเลขเบื้องต้น


        บทความนี้ก็ขอเป็นเรื่องพื้นฐานๆดีกว่า โดยจะเป็นเรื่องการสุ่มตัวเลข เพราะมีผู้ที่หลงเข้ามาอ่านหลายๆคนต้องการสุ่มค่าเพื่อดึงข้อมูล อยากจะสุ่มภาพมาแสดงบ้าง สุ่มข้อมูลจากฐานข้อมูลมาแสดงบ้าง ซึ่งการสุ่มใดๆก็ตาม ก็จะมีพื้นฐานมาจากตัวแปร Value ทั้งนั้น


        สำหรับการสุ่มอะไรก็ตาม เข้าใจก่อนว่ามาจากการสุ่มตัวเลขหนึ่งตัว เริ่มจากการสุ่มตัวเลขในช่วงของตัวเลขที่ต้องการมาก่อนหนึ่งตัวแล้วค่อยเอาตัวเลขนั้นไประบุข้อมูลที่จะนำมาใช้งานอีกทีหนึ่ง ดังนี้
String[] str_array = { "Ant", "Bird", "Cat" }; int n = สุ่มค่าตัวเลขระหว่าง 0 ถึง str_array.lenght; String str_random = str_array[n];
        จากตัวอย่างก็คือ เจ้าของบล็อกประกาศ String Array ไว้สามตัว จากนั้นก็ให้สุ่มค่าตัวเลขระหว่าง 0 ถึง 2 มาเก็บไว้ในตัวแปร n แล้วประกาศ String ขึ้นมาโดยให้มีค่าเป็น String Array ตัวที่ n สมมติว่า n สุ่มได้เป็น 0 ก็จะได้เป็น "Ant" ถ้าเป็น 2 ก็เป็น "Cat"

        แม้แต่การสุ่มภาพจาก Drawable ก็ตาม ก็ใช้หลักการเดียวกัน
int[] image_list = { R.drawable.image1, R.drawable.image2 , R.drawable.image3, R.drawable.image4 , R.drawable.image5, R.drawable.image6 }; int n = สุ่มค่าตัวเลขระหว่าง 0 ถึง image_list.lenght; ImageView iv= (ImageView)findViewById(R.id.imageView); iv.setImageResource(image_list[n]);

        และสมมติว่าดึงข้อมูลจากฐานข้อมูล (ขอย่อโค๊ดหน่อยนะ)
Database mHelper = new Database(this); SQLiteDatabase mDb = mHelper.getWritableDatabase(); Cursor mCursor = mDb.rawQuery("SELECT * FROM Table", null); int n = สุ่มค่าตัวเลขระหว่าง 0 ถึง mCursor.getCount(); mCursor.moveToPosition(n); String id = mCursor.getString(mCursor.getColumnIndex(COL_ID)); String name = mCursor.getString(mCursor.getColumnIndex(COL_NAME)); mHelper.close(); mDb.close(); 
        จะเห็นได้ว่า ไม่ว่าจะสุ่มอะไรก็ตาม ก็ต้องเริ่มจากสุ่มตัวเลขทั้งหมด

        ทีนี้จะยกตัวอย่างต่อมาก็คือการสุ่มตัวเลขจำนวนหลายๆตัว โดยเริ่มแบบเดิมนั่นแหละ สุ่มตัวเลขทีละตัวแล้วเก็บใน Array
int[] rand_int = new int[10]; for(int i = 0 ; i < rand_int ; i++) { rand_int[i] = สุ่มตัวเลขระหว่าง 0 ถึง x; } // นำ rand_int ไปใช้งานได้เลย

        ทีนี้มาดูคำสั่งสุ่มตัวเลขกันก่อน เพราะยังไม่เห็นมีคำสั่งสุ่มตัวเลขเลย การสุ่มตัวเลขจะมีอยู่สองแบบคือใช้คลาส Math และคลาส Random

        ก่อนอื่นก็ขอพูดถึงการสุ่มด้วยคลาส Math ก่อนละกันนะ คลาส Math ก็จะมีคำสั่งสุ่มตัวเลขอยู่ โดยให้ค่าออกมาเป็น Double
double rand_double = Math.rand();

        โดยค่า Double ที่ได้จากการสุ่มจะมีค่าตั้งแต่ 0 ถึง 1 เท่านั้น ถ้าต้องการให้ค่าออกมาอยู่ในช่วงที่ต้องการก็ต้องเอามาคำนวณ สมมติว่าต้องการให้ค่าอยู่ในช่วง 0 ถึง 29 ถ้าเอาแบบง่ายๆก็ดังนี้
double rand_double = Math.rand(); int result_d = (int)(rand_double * 29);

        แต่ว่าวิธีนี้ก็ไม่ค่อยแนะนำซักเท่าไร ถึงจะดูง่ายก็ตาม เพราะว่าค่าจะอยู่ในช่วง X >= 0.0 และ X < 1.0 หรือ [0.0, 1.0) เท่านั้น


        ผู้ที่หลงเข้ามาอ่านบางคนอาจจะยังมองไม่ออก ณ จุดนี้ ก็คือค่าที่สุ่มออกมาจากคำสั่งนี้ไม่มีทางที่จะเป็น 1 เลย เพราะค่าที่ได้น้อยกว่า 1 ตลอด (0.9999999999999999) ดังนั้นการคูณด้วย 29 ทำให้ค่าที่ได้ไม่มีทางเท่ากับ 29 จึงใช้วิธีดึงตัวเลขทศนิยมตัวที่ 1 ถึง 9 แล้วหาร 29 หาเศษ


double rand_double = Math.rand(); int result_d = (int)((rand_double * 1000000000) % (29 + 1)); 
        จะเห็นว่าเจ้าของบล็อกใช้วิธีการหารแบบหาเศษเอา โดยต้องบวกเพิ่มจากค่าที่ต้องการไปอีก 1 ด้วย เพราะการหารด้วย 29 ไม่มีทางได้เศษเป็น 29 อยู่แล้ว จึงบวกเพิ่มเข้าไปอีก 1 เพื่อให้เป็น 30 จะได้มีเศษ 29

        สมมติว่าต้องการค่าระหว่าง 0 ถึง 8 โดยมีทศนิยม 2 ตำแหน่ง
double rand_double = Math.rand(); int result_d = (double)((int)((d * 1000000000) % (800 + 1))) / 100;

        สมมติต่อว่าต้องการค่าระหว่าง 0 ถึง 50 โดยมีทศนิยม 3 ตำแหน่ง
double rand_double = Math.rand(); int result_d = (double)((int)((d * 1000000000) % (50000 + 1))) / 1000;

        และก็สมมติว่าต้องการค่าระหว่าง 5 ถึง 15 โดยมีทศนิยม 1 ตำแหน่ง
double rand_double = Math.rand(); int result_d = ((double)((int)((d * 1000000000) % ((150 - 50) + 1))) / 10) + 5;

        จริงๆแล้วก็ขึ้นอยู่กับวิธีคิดของแต่ละคนแหละ ไม่ได้ตายตัว แต่ควรจะให้ค่าที่สุ่มออกมามีความเป็นไปได้ที่ครอบคลุมด้วย

        ทีนี้มาดูการใช้คลาส Random บ้าง ซึ่งง่ายกว่า Math.rand() สำหรับคลาส Random จะสามารถสุ่มค่าได้เป็นตัวแปรหลายแบบดังนี้

                Boolean / Byte / Double / Float / Double(Gaussian) / Integer / Long

Random r = new Random(); boolean r_bool = r.nextBoolean(); double r_double = r.nextDouble(); float r_float = r.nextFloat(); double r_gaussian = r.nextGaussian(); int r_int = r.nextInt(); long r_long = r.nextLong(); 
        สำหรับ Boolean ก็จะสุ่มออกมาได้สองค่าคือ True กับ False ส่วน Double และ Float สุ่มออกมาได้เป็น X >= 0 และ X < 1 ซึ่งค่าที่ได้เหมือนกับกรณีที่ใช้คำสั่ง Math.rand() นั่นเอง ส่วน Gaussian เป็นแบบ Ganssian Distribution ที่ได้เป็น Double ซึ่งการสุ่มแบบอื่นๆในคลาส Random จะเป็นแบบ Uniform Distribution และนอกจากนี้ยังมี Byte ที่จะพิเศษหน่อย และ Integer จะมีคำสั่งอีกแบบ

        สำหรับ Byte จะไม่ได้สุ่มค่า Byte ธรรมดาๆ เพราะว่าค่า Byte  มีค่าได้ตั้งแต่ -128 ถึง 127 เท่านั้น ซึ่งปกติก็ใช้ Integer แทนได้ แต่ nextBytes ในคลาส Random จะเป็นการสุ่มตัวแปร Byte Array หรือก็คือสุ่มตัวแปร Byte จำนวนหลายๆชุดด้วยกันนั่นเอง เหมาะสำหรับกรณีที่ต้องการสุ่มค่าหลายๆตัวด้วยกัน
Random r = new Random(); byte[] r_bytes = new byte[10]; r.nextBytes(r_bytes); 
        ผู้ที่หลงเข้ามาอ่านสามารถกำหนดได้ว่าจะให้สุ่มกี่ตัว โดยกำหนดที่จำนวน Byte Array แล้วคำสั่งจะจัดการเอง จากตัวอย่างก็จะได้ค่าสุ่มตั้งแต่ -127 ถึง 128 จำนวน 10 ตัว

        ทีนี้มาดูกันต่อที่คำสั่ง Integer อีกแบบหนึ่ง ซึ่งเจ้าของบล็อกใช้บ่อย เพราะเป็นคำสั่งที่สามารถกำหนดขอบเขตของการสุ่มได้เลย
Random r = new Random(); int r_int = r.nextInt(9); 
        ซึ่ง 9 หมายถึงจำนวนข้อมูล ไม่ใช่ว่าค่าเป็นไปได้สูงสุดคือ 9  เพราะว่าเวลาสุ่มค่า จะเริ่มจาก 0 และค่าสูงสุดจะได้เป็น 8 ถ้านับจาก 0 ไปจนถึง 8 ก็จะมีความเป็นไปได้ 9 แบบนั่นเอง

        ขออธิบายคำสั่ง nextInt แบบกำหนดจำนวนข้อมูลเพิ่มหน่อย เพราะเจ้าของบล็อกใช้แต่คำสั่งนี้เพื่อสุ่มข้อมูลมากกว่า

        สมมติต้องการค่าที่อยู่ระหว่าง 0 ถึง 99 ก็ใช้คำสั่งดังนี้
Random r = new Random(); int r_int = r.nextInt(99 + 1); 
        เจ้าของบล็อกจะใช้ + 1 เพิ่มเข้าไปแทนเพื่อให้ง่ายต่อการเข้าใจ

        สมมติต้องการค่าที่อยู่ระหว่าง 125 ถึง 384 ก็ใช้คำสั่งดังนี้
Random r = new Random(); int r_int = r.nextInt((384 - 125) + 1) + 125;

        สมมติว่าต้องการค่าระหว่าง 0 - 18 มีทศนิยม 2 ตำแหน่ง ใช้คำสั่งดังนี้
Random r = new Random(); float r_float = (float)(r.nextInt((18 * 100) + 1)) / 100;

        และสมมติว่าต้องการค่าระหว่าง 20 - 101 มีทศนิยม 3 ตำแหน่ง ใช้คำสั่งดังนี้
Random r = new Random(); int r_float = ((float)(r.nextInt((101 - 20) * 1000 + 1)) / 1000) + 20;

        หมดล่ะสำหรับตัวอย่างการสุ่มตัวเลขเบื้องต้นจากเจ้าของบล็อก ที่เหลือก็ขึ้นอยู่กับผู้ที่หลงเข้ามาอ่านแล้วล่ะ ว่าจะเอาไปใช้งานยังไง



บทความที่เกี่ยวข้อง

        • การ Random ตัวเลขจำนวนหลายๆตัว
        • การ Random ชุดสีที่เตรียมไว้มาแสดง




เหล่าพันธมิตรแอนดรอยด์

Devahoy Layer Net NuuNeoI The Cheese Factory Somkiat CC Mart Routine Artit-K Arnondora Kamonway Try to be android developer Oatrice Benz Nest Studios Kotchaphan@Medium Jirawatee@Medium Travispea@Medium