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);
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);
std::string s("Hello world");
if (s.find("Hello") == 0)
{
std::cout << "String starts with Hello\n";
}
@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? –
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
Một giải pháp hiệu quả nên là 'O (min (bigString.length(), smallString.length()))' –
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());
}
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
strstr()
trả về con trỏ đến lần xuất hiện đầu tiên của chuỗi trong chuỗi.
http://www.cplusplus.com/reference/string/string/substr/
Bạn có thể sử dụng string.substr() để xem bất kỳ số lượng ký tự từ vị trí bất kỳ, hoặc bạn có thể sử dụng một thành viên string.find().
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_with
và ends_with
, vì vậy bạn cuối cùng cũng có thể viết chỉ bigString.starts_with(smallString)
.
Giải pháp chính xác, như mọi khi, đến từ Boost: boost::algorithm::starts_with
.
Awful để sử dụng tăng chỉ để làm nhiệm vụ đơn giản này. – Borzh
@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
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
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) 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
Có, cho cả hai. Đó là 'std :: equal', và nó phải là' bigString.end() '. –
Để 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>
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;
}
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()));
}
là bạn nói chuỗi C hoặc std: : Chuỗi –
Tôi đang nói về C++ string.std :: string –