มีวิธี neater สำหรับการรับความยาวของ int กว่าวิธีนี้หรือไม่?
int length = String.valueOf(1000).length();
มีวิธี neater สำหรับการรับความยาวของ int กว่าวิธีนี้หรือไม่?
int length = String.valueOf(1000).length();
คำตอบ:
โซลูชันที่อิงกับสตริงของคุณนั้นใช้ได้อย่างสมบูรณ์แบบไม่มีสิ่งใดที่ "ไม่เรียบร้อย" เกี่ยวกับมัน คุณต้องตระหนักว่าในทางคณิตศาสตร์ตัวเลขไม่มีความยาวหรือไม่มีตัวเลข ความยาวและตัวเลขเป็นคุณสมบัติทั้งสองของการแสดงทางกายภาพของตัวเลขในฐานที่เฉพาะเจาะจงเช่นสตริง
วิธีแก้ปัญหาแบบลอการิทึม (บางส่วน) เป็นแบบเดียวกับที่ใช้แบบสตริงภายในและอาจทำได้เร็วกว่าเล็กน้อย (ไม่สำคัญ) เพราะมันผลิตความยาวและไม่สนใจตัวเลข แต่ฉันจะไม่คิดว่ามันชัดเจนในเจตนา - และนั่นคือปัจจัยที่สำคัญที่สุด
Math.abs()
จะแก้ไขปัญหานี้ได้
ลอการิทึมเป็นเพื่อนของคุณ:
int n = 1000;
int length = (int)(Math.log10(n)+1);
NB: ใช้ได้กับ n> 0 เท่านั้น
วิธีที่เร็วที่สุด: แบ่งและพิชิต
สมมติว่าช่วงของคุณคือ 0 ถึง MAX_INT จากนั้นคุณมี 1 ถึง 10 หลัก คุณสามารถเข้าใกล้ช่วงเวลานี้โดยใช้การหารและพิชิตโดยมีการเปรียบเทียบสูงสุดถึง 4 การเปรียบเทียบสำหรับแต่ละอินพุต ก่อนอื่นคุณแบ่ง [1..10] เป็น [1..5] และ [6..10] ด้วยการเปรียบเทียบหนึ่งครั้งจากนั้นแต่ละช่วงความยาว 5 คุณแบ่งโดยใช้การเปรียบเทียบหนึ่งรายการเป็นหนึ่งความยาว 3 และหนึ่งช่วงเวลาความยาว 2 ช่วงเวลาความยาว 2 ต้องการการเปรียบเทียบอีกหนึ่งรายการ (การเปรียบเทียบทั้ง 3 รายการ) ช่วงเวลาความยาว 3 สามารถแบ่งออกเป็นช่วงเวลาความยาว 1 (โซลูชัน) และช่วงเวลาความยาว 2 ดังนั้นคุณต้องเปรียบเทียบ 3 หรือ 4
ไม่มีแผนกไม่มีการดำเนินการจุดลอยไม่มีลอการิทึมราคาแพงการเปรียบเทียบจำนวนเต็มเท่านั้น
รหัส (ยาว แต่เร็ว):
if (n < 100000){
// 5 or less
if (n < 100){
// 1 or 2
if (n < 10)
return 1;
else
return 2;
}else{
// 3 or 4 or 5
if (n < 1000)
return 3;
else{
// 4 or 5
if (n < 10000)
return 4;
else
return 5;
}
}
} else {
// 6 or more
if (n < 10000000) {
// 6 or 7
if (n < 1000000)
return 6;
else
return 7;
} else {
// 8 to 10
if (n < 100000000)
return 8;
else {
// 9 or 10
if (n < 1000000000)
return 9;
else
return 10;
}
}
}
เบนช์มาร์ก (หลังจากการอุ่นเครื่อง JVM) - ดูรหัสด้านล่างเพื่อดูว่าเกณฑ์มาตรฐานทำงานอย่างไร:
รหัสเต็ม:
public static void main(String[] args)
throws Exception
{
// validate methods:
for (int i = 0; i < 1000; i++)
if (method1(i) != method2(i))
System.out.println(i);
for (int i = 0; i < 1000; i++)
if (method1(i) != method3(i))
System.out.println(i + " " + method1(i) + " " + method3(i));
for (int i = 333; i < 2000000000; i += 1000)
if (method1(i) != method3(i))
System.out.println(i + " " + method1(i) + " " + method3(i));
for (int i = 0; i < 1000; i++)
if (method1(i) != method4(i))
System.out.println(i + " " + method1(i) + " " + method4(i));
for (int i = 333; i < 2000000000; i += 1000)
if (method1(i) != method4(i))
System.out.println(i + " " + method1(i) + " " + method4(i));
// work-up the JVM - make sure everything will be run in hot-spot mode
allMethod1();
allMethod2();
allMethod3();
allMethod4();
// run benchmark
Chronometer c;
c = new Chronometer(true);
allMethod1();
c.stop();
long baseline = c.getValue();
System.out.println(c);
c = new Chronometer(true);
allMethod2();
c.stop();
System.out.println(c + " = " + StringTools.formatDouble((double)baseline / c.getValue() , "0.00") + " times as fast as baseline");
c = new Chronometer(true);
allMethod3();
c.stop();
System.out.println(c + " = " + StringTools.formatDouble((double)baseline / c.getValue() , "0.00") + " times as fast as baseline");
c = new Chronometer(true);
allMethod4();
c.stop();
System.out.println(c + " = " + StringTools.formatDouble((double)baseline / c.getValue() , "0.00") + " times as fast as baseline");
}
private static int method1(int n)
{
return Integer.toString(n).length();
}
private static int method2(int n)
{
if (n == 0)
return 1;
return (int)(Math.log10(n) + 1);
}
private static int method3(int n)
{
if (n == 0)
return 1;
int l;
for (l = 0 ; n > 0 ;++l)
n /= 10;
return l;
}
private static int method4(int n)
{
if (n < 100000)
{
// 5 or less
if (n < 100)
{
// 1 or 2
if (n < 10)
return 1;
else
return 2;
}
else
{
// 3 or 4 or 5
if (n < 1000)
return 3;
else
{
// 4 or 5
if (n < 10000)
return 4;
else
return 5;
}
}
}
else
{
// 6 or more
if (n < 10000000)
{
// 6 or 7
if (n < 1000000)
return 6;
else
return 7;
}
else
{
// 8 to 10
if (n < 100000000)
return 8;
else
{
// 9 or 10
if (n < 1000000000)
return 9;
else
return 10;
}
}
}
}
private static int allMethod1()
{
int x = 0;
for (int i = 0; i < 1000; i++)
x = method1(i);
for (int i = 1000; i < 100000; i += 10)
x = method1(i);
for (int i = 100000; i < 1000000; i += 100)
x = method1(i);
for (int i = 1000000; i < 2000000000; i += 200)
x = method1(i);
return x;
}
private static int allMethod2()
{
int x = 0;
for (int i = 0; i < 1000; i++)
x = method2(i);
for (int i = 1000; i < 100000; i += 10)
x = method2(i);
for (int i = 100000; i < 1000000; i += 100)
x = method2(i);
for (int i = 1000000; i < 2000000000; i += 200)
x = method2(i);
return x;
}
private static int allMethod3()
{
int x = 0;
for (int i = 0; i < 1000; i++)
x = method3(i);
for (int i = 1000; i < 100000; i += 10)
x = method3(i);
for (int i = 100000; i < 1000000; i += 100)
x = method3(i);
for (int i = 1000000; i < 2000000000; i += 200)
x = method3(i);
return x;
}
private static int allMethod4()
{
int x = 0;
for (int i = 0; i < 1000; i++)
x = method4(i);
for (int i = 1000; i < 100000; i += 10)
x = method4(i);
for (int i = 100000; i < 1000000; i += 100)
x = method4(i);
for (int i = 1000000; i < 2000000000; i += 200)
x = method4(i);
return x;
}
มาตรฐานอีกครั้ง:
แก้ไข: หลังจากที่ฉันเขียนเกณฑ์มาตรฐานฉันได้แอบเข้าไปใน Integer.toString จาก Java 6 และฉันพบว่ามันใช้:
final static int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999,
99999999, 999999999, Integer.MAX_VALUE };
// Requires positive x
static int stringSize(int x) {
for (int i=0; ; i++)
if (x <= sizeTable[i])
return i+1;
}
ฉันเปรียบเทียบกับโซลูชันแบ่งและพิชิตของฉัน:
Mine มีความเร็วประมาณ 4x เท่าโซลูชัน Java 6
n<100000?n<100?n<10?1:2:n<1000?3:n<10000?4:5:n<10000000?n<1000000?6:7:n<100000000?8:n<1000000000?9:10
สองความคิดเห็นเกี่ยวกับเกณฑ์มาตรฐานของคุณ: Java เป็นสภาพแวดล้อมที่ซับซ้อนสิ่งที่มีเพียงการรวบรวมเวลาและการเก็บขยะและอื่น ๆ เพื่อให้ได้รับการเปรียบเทียบที่ยุติธรรมเมื่อใดก็ตามที่ฉันใช้มาตรฐานฉันมักจะ: (a) ล้อมรอบการทดสอบทั้งสอง ในลูปที่รันพวกมันตามลำดับ 5 หรือ 10 ครั้ง บ่อยครั้งที่รันไทม์ของการผ่านครั้งที่สองผ่านลูปนั้นค่อนข้างแตกต่างจากครั้งแรก และ (b) หลังจาก "เข้าใกล้" ทุกครั้งฉันจะทำ System.gc () เพื่อพยายามเรียกชุดเก็บขยะ มิฉะนั้นวิธีแรกอาจสร้างกลุ่มของวัตถุ แต่ไม่เพียงพอที่จะบังคับให้รวบรวมขยะจากนั้นวิธีที่สองจะสร้างวัตถุสองสามชิ้นฮีปจะหมดและเรียกใช้การรวบรวมขยะ จากนั้นแนวทางที่สองจะถูก "เรียกเก็บเงิน" เพื่อเก็บขยะที่เหลือโดยวิธีแรก ไม่ยุติธรรมมาก!
ที่กล่าวว่าไม่ได้สร้างความแตกต่างอย่างมีนัยสำคัญในตัวอย่างนี้
ไม่ว่าจะมีการดัดแปลงหรือไม่ก็ตามฉันได้ผลลัพธ์ที่แตกต่างจากที่คุณทำ เมื่อฉันรันสิ่งนี้ใช่วิธี toString ให้เวลารัน 6400 ถึง 6600 มิลลิวินาทีในขณะที่วิธีการบันทึกมีค่าสูงสุด 20,000 ถึง 20,400 มิลลิวินาที แทนที่จะเป็นเร็วขึ้นเล็กน้อยวิธีการบันทึกก็ช้าลง 3 เท่าสำหรับฉัน
โปรดทราบว่าทั้งสองวิธีเกี่ยวข้องกับค่าใช้จ่ายที่แตกต่างกันมากดังนั้นจึงไม่น่าตกใจอย่างสิ้นเชิง: วิธี toString จะสร้างวัตถุชั่วคราวจำนวนมากที่ต้องทำความสะอาดในขณะที่วิธีการบันทึกใช้การคำนวณที่เข้มข้นกว่า ดังนั้นความแตกต่างก็คือบนเครื่องที่มีหน่วยความจำน้อย toString ต้องใช้การรวบรวมขยะมากขึ้นในขณะที่บนเครื่องที่มีโปรเซสเซอร์ที่ช้ากว่าการคำนวณเพิ่มเติมของบันทึกจะเจ็บปวดมากขึ้น
ฉันยังลองวิธีที่สาม ฉันเขียนฟังก์ชันเล็ก ๆ นี้:
static int numlength(int n)
{
if (n == 0) return 1;
int l;
n=Math.abs(n);
for (l=0;n>0;++l)
n/=10;
return l;
}
นั่นวิ่งใน 1,600 ถึง 1,900 millis - น้อยกว่า 1/3 ของวิธี toString และ 1/10 วิธีเข้าสู่ระบบในเครื่องของฉัน
หากคุณมีตัวเลขจำนวนมากคุณสามารถเร่งความเร็วได้มากขึ้นโดยเริ่มจากการหารด้วย 1,000 หรือ 1,000,000 เพื่อลดจำนวนครั้งในการวนซ้ำ ฉันไม่ได้เล่นกับสิ่งนั้น
ใช้จาวา
int nDigits = Math.floor(Math.log10(Math.abs(the_integer))) + 1;
ใช้import java.lang.Math.*;
ในการเริ่มต้น
ใช้ C.
int nDigits = floor(log10(abs(the_integer))) + 1;
ใช้inclue math.h
ในการเริ่มต้น
the_integer
เป็น0
เช่นนั้นตรวจสอบสิ่งนั้น
ยังไม่สามารถแสดงความคิดเห็นได้ดังนั้นฉันจะโพสต์เป็นคำตอบแยกต่างหาก
วิธีแก้ปัญหาแบบลอการิทึมไม่ได้คำนวณจำนวนหลักที่ถูกต้องสำหรับจำนวนเต็มที่มีขนาดใหญ่มากเช่น:
long n = 99999999999999999L;
// correct answer: 17
int numberOfDigits = String.valueOf(n).length();
// incorrect answer: 18
int wrongNumberOfDigits = (int) (Math.log10(n) + 1);
วิธีแก้ปัญหาแบบลอการิทึมคำนวณจำนวนหลักที่ไม่ถูกต้องในจำนวนเต็มขนาดใหญ่
เนื่องจากจำนวนหลักในฐาน 10 ของจำนวนเต็มเป็น1 + truncate (log10 (number))คุณสามารถทำได้:
public class Test {
public static void main(String[] args) {
final int number = 1234;
final int digits = 1 + (int)Math.floor(Math.log10(number));
System.out.println(digits);
}
}
แก้ไขเนื่องจากการแก้ไขล่าสุดของฉันแก้ไขตัวอย่างรหัส แต่ไม่ใช่คำอธิบาย
Math.floor
เป็นซ้ำซ้อนบิตไม่ได้หรือไม่ การร่ายint
จะทำให้มันกลมลงเลยล่ะค่ะ
โซลูชันของ Marian ดัดแปลงมาสำหรับหมายเลขแบบยาว (มากถึง 9,223,372,036,854,775,807) ในกรณีที่มีคนต้องการคัดลอกและวาง ในโปรแกรมฉันเขียนสิ่งนี้สำหรับตัวเลขที่มากถึง 10,000 มีความเป็นไปได้มากกว่าดังนั้นฉันจึงสร้างสาขาเฉพาะสำหรับพวกเขา อย่างไรก็ตามมันจะไม่สร้างความแตกต่างอย่างมีนัยสำคัญ
public static int numberOfDigits (long n) {
// Guessing 4 digit numbers will be more probable.
// They are set in the first branch.
if (n < 10000L) { // from 1 to 4
if (n < 100L) { // 1 or 2
if (n < 10L) {
return 1;
} else {
return 2;
}
} else { // 3 or 4
if (n < 1000L) {
return 3;
} else {
return 4;
}
}
} else { // from 5 a 20 (albeit longs can't have more than 18 or 19)
if (n < 1000000000000L) { // from 5 to 12
if (n < 100000000L) { // from 5 to 8
if (n < 1000000L) { // 5 or 6
if (n < 100000L) {
return 5;
} else {
return 6;
}
} else { // 7 u 8
if (n < 10000000L) {
return 7;
} else {
return 8;
}
}
} else { // from 9 to 12
if (n < 10000000000L) { // 9 or 10
if (n < 1000000000L) {
return 9;
} else {
return 10;
}
} else { // 11 or 12
if (n < 100000000000L) {
return 11;
} else {
return 12;
}
}
}
} else { // from 13 to ... (18 or 20)
if (n < 10000000000000000L) { // from 13 to 16
if (n < 100000000000000L) { // 13 or 14
if (n < 10000000000000L) {
return 13;
} else {
return 14;
}
} else { // 15 or 16
if (n < 1000000000000000L) {
return 15;
} else {
return 16;
}
}
} else { // from 17 to ...¿20?
if (n < 1000000000000000000L) { // 17 or 18
if (n < 100000000000000000L) {
return 17;
} else {
return 18;
}
} else { // 19? Can it be?
// 10000000000000000000L is'nt a valid long.
return 19;
}
}
}
}
}
วิธีการสตริงอื่น สั้นและหวาน - n
สำหรับจำนวนเต็มใด
int length = ("" + n).length();
n
และศูนย์เท่านั้น สามารถใช้("" + Math.abs(n)).length()
เพื่อรับความยาวของจำนวนเต็มลบ
ฉันลองได้ไหม ;)
ขึ้นอยู่กับการแก้ปัญหาของเดิร์ค
final int digits = number==0?1:(1 + (int)Math.floor(Math.log10(Math.abs(number))));
คณิตศาสตร์โบราณแบบธรรมดาเป็นอย่างไร? หารด้วย 10 จนกว่าคุณจะถึง 0
public static int getSize(long number) {
int count = 0;
while (number > 0) {
count += 1;
number = (number / 10);
}
return count;
}
Long.MAX_VALUE
ซึ่งเป็นกรณีที่ซับซ้อนที่สุดของรหัสของคุณและใช้System.nanoTime()
ในการทดลองตอกบัตรกับกรณีที่ซับซ้อนที่สุดของโซลูชันอื่น ++ ที่จริงแล้วลองใช้อาร์เรย์ที่เต็มไปด้วยชุดเครื่องมือสุ่มที่ตั้งค่าไว้ที่ช่วง0
ไปจนถึงLong.MAX_VALUE
เช่นเดียวกับการทดสอบ "ความซับซ้อนโดยเฉลี่ย" ++ คุณอาจพบผลลัพธ์ ... น่าตกใจมาก
int,
วนซ้ำนี้จะดำเนินการสูงสุด 11 ครั้ง คุณมีหลักฐานยืนยันหรือไม่?
ทางออกของ Marian ตอนนี้พร้อม Ternary:
public int len(int n){
return (n<100000)?((n<100)?((n<10)?1:2):(n<1000)?3:((n<10000)?4:5)):((n<10000000)?((n<1000000)?6:7):((n<100000000)?8:((n<1000000000)?9:10)));
}
เพราะเราทำได้
อยากรู้อยากเห็นฉันพยายามที่จะสร้างมาตรฐาน ...
import org.junit.Test;
import static org.junit.Assert.*;
public class TestStack1306727 {
@Test
public void bench(){
int number=1000;
int a= String.valueOf(number).length();
int b= 1 + (int)Math.floor(Math.log10(number));
assertEquals(a,b);
int i=0;
int s=0;
long startTime = System.currentTimeMillis();
for(i=0, s=0; i< 100000000; i++){
a= String.valueOf(number).length();
s+=a;
}
long stopTime = System.currentTimeMillis();
long runTime = stopTime - startTime;
System.out.println("Run time 1: " + runTime);
System.out.println("s: "+s);
startTime = System.currentTimeMillis();
for(i=0,s=0; i< 100000000; i++){
b= number==0?1:(1 + (int)Math.floor(Math.log10(Math.abs(number))));
s+=b;
}
stopTime = System.currentTimeMillis();
runTime = stopTime - startTime;
System.out.println("Run time 2: " + runTime);
System.out.println("s: "+s);
assertEquals(a,b);
}
}
ผลลัพธ์คือ:
เวลารัน 1: 6765 s: 400000000 เวลารัน 2: 6000 s: 400000000
ตอนนี้ฉันถูกทิ้งให้สงสัยว่าเกณฑ์มาตรฐานของฉันจริง ๆ แล้วหมายถึงบางสิ่ง แต่ฉันได้รับผลลัพธ์ที่สอดคล้องกัน (การเปลี่ยนแปลงภายในมิลลิวินาที) มากกว่าการทดสอบมาตรฐานหลายตัวเอง ... :) ดูเหมือนว่ามันไร้ประโยชน์ที่จะลองและเพิ่มประสิทธิภาพ ...
แก้ไข: ตามความคิดเห็นของ ptomli ฉันแทนที่ 'number' โดย 'i' ในรหัสด้านบนและได้ผลลัพธ์ต่อไปนี้มากกว่า 5 การรันของผู้พิพากษา:
เวลารัน 1: 11500 s: 788888890 เวลารัน 2: 8547 s: 788888890 เวลารัน 1: 11485 s: 788888890 เวลารัน 2: 8547 s: 788888890 เวลารัน 1: 11469 s: 788888890 เวลารัน 2: 8547 s: 788888890 เวลารัน 1: 11500 s: 788888890 เวลารัน 2: 8547 s: 788888890 เวลารัน 1: 11484 s: 788888890 เวลารัน 2: 8547 s: 788888890
วิธีการแบบวนซ้ำนี้
private static int length = 0;
public static int length(int n) {
length++;
if((n / 10) < 10) {
length++;
} else {
length(n / 10);
}
return length;
}
ทางออกที่ง่าย:
public class long_length {
long x,l=1,n;
for (n=10;n<x;n*=10){
if (x/n!=0){
l++;
}
}
System.out.print(l);
}
ทางออกที่ง่ายมาก:
public int numLength(int n) {
for (int length = 1; n % Math.pow(10, length) != n; length++) {}
return length;
}
หรือแทนความยาวที่คุณสามารถตรวจสอบว่าหมายเลขมีขนาดใหญ่กว่าหรือเล็กกว่านั้นตามจำนวนที่ต้องการ
public void createCard(int cardNumber, int cardStatus, int customerId) throws SQLException {
if(cardDao.checkIfCardExists(cardNumber) == false) {
if(cardDao.createCard(cardNumber, cardStatus, customerId) == true) {
System.out.println("Card created successfully");
} else {
}
} else {
System.out.println("Card already exists, try with another Card Number");
do {
System.out.println("Enter your new Card Number: ");
scan = new Scanner(System.in);
int inputCardNumber = scan.nextInt();
cardNumber = inputCardNumber;
} while(cardNumber < 95000000);
cardDao.createCard(cardNumber, cardStatus, customerId);
}
}
}
ฉันยังไม่เห็นโซลูชันที่ใช้การคูณ การแก้ปัญหาลอการิทึมการหารและการใช้สตริงจะค่อนข้างไม่สะดวกกับกรณีทดสอบหลายล้านครั้งดังนั้นนี่คือหนึ่งในints
:
/**
* Returns the number of digits needed to represents an {@code int} value in
* the given radix, disregarding any sign.
*/
public static int len(int n, int radix) {
radixCheck(radix);
// if you want to establish some limitation other than radix > 2
n = Math.abs(n);
int len = 1;
long min = radix - 1;
while (n > min) {
n -= min;
min *= radix;
len++;
}
return len;
}
ในฐาน 10 งานนี้เพราะ n ถูกเปรียบเทียบกับ 9, 99, 999 ... เนื่องจาก min คือ 9, 90, 900 ... และ n ถูกลบด้วย 9, 90, 900 ...
น่าเสียดายที่นี่ไม่สามารถพกพาไปได้long
ด้วยการแทนที่ทุกกรณีint
เนื่องจากล้น ในทางกลับกันมันเกิดขึ้นเพียงเพื่อจะได้ฐาน 2 และ 10 (แต่ไม่ดีสำหรับฐานอื่น ๆ ส่วนใหญ่) คุณจะต้องมีตารางการค้นหาคะแนนล้น (หรือการทดสอบการหาร ... ew)
/**
* For radices 2 &le r &le Character.MAX_VALUE (36)
*/
private static long[] overflowpt = {-1, -1, 4611686018427387904L,
8105110306037952534L, 3458764513820540928L, 5960464477539062500L,
3948651115268014080L, 3351275184499704042L, 8070450532247928832L,
1200757082375992968L, 9000000000000000000L, 5054470284992937710L,
2033726847845400576L, 7984999310198158092L, 2022385242251558912L,
6130514465332031250L, 1080863910568919040L, 2694045224950414864L,
6371827248895377408L, 756953702320627062L, 1556480000000000000L,
3089447554782389220L, 5939011215544737792L, 482121737504447062L,
839967991029301248L, 1430511474609375000L, 2385723916542054400L,
3902460517721977146L, 6269893157408735232L, 341614273439763212L,
513726300000000000L, 762254306892144930L, 1116892707587883008L,
1617347408439258144L, 2316231840055068672L, 3282671350683593750L,
4606759634479349760L};
public static int len(long n, int radix) {
radixCheck(radix);
n = abs(n);
int len = 1;
long min = radix - 1;
while (n > min) {
len++;
if (min == overflowpt[radix]) break;
n -= min;
min *= radix;
}
return len;
}
ด้วยการออกแบบ (ขึ้นอยู่กับปัญหา) นี่คือทางเลือกของการหารและพิชิต ก่อนอื่นเราจะกำหนด enum (พิจารณาเฉพาะสำหรับ int ที่ไม่ได้ลงชื่อ)
public enum IntegerLength {
One((byte)1,10),
Two((byte)2,100),
Three((byte)3,1000),
Four((byte)4,10000),
Five((byte)5,100000),
Six((byte)6,1000000),
Seven((byte)7,10000000),
Eight((byte)8,100000000),
Nine((byte)9,1000000000);
byte length;
int value;
IntegerLength(byte len,int value) {
this.length = len;
this.value = value;
}
public byte getLenght() {
return length;
}
public int getValue() {
return value;
}
}
ตอนนี้เราจะกำหนดคลาสที่ผ่านค่าของ enum และเปรียบเทียบและส่งคืนความยาวที่เหมาะสม
public class IntegerLenght {
public static byte calculateIntLenght(int num) {
for(IntegerLength v : IntegerLength.values()) {
if(num < v.getValue()){
return v.getLenght();
}
}
return 0;
}
}
เวลารันของโซลูชันนี้เหมือนกับวิธีแบ่งและพิชิต
num>=Nine.getValue()
ใช่
ใครอยากทำสิ่งนี้ส่วนใหญ่เพราะเขา / เธอต้องการที่จะ "นำเสนอ" ซึ่งส่วนใหญ่หมายความว่าในที่สุดมันก็จำเป็นต้องเป็น "toString-ed" (หรือเปลี่ยนแปลงในทางอื่น) อย่างชัดเจนหรือโดยปริยาย ก่อนที่จะสามารถนำเสนอ (พิมพ์ตัวอย่าง)
หากเป็นเช่นนั้นให้ลองทำการ "toString" ที่จำเป็นและนับจำนวนบิต
เราสามารถทำได้โดยใช้วนซ้ำ
public static int digitCount(int numberInput, int i) {
while (numberInput > 0) {
i++;
numberInput = numberInput / 10;
digitCount(numberInput, i);
}
return i;
}
public static void printString() {
int numberInput = 1234567;
int digitCount = digitCount(numberInput, 0);
System.out.println("Count of digit in ["+numberInput+"] is ["+digitCount+"]");
}
ฉันเขียนฟังก์ชันนี้หลังจากดูInteger.java
ซอร์สโค้ด
private static int stringSize(int x) {
final int[] sizeTable = {9, 99, 999, 9_999, 99_999, 999_999, 9_999_999,
99_999_999, 999_999_999, Integer.MAX_VALUE};
for (int i = 0; ; ++i) {
if (x <= sizeTable[i]) {
return i + 1;
}
}
}
ฉันเห็นผู้คนที่ใช้ห้องสมุด String หรือแม้กระทั่งใช้คลาส Integer ไม่มีอะไรผิดปกติ แต่อัลกอริทึมสำหรับการรับจำนวนหลักนั้นไม่ซับซ้อน ฉันใช้ตัวอย่างนี้มานาน แต่มันใช้ได้ดีกับ int
private static int getLength(long num) {
int count = 1;
while (num >= 10) {
num = num / 10;
count++;
}
return count;
}
ไม่มี String API, utils, ไม่มีการแปลงประเภท, เพียงแค่ทำซ้ำ java บริสุทธิ์ ->
public static int getNumberOfDigits(int input) {
int numOfDigits = 1;
int base = 1;
while (input >= base * 10) {
base = base * 10;
numOfDigits++;
}
return numOfDigits;
}
คุณสามารถลองใช้ค่าที่ยิ่งใหญ่กว่านี้ได้ถ้าต้องการ
int num = 02300;
int count = 0;
while(num>0){
if(num == 0) break;
num=num/10;
count++;
}
System.out.println(count);
วิธีการเวียนเกิดง่าย ๆ
int get_int_lenght(current_lenght, value)
{
if (value / 10 < 10)
return (current_lenght + 1);
return (get_int_lenght(current_lenght + 1, value))
}
ไม่ได้ทดสอบ
คุณสามารถใช้ตัวเลขโดยใช้การแบ่งต่อเนื่องสิบ:
int a=0;
if (no < 0) {
no = -no;
} else if (no == 0) {
no = 1;
}
while (no > 0) {
no = no / 10;
a++;
}
System.out.println("Number of digits in given number is: "+a);
ใส่จำนวนและสร้างและห่วงในขณะที่จะมีการบันทึกตัวเลขทั้งหมดไปยังArraylist
Arraylist
จากนั้นเราสามารถนำขนาดของอาร์เรย์ออกมาซึ่งจะเป็นความยาวของค่าจำนวนเต็มที่คุณป้อน
ArrayList<Integer> a=new ArrayList<>();
while(number > 0)
{
remainder = num % 10;
a.add(remainder);
number = number / 10;
}
int m=a.size();
นี่เป็นวิธีที่ง่ายมาก ๆ ที่ฉันใช้กับทุกหมายเลข:
public static int numberLength(int userNumber) {
int numberCounter = 10;
boolean condition = true;
int digitLength = 1;
while (condition) {
int numberRatio = userNumber / numberCounter;
if (numberRatio < 1) {
condition = false;
} else {
digitLength++;
numberCounter *= 10;
}
}
return digitLength;
}
วิธีการทำงานกับตัวแปรตัวนับหมายเลขคือ 10 = 1 พื้นที่ว่าง ตัวอย่างเช่น. 1 = 1 ในสิบ => พื้นที่ 1 หลัก ดังนั้นถ้าคุณมีint number = 103342;
คุณจะได้ 6 เพราะนั่นเท่ากับ. 000001 ช่องว่างด้านหลัง นอกจากนี้ทุกคนมีชื่อตัวแปรที่ดีกว่าnumberCounter
ใช่หรือไม่ ฉันไม่สามารถคิดอะไรดีขึ้น
แก้ไข: แค่คิดถึงคำอธิบายที่ดีกว่า โดยพื้นฐานแล้วสิ่งนี้ในขณะที่ลูปกำลังทำอยู่คุณสามารถหารหมายเลขด้วย 10 จนกว่ามันจะน้อยกว่าหนึ่ง โดยพื้นฐานแล้วเมื่อคุณแบ่งบางอย่างด้วย 10 คุณจะย้ายมันกลับเป็นช่องว่างหนึ่งหมายเลขดังนั้นคุณก็หารมันด้วย 10 จนกระทั่งคุณมาถึง <1 ตามจำนวนตัวเลขในจำนวนของคุณ
นี่เป็นอีกเวอร์ชั่นที่สามารถนับจำนวนตัวเลขเป็นทศนิยม:
public static int repeatingLength(double decimalNumber) {
int numberCounter = 1;
boolean condition = true;
int digitLength = 1;
while (condition) {
double numberRatio = decimalNumber * numberCounter;
if ((numberRatio - Math.round(numberRatio)) < 0.0000001) {
condition = false;
} else {
digitLength++;
numberCounter *= 10;
}
}
return digitLength - 1;
}
ลองแปลงintกับสตริงแล้วได้รับความยาวของสตริง ที่ควรจะได้รับความยาวของint
public static int intLength(int num){
String n = Integer.toString(num);
int newNum = n.length();
return newNum;
}
number
มีค่าลบ