2010-04-02 74 views
7

Một người bạn của tôi đến với tôi với hành vi kỳ lạ này mà tôi không thể giải thích, bất kỳ cái nhìn sâu sắc nào cũng sẽ được đánh giá cao.Phương thức IndexOf trả về 0 khi nó phải trả về -1 trong C#/Java

Im chạy VS 2005 (C# 2.0), các mã sau đây cho thấy hành vi

int rr = "test".IndexOf(""); 
Console.WriteLine(rr.ToString()); 

đoạn mã trên, print "0" mà thể hiện rõ nó nên có lợi nhuận -1

này cũng xảy ra trong Java mà lớp sau đây cho thấy các hành vi:

public class Test{ 
public static void main(String[] args){ 
    System.out.println("Result->"+("test".indexOf(""))); 
} 
} 

Im chạy Java 1.6.0_17

+0

Duplicate của http://stackoverflow.com/questions/3872936/why-do-strings-start-with-a-in-java và http://stackoverflow.com/questions/145509/why- không-abcd-startswith-trở-thành sự thật –

Trả lời

10

Đây không phải là ngoại lệ đối với quy tắc, mà là hậu quả tự nhiên của cách xác định indexOfstartsWith.

Bạn đang tuyên bố rằng "test".indexOf("") phải trả lại -1. Về cơ bản, điều này tương đương với tuyên bố rằng "test".startsWith("") phải trả lại false. Tại sao điều này?Mặc dù trường hợp này được giải quyết cụ thể trong tài liệu khi trả lại true, đây không chỉ là quyết định tùy ý.

Làm thế nào bạn sẽ quyết định "test".startsWith("te"), ví dụ? Cách đơn giản nhất là sử dụng đệ quy. Vì cả hai chuỗi bắt đầu bằng ký tự 't', bạn gọi "est".startsWith("e") và trả về kết quả. Tương tự, bạn sẽ gọi số "st".startsWith("") và trả lại kết quả. Nhưng bạn đã biết rằng câu trả lời phải là true, vì vậy đó là lý do tại sao mọi chuỗi bắt đầu bằng "".

+0

@jleedev lời giải thích tuyệt vời cảm ơn – jcgarciam

10

0 là chính xác. Bắt đầu tại vị trí 0 và bạn có thể (trivially) khớp với chuỗi có độ dài bằng 0. Tương tự, "" chứa "".

+0

đó sẽ là tốt nếu mà có thể đã được ví dụ của tôi, tôi đã cố gắng: "Test" .IndexOf (""); khác với những gì bạn giải thích. – jcgarciam

+0

@jcgarciam không thực sự. Nhìn nó theo cách này; theo cách nào ** không ** bắt đầu bằng (hoặc chứa) "". Cho tôi xem nhân vật không phù hợp. Không có một, do đó nó là một trận đấu. –

21

Trích từ C# documentation:

Nếu giá trị là Empty, giá trị trả về là 0.

Các hành vi mà bạn mô tả là hoàn toàn như mong đợi (ít nhất là trong C#).

+0

Cảm ơn bạn đã chỉ cho C# (Vì vậy, có vẻ như là Ngoại lệ đối với quy tắc). Trên phần truy cập của nó (JavaDoc), không được giải thích rõ ràng rằng hành vi này sẽ được mong đợi. – jcgarciam

+0

@jcgarciam: điểm tốt; Tôi sẽ cập nhật câu trả lời cho biết rằng nó có liên quan đến C#. –

6

0 là chính xác. Javadocs chỉ ra rằng indexOf công trình như sau:

các số nguyên trở lại là nhỏ nhất giá trị k sao cho:

this.startsWith(str, k) 

Bất kỳ chuỗi bắt đầu với "" bằng với chuỗi gốc (và mỗi chuỗi bắt đầu bằng ""), vì vậy nhỏ nhất k cho str = "" luôn là 0.

+0

Xin lỗi, nhưng tôi không hiểu lý do của bạn về điều này. – jcgarciam

+4

* Mỗi chuỗi đơn * bắt đầu với "" Tương tự như vậy, mỗi bộ duy nhất là một superset của một tập rỗng. Etc ... Đó là một quy ước rất thuận tiện. – glebm

+0

Cảm ơn bạn đã chỉ ra @glebm – jcgarciam

2

Nó sẽ trả về 0. Bạn đang tìm kiếm sự xuất hiện đầu tiên của một chuỗi rỗng, đúng không? :)

3

Hãy suy nghĩ theo cách này: IndexOf, khi tìm kiếm một chuỗi, sẽ bắt đầu ở vị trí 0, cố gắng khớp chuỗi, nếu nó không vừa, hãy chuyển sang vị trí 1, 2, v.v. Khi bạn gọi nó bằng một chuỗi rỗng, nó cố gắng khớp với chuỗi rỗng với chuỗi bắt đầu từ vị trí 0 với độ dài 0. Và hooray, không có gì bằng không.

Lưu ý phụ: Không có lý do thực sự để sử dụng ToString khi bạn đang sử dụng Console.Write/WriteLine. Hàm này sẽ tự động gọi phương thức ToString của đối tượng được đề cập. (Trừ khi quá tải ToString)

+0

Tại vị trí chỉ mục 0, "kiểm tra" không giữ "không có gì", nó có "t". Bình chọn +1 cho cách bạn đặt nó. :) –

+0

như vòng nói, tại vị trí 0 nó không giữ "không có gì". Nhưng dù gì cũng cảm ơn! Dường như điều này được giải thích trong Tài liệu. Tôi sẽ đặt điều này như là một ngoại lệ đối với quy tắc IndexOf được cho là hoạt động như thế nào. – jcgarciam

1

Chỉ để giải trí. Nó cũng hoạt động như thế trong python

>>> "test".startswith("") 
True 
>>> "test".index("") 
0 

Python ném giá trị ValueError thay vì -1 là tốt.

>>> "test".index('r') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: substring not found 
1

PHP thú vị khác thực sự hoạt động tốt hơn!

php -r "print strpos('test','');" 
PHP Warning: strpos(): Empty delimiter. in Command line code on line 1 
Các vấn đề liên quan