2011-11-11 30 views
36

Có cách nào trong C++ để kiểm tra chuỗi bắt đầu bằng một chuỗi nhất định (nhỏ hơn bản gốc) không? Cũng giống như chúng ta có thể làm gì trong Javacách kiểm tra chuỗi bắt đầu bằng C++

bigString.startswith(smallString); 
+0

là bạn nói chuỗi C hoặc std: : Chuỗi –

+0

Tôi đang nói về C++ string.std :: string –

Trả lời

65
std::string s("Hello world"); 

if (s.find("Hello") == 0) 
{ 
    std::cout << "String starts with Hello\n"; 
} 
+0

@avakar Tôi đồng ý. Tôi đã không thử các biểu thức chính quy C++ 11, nhưng đó cũng sẽ là một giải pháp, và hy vọng hiệu quả hơn? –

+3

Tôi nghĩ rằng regex là một lựa chọn tồi cho việc kiểm tra đơn giản như vậy, hãy xem câu trả lời của tôi cho những gì tôi nghĩ là một giải pháp hiệu quả cho vấn đề này. Hoặc thậm chí tốt hơn Alan Stokes trả lời bằng chuỗi :: compare(). – Kleist

+5

Một giải pháp hiệu quả nên là 'O (min (bigString.length(), smallString.length()))' –

25

Các phương pháp sử dụng string::find() hoặc string::substr() không tối ưu vì chúng hoặc tạo một bản sao của chuỗi của bạn, hoặc tìm kiếm hơn các trận đấu vào lúc bắt đầu của chuỗi. Nó có thể không phải là một vấn đề trong trường hợp của bạn, nhưng nếu bạn có thể sử dụng thuật toán std::equal. Hãy nhớ kiểm tra xem "haystack" có ít nhất là "kim" hay không.

#include <string>  

using namespace std; 

bool startsWith(const string& haystack, const string& needle) { 
    return needle.length() <= haystack.length() 
     && equal(needle.begin(), needle.end(), haystack.begin()); 
} 
-1

Hoặc tạo ra một chuỗi con đó là chiều dài của biến smallString của bạn, và so sánh hai. Hoặc thực hiện tìm kiếm chuỗi con smallString và xem nó có trả về chỉ số 0

0

strstr() trả về con trỏ đến lần xuất hiện đầu tiên của chuỗi trong chuỗi.

55

Bạn có thể làm điều này với string::compare(), cung cấp các tùy chọn khác nhau để so sánh tất cả hoặc một phần của hai chuỗi. Phiên bản này so sánh smallString với tiền tố kích thước thích hợp của bigString (và hoạt động một cách chính xác nếu bigString ngắn hơn smallString):

bigString.compare(0, smallString.length(), smallString) == 0 

tôi có xu hướng để quấn này trong một chức năng miễn phí có tên startsWith(), vì nếu không nó có thể nhìn một chút bí ẩn.

Cập nhật: C++20 is adding các chức năng mới starts_withends_with, vì vậy bạn cuối cùng cũng có thể viết chỉ bigString.starts_with(smallString).

14

Giải pháp chính xác, như mọi khi, đến từ Boost: boost::algorithm::starts_with.

+12

Awful để sử dụng tăng chỉ để làm nhiệm vụ đơn giản này. – Borzh

+1

@Borzh, chắc chắn, bạn đã sử dụng Boost mạnh trong các dự án của bạn, tại sao không cho điều này? – avakar

+37

Không phải ai cũng sử dụng boost. Và để tải xuống, hãy đặt nó vào kho lưu trữ chỉ để sử dụng starts_with() là một chút phóng đại. Có lẽ bạn nên cân nhắc xóa "Giải pháp đúng, như thường lệ ...". Nó cũng không phải là "đúng" không phải "luôn luôn". – Borzh

1

Phương pháp đơn giản nhất sẽ là:

if (smallString.size() <= bigString.size() 
    && std::equals(smallString.begin(), smallString.end(), bigString.end()) 

(Điều này cũng sẽ có tác dụng nếu một trong hai, hoặc cả hai, là một vector Hoặc bất kỳ container loại tiêu chuẩn khác..)

+1

-1 1) Tôi không thể tìm thấy bất kỳ std :: equals. Ý của bạn là std :: equal? 2) bạn có chắc chắn với bigString.end() - một trong những mong chờ bigString.begin()? 3) trả lời bởi Kleist được đăng trước khi có vẻ để có được tất cả các quyền này – Suma

+0

Có, cho cả hai. Đó là 'std :: equal', và nó phải là' bigString.end() '. –

5

Để tối ưu hóa một chút:

if (smallString.size() <= bigString.size() && 
    strncmp(smallString.c_str(), bigString.c_str(), smallString.length()) == 0) 

Đừng quên #include <cstring> hoặc #include <string.h>

0

Tôi nghĩ có ý nghĩa khi đăng một giải pháp thô không sử dụng bất kỳ chức năng thư viện nào ...

// Checks whether `str' starts with `start' 
bool startsWith(const std::string& str, const std::string& start) { 
    if (&start == &str) return true; // str and start are the same string 
    if (start.length() > str.length()) return false; 
    for (size_t i = 0; i < start.length(); ++i) { 
     if (start[i] != str[i]) return false; 
    } 
    return true; 
} 

Thêm một đơn giản std::tolower chúng ta có thể làm cho trường hợp này không nhạy cảm

// Checks whether `str' starts with `start' ignoring case 
bool startsWithIgnoreCase(const std::string& str, const std::string& start) { 
    if (&start == &str) return true; // str and start are the same string 
    if (start.length() > str.length()) return false; 
    for (size_t i = 0; i < start.length(); ++i) { 
     if (std::tolower(start[i]) != std::tolower(str[i])) return false; 
    } 
    return true; 
} 
0

Tôi ngạc nhiên không có ai đăng bài phương pháp này được nêu ra:

#include <string>  
using namespace std; 

bool starts_with(const string& smaller_string, const string& bigger_string) 
{ 
    return (smaller_string == bigger_string.substr(0,smaller_string.length())); 
} 
Các vấn đề liên quan