นี่เป็นตัวเลขหรือไม่?


17

โหมโรง:

ฉันต้องการฝึกทำเคสทดสอบดังนั้นฉันจะลองทำสิ่งที่ง่าย

ท้าทาย:

รับอินพุต (สตริง) ใด ๆ (ภายในช่วง ASCII ที่มองเห็นได้) และอนุมานว่าเป็นตัวเลขและแสดงผลลัพธ์ที่สามารถใช้ในการประเมินได้หรือไม่

กฎ:

  • ตัวเลขจะประกอบด้วยอักขระเท่านั้น -0123456789,.
  • รู้รอบจำเป็นต้องใช้เพื่อรับรู้ตัวเลขระหว่าง -1000000000 ถึง 1000000000 (พิเศษ) แต่อาจรับรู้จำนวนมากโดยพล
  • คุณสามารถเขียนโปรแกรมเต็มรูปแบบหรือฟังก์ชั่น
  • หากตัวเลขให้ส่งคืนสิ่งใดก็ตามที่สามารถนำมาใช้เพื่อแยกแยะและจัดทำเอกสารผลลัพธ์ในคำอธิบาย (เช่นMy program outputs T if a number, F if not.)
  • ข้อมูลที่ป้อนจะเป็นจำนวนอักขระใด ๆ ภายในช่วง ASCII หรือว่างเปล่า (หากว่างเปล่าส่งคืนสิ่งที่คุณส่งออกหากไม่ใช่ตัวเลข)
  • ตัวเลขอาจมีจุดทศนิยม (เช่น3.14) หากมีจะต้องมีหลักอย่างน้อยหนึ่งหลักก่อนจุดทศนิยมและอย่างน้อยหนึ่งหลัก
  • ตัวเลขอาจมีเลขศูนย์นำหน้าหรือต่อท้าย (เช่น 000001.00000 )
  • ส่วนจำนวนเต็มของตัวเลขสามารถแบ่งออกเพื่อให้สามารถอ่านได้เป็นจำนวนสามหลักด้วยเครื่องหมายจุลภาค (เช่น1,000.23456) ในกรณีนี้พวกเขาจะต้องถูกแบ่งออกทุกสามตัวเลขจากขวาไปซ้าย (อดีต. 1,234,567, 10,000.202, 123,234.00, 0,123.293)
  • ตัวเลขเชิงลบถูกระบุโดยผู้นำหน้า-(เช่น-1.23) +ไม่อนุญาตให้นำไปสู่หมายเลขที่เป็นบวกและควรส่งออกผลลัพธ์เป็นเท็จ
  • ข้อยกเว้นจะไม่ถูกนับเป็นเอาต์พุตที่ถูกต้องและมองเห็นได้ (ยกเว้นเมื่อสามารถส่งเอาต์พุตไปยังสตรีมออกมาตรฐาน (เช่นException on line N [...]สามารถใส่เป็นเอาต์พุตสำหรับหมายเลข / ไม่ใช่ตัวเลข) หากสตริงถูกสตรีมมาตรฐาน

กรณีทดสอบ:

(สมมติว่าเป็นMy program outputs T if a number, F if not.เวอร์ชั่น)

123 -> T [on integer]
-123 -> T [negative numbers need to be handled]
0 -> T [on zero]
123.456 -> T [on floating point]
123,456.789 -> T [on evenly divided by 3 digits with comas]
123456789 -> T [thousand separators are not required]
0000001.00000 -> T [on leading/trailing zeros]
00.00 -> T [on zero and leading/trailing zeros]
999999999.9999999999999999999999999999999999999999999999999999 -> T [on close to the maximum value]
-999999999.9999999999999999999999999999999999999999999999999999 -> T [on close to the minimum value]
 -> F [on empty]
lolz -> F [on non-number value]
n4melyh4xor -> F [on non-number with digits]
  1.2 -> F [on space-padded]
9.3 1.3 -> F [on anyhow separated multiple numbers]
1e5 -> F [no scientific notation]
50cl05e.buty3ts0f4r -> F [on input with letters obscuring the number]
1,2,3,4.5678 -> F [on badly readability-divided number]
1,234.5,678 -> F [on readability-divided floating point part]
.234 -> F [on no leading zero]
+1 -> F [no leading + sign]
1.234.3 -> F [only one decimal point]
12345,678 -> F [on separator stopping mid-way]

ตัวละครอย่างน้อยเป็นผู้ชนะ


เราสามารถสมมติว่าอินพุตเป็น ASCII ได้ตลอดเวลาหรือไม่?
แบรดกิลเบิร์ต b2gills

@ BradGilbertb2gills ใช่
n4melyh4xor

ถ้า-123ตกลงจะเป็นอย่างไร+456-> ดีหรือไม่ดี หรือถูก+ออกจากงานปาร์ตี้?
chux - Reinstate Monica

@ chux ขบวนรถไฟออกจากที่นั่นก่อนที่ + จะไปถึงที่นั่น ขอให้โชคดีในครั้งต่อไป +
n4melyh4xor

2
เมื่อมีคนขอคำชี้แจงในความคิดเห็นคุณควรแก้ไขคำถาม ไม่จำเป็นต้องอ่านความคิดเห็นเพื่อทราบสเป็ค ฉันได้แก้ไขเพื่อรวมคำตอบและกรณีทดสอบบางอย่าง
Peter Taylor

คำตอบ:


10

เรติน่า , 28 29 31 40 34 ไบต์

^-?\d{1,3}((,\d{3})*|\d*)(\.\d+)?$

แสดงผล1หากความจริงเป็น0อย่างอื่น เท่าที่ฉันเข้าใจในกรณีนี้ Retina จะแสดงจำนวนการจับคู่ regex ที่มีในอินพุต

ลองออนไลน์!

ชุดทดสอบ

การแก้ไข

  • แก้ไขเพื่อให้สอดคล้องกับกฎ "ควรมีตัวเลขหลังจุดทศนิยม"
  • แก้ไขเพื่อให้สอดคล้องกับกฎ "จัดการเชิงลบ"
  • แก้ไขให้สอดคล้องกับตัวคั่นเครื่องหมายจุลภาคหรือไม่ก็ได้
  • แก้ไขข้อบกพร่องด้วยตัวคั่นหลักพันตามที่ระบุไว้โดย @MartinEnder
  • Golfed โดยการลบ lookahead ตามเงื่อนไข

RegExplanation

^-?\d{1,3}((,\d{3})*|\d*)(\.\d+)?$
^                                $  This marks the start and end of regex
 -?                                 Optional hyphen for negative number
   \d{1,3}                          Matches between 1 and 3 digits
          (             )           Capturing group
           (,\d{3})*                 Matches at least zero of comma and three numbers (in the case of separators)
                    |                OR
                     \d*             Matches at least zero digits (in the case of no separators)
                        (\.\d+)?    Matches an optional . and at least one digit (for decimal numbers)

@MartinEnder แก้ไขแล้ว! นอกจากนี้คุณจะระบุค่าสถานะ (พูดค่าสถานะสำหรับmและg) ใน Retina ได้อย่างไร
Kritixi Lithos

ใส่`ในด้านหน้าของ regex m`^.$แล้วปรับเปลี่ยนไปในด้านหน้าของที่เช่น gไม่มีอยู่ใน. NET การจับคู่นั้นเป็นค่าเริ่มต้น
Martin Ender

3

JavaScript, 46 49 ไบต์

นี่เป็นพอร์ตโดยตรงของคำตอบ Retina ของฉัน เหตุผลเดียวที่ฉันใช้ JS คือมีวิธีง่ายๆในการทดสอบ regex โดยใช้ Snack Snippet ด้านล่าง

f=s=>/^-?\d{1,3}((,\d{3})*|\d*)(\.\d+)?$/.test(s)

f=s=>/^-?\d{1,3}((,\d{3})*|\d*)(\.\d+)?$/.test(s)
<input oninput=p.innerText=f(value)><p id=p></p>


หากไม่ใช่กฎบางข้อ (เช่นกฎคอมมา) ก็สามารถทำได้เพียงisNaN(+prompt())16 ตัวอักษร นั่นคือชีวิตฉันคิดว่า
Matheus Avellar

2

Perl 6 , 42 ไบต์

{?/^\-?[\d**1..3[\,\d**3]+|\d+][\.\d+]?$/}

ลองมัน

ขยาย:

{  # bare block lambda with implicit parameter 「$_」

  ? # turn the following into a Bool result

  /  # match implicitly against 「$_」

    ^                 # beginning of string

    \- ?              # optional leading 「-」

    [

      \d ** 1..3      # 1 to 3 digits
      [
        \,            # comma
        \d ** 3       # three digits
      ]+              # repeat at least once

    |                 # or

      \d+             # at least one digit

    ]

    [ \. \d+ ]?       # 「.」 followed by at least one digit optionally

    $  # end of string

  /
}

1

PHP, 62 ไบต์

<?=preg_match("#^-?(\d+|\d{1,3}(,\d{3})*)(\.\d+)?$",$argv[1]);

builtin ไม่สามารถจัดการเครื่องหมายจุลภาคและยอมรับเครื่องหมายทางวิทยาศาสตร์ ดังนั้นฉันต้องเดินตามวิธีการ regex <?=is_numeric($argv[1]);น่าจะเป็น 24 ไบต์


0

เครื่องมือทุบตี / Unix ขนาด 64 ไบต์

egrep -c '^-?([0-9]+|[0-9]{1,3}(,[0-9]{3})+)(\.[0-9]+)?$'<<<"$1"

บันทึกสิ่งนี้เป็นไฟล์และส่งผ่านสตริงเพื่อทดสอบเป็นอาร์กิวเมนต์แรกของคำสั่ง

เอาต์พุตคือ 0 สำหรับตัวเลขที่ไม่ใช่ 1 สำหรับตัวเลข

หากคุณยินดีที่จะรับอินพุตจาก stdin และหากคุณสามารถรับประกันได้ว่าอินพุตนั้นประกอบด้วยเพียงหนึ่งบรรทัดคุณสามารถลบ <<< "$ 1" ที่ส่วนท้ายได้โดยมี57 ไบต์ไบต์

สำหรับโค้ดนั้นตัวเลือก -c เพื่อ egrep จะนับจำนวนบรรทัดที่ตรงกัน (ซึ่งจะเป็น 0 หรือ 1)


0

Pyth, 25 อักขระ

:zCiCM"૧򡊪񛨮򶟉񠫊򆻛񓰚祥񯯏󪬡򢝉񁘍񲲂쪤"^T6

บีบอัดKritixi Lithos' regex

ลองออนไลน์ ใช้อักขระ Unicode นอก Basic Multilingual Plane ซึ่ง TIO ใดที่เห็นชัดว่าไม่สามารถจัดการได้ แอพตัวเล็กนี้รายงานขนาดที่ผิดสำหรับสตริง อักขระ / ไบต์ตัวนับนี้ทำให้ถูกต้อง


0

C89, 195 ไบต์

b,d,c,i;f(char*s){b=*s;for(d=c=i=0;i++,*(s++),d+=*s=='.',c+=*s==',',b=c?i&(i%4!=3)&*s==','?0:b:b;)if(*s==45&!i);else if((*s==32)|(*s==46)|*s==43|!isdigit(*s)&*s!=46&*s!=44)||!(d-1))b=0;return b;}

Ungolfed:

bool is_base10_number (const char* const str) {

  if(!str[0])return false;

  size_t
    dpts = 0,
    cmas = 0;

  for (size_t i = 0; i < strlen(str); i++) {

    if ((str[i] == '-') && (!i)){
      continue;
    }

    if (
      (str[i] == ' ')
      || (str[0] == '.')
      || (str[0] == '+')
      ||
      (
        (!isdigit(str[i]))
        && (str[i] != '.')
        && (str[i] != ',')
      )
    ) {
      return false;
    }

    dpts += str[i] == '.';
    cmas += str[i] == ',';

    if (cmas) {
      if (i & ((i % 4) != 3) & str[i] == ',') {
        return false;
      }
    }

  }

  if (dpts > 1) { return false; }

  return true;
}


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.