2009-09-16 41 views
6

Tôi đang làm việc trên một số bài tập về nhà cho các lớp học biên dịch của tôi và tôi có vấn đề sau đây:Có thể đơn giản hóa biểu thức chính quy này thêm nữa không?

Viết một biểu thức chính quy cho tất cả các chuỗi của một 's và b' s có chứa một số lẻ của số hoặc số lẻ là b (hoặc cả hai).

Sau rất nhiều công việc Bảng tôi đã đưa ra các giải pháp sau đây:

(aa|bb)* (ab|ba|a|b) ((aa|bb)* (ab|ba) (aa|bb)* (ab|ba) (aa|bb)*)* 

Tuy nhiên, là đây là đơn giản nhất mà tôi có thể lấy nó? Tôi đã xem xét việc xây dựng DFA cố gắng để giảm thiểu số lượng các tiểu bang ở đó để xem nếu nó sẽ giúp tôi đơn giản hóa nhưng tôi figured tôi sẽ yêu cầu rất kinh nghiệm regex trên SO đầu tiên.

+0

Bạn có quyền sử dụng các tính năng nâng cao nào của regex? –

+6

anh ấy đang sử dụng cụm từ thông dụng trong Khoa học Máy tính chứ không phải PCRE hoặc posix regex;) Chúng khác nhau. –

+1

@ Brad Gilbert, tôi cho rằng chúng tôi chỉ được phép sử dụng regex đã được giới thiệu cho đến nay trong cuốn sách mà không nhiều. (*, +,?, |, [], ^). Khá đơn giản. –

Trả lời

8

Hãy Greg D's đề nghị bắt đầu với một (aa) *, và đi từ đó. Sepp2k gần như đã đúng, nhưng sự cân nhắc thực sự là bạn không quan tâm đến lá thư kia. Ý tôi là, khi bạn đang nhìn vào ràng buộc "số lẻ", bạn không quan tâm gì về những gì b nằm trong chuỗi của bạn. Như vậy, thanh b * 's bất cứ nơi nào bạn có thể :)

câu trả lời Sepp2k là gần đúng, nhưng điều này là đúng:

b* a b* (a b* a b*)* | a* b a* (b a* b a*)* 

Xây dựng, regex này hiểu ra tất cả các chuỗi với một số lẻ của một người (phần đầu tiên), và các chuỗi của OR với bất kỳ chuỗi nào chứa số lẻ b.

+0

@Walt W, tôi đang chạy cái này thông qua các bước của nó nhưng tôi nghĩ rằng bạn là chính xác. – mmcdole

+0

xin vui lòng cho tôi biết biểu thức chính quy cho bất kỳ chuỗi nào có chứa số chẵn và số chẵn của b? –

+0

Bạn có nghĩa là số chẵn hoặc số chẵn của b không? Tôi cho rằng bạn có thể làm một AND với lookaheads không dài ... Đó không phải là thứ regex tiêu chuẩn mặc dù. Nếu bạn muốn thay đổi phương trình này từ kỳ lạ thành chẵn, chỉ cần bỏ hai cụm từ đầu tiên của mỗi phân đoạn (b * a từ phía bên trái và dấu * b từ bên phải) –

2

Tôi e rằng tôi không tin rằng regex của bạn được viết là chính xác. Hãy xem xét các chuỗi:

aba 

Chúng tôi có một vài lựa chọn cho trận đấu, nhưng thực tế là nó lẻ chiều dài có nghĩa là chúng ta phải phù hợp với một một duy nhất ở phía trước, vì vậy:

(a)(ba) 

Nhưng, thật đáng buồn , không thể cho nhóm chính thứ hai của bạn ở đó để phù hợp (ba).

Khi giao dịch với một ràng buộc như thế này, tôi thấy dễ dàng hơn để bắt đầu từ ràng buộc cốt lõi và đi từ đó. Trong trường hợp này, hạn chế của bạn là "lẻ", vì vậy hãy bắt đầu với

a(aa)* 

để buộc số lẻ a và chuyển từ đó. :)

+0

@Greg D, điều đó đúng. Hãy để tôi suy nghĩ về nó trong một giây. – mmcdole

5

này nên làm việc:

b* a b* (a b* a b*)* | a* b a* (b a* b a*)* 
+3

Tôi đã viết một cái gì đó tương tự :) Để xây dựng, regex này con số ra tất cả các chuỗi với một số lẻ của một (phần đầu tiên), và OR của những chuỗi với bất kỳ chuỗi có chứa một số lẻ của b. Có một lỗi nhỏ ở đây mặc dù, như thuật ngữ đầu tiên cần b * ở cuối, và tùy chọn thứ hai cần một * ở cuối. Nếu không, abbba sẽ không được chấp nhận. –

+0

@ sepp2k, điều này đang làm việc trong tất cả các trường hợp thử nghiệm của tôi. Bạn có thể mô tả quá trình suy nghĩ của bạn khi bạn đã làm điều đó? Nó đơn giản hơn nhiều so với con đường tôi đang đi xuống. – mmcdole

+0

Không ai nói nó không thể mơ hồ. Walt là chính xác, nó không được hoàn thành, nhưng tất cả các bit quan trọng là có. :) –

0

Tôi nghĩ bạn cần tiếp cận vấn đề một cách khác nhau.

Bạn đang cố gắng khớp với bất kỳ thứ gì không có số chẵn là cả số ab.

Có thể sẽ dễ dàng hơn để bắt đầu với một cái gì đó khớp với số thậm chí số ab. Tất cả những gì bạn phải làm vào thời điểm đó sẽ là thêm thứ gì đó vào cuối khớp với chuỗi nhỏ nhất mà bạn thực sự muốn khớp.

Các vấn đề liên quan