2012-01-25 4 views
1

좋은 하루 되세요! 아래는 사용자에게 문장을 물어보고 그것에 문장의 수를 출력하는 프로그램입니다.문장에서 문장의 수를 세는 것

#include<iostream> 
#include<string> 
#include<sstream> 

using namespace std; 

bool isPalindrome (const std::string& s) { 
    for (int i = 0; i < (s.length())/2; ++i) { 
     if (s[i] != s[s.length()-1 - i]) 
      return false; 
     else 
      return true; 
    } 
} 


int main() { 
    string sentence; 
    int counter=0; 
    cout << "Please input a sentence." << endl; 
    getline(cin, sentence); 
    stringstream processtokens(sentence); 
    for(string word; processtokens >> word;) 
     if(isPalindrome(word)) 
      ++counter; 
    cout << "Number of Palindromes are : " << counter << endl; 
} 

잘 작동합니다. 그러나 예를 들어 "빠른 갈색 개그가 파란 눈을.니다."라고 입력하면 프로그램에 표시되는 문장의 수는 단지 1 개이지만 실제로는 개그와 눈의 2 가지 문장이 있습니다. 문제는 "눈"이라는 단어에 마침표가 있다는 것입니다. 그렇다면 예를 들어 사용자가 "정오, 저녁, 자정을 사랑합니다"라고 입력하면 프로그램에서 쉼표와 같은 마침표와 기타 구두점을 어떻게 무시할 수 있습니까? 정오는 회문이지만 프로그램은 쉼표 때문에 인식하지 못합니다.

또 다른 문제는 대문자입니다. 사용자가 "부인, 내 작업이 완료되었습니다."라고 입력하면이 프로그램이 작동하게 (그리고 ASCII와 동등한 것을 무시하기를) 원합니다. 나는 그것이 tolower과 관련이 있다는 것을 알고 있습니다. 요약하면

, 나는이 프로그램이 A) 을 표시 구두점을 무시 기능와 b) 총액을 갖고 싶어.

아, "stringstream processtokens (sentence);"의 대안은 무엇입니까? 그 대신,이 프로그램을 부분 문자열 (substr)을 사용하고을 찾으려면이 프로그램이 필요합니다.

제발 나를 안내하십시오! 고마워요 그리고 모든 종류의 도움은 매우 감사드립니다. 다시 한번 감사 드리며 좋은 하루 되세요!

+2

당신은 이미해야 할 모든 것을 거의 설명했습니다. 모든 것을 소문자로 변환하고 비 문자를 건너 뜁니다. 거의 다 왔어. –

답변

0

구두점을 확인하는 기능이 있다고 생각합니다. 시도해보십시오. ispunct

2

ispunct을 사용할 수 있으며 ispunct가 true를 반환하는 문자는 무시하십시오.

inline bool is_letter(char c) 
{ return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'); } 


bool is_palindrome(const std::string & s) 
{ 
    std::string::const_iterator it = s.begin(); 
    std::string::const_reverse_iterator rt = s.rbegin(); 

    while (it != s.end() && rt != s.rend() && std::distance(it, rt.base()) > 0) 
    { 
     // Skip non-letters 
     while (it != s.end() && !is_letter(*it)) { ++it; } 
     while (rt != s.rend() && !is_letter(*rt)) { ++rt; } 

     if (it == s.end() || rt == s.rend()) { break; } 

     // Check palindromy 
     if (std::tolower(*it) != std::tolower(*rt)) { return false; } 

     // Move on 
     ++it; 
     ++rt; 
    } 

    return true; 
} 

트릭은 양쪽 끝에서 문자열을 공격하는 것입니다 : 당신은 또한 통화 tolower에 문자 비교() 어쩌면이 작은 운동은 반복자 일부 좋은 C++ 기능을 소개하는 데 사용할 수 있습니다

+0

궁금한데, tolower()가 숫자를 만났을 때 예외를 던지나요? 아니면 그냥 계속 나아가나요? – fdh

+0

@Farhad : 숫자를 만나면 반환 된 값은 변경되지 않습니다. – omggs

+0

@Oleksi : 고마워요! 그러나 나는 그들을 어떻게 무시합니까? 나는 bool 함수를 수행했지만 그 문자를 "무시"하기 위해 무엇을해야할지 모르겠습니다. 제발 고마워! –

2

을 포장한다 . 이를 위해 우리는 보통 반복자 인 it을 문자열의 시작 부분에서 가져오고 반대로 반복자 인 rt을 문자열 끝에서 가져옵니다.

코드 핵심은 회상색 (대문자와 소문자를 비교하여 대문자와 소문자를 구별하지 않음)을 확인하는 것이며, 실패한 경우에도 즉도 return false입니다. 그렇지 않으면 두 개의 반복자가 하나씩 진행됩니다.

마지막으로 루프의 시작 부분은 문자열의 문자가 아닌 문자를 거슬러 올라가므로 무시할 수 있습니다. 우리는 멍청한 끈의 끝에 도달했는지 다시 확인합니다. 당신은 당신이 단지 iterator를 유효한 요소로 역 참조하는 것을 확인해야만한다!

전진 이동 반복기가 후진 이동 반복기를 지나치면 루프가 중지됩니다. 이것은 distance(it, rt.base()) > 0 조건의 내용입니다. 역방향 반복기의 "기본"은 실제로 요소에 대한 일반 반복자이며, 역 반복기 요소 인 이후입니다. 따라서 it에서 rt까지의 거리가 0보다 큰 경우 을 넘지 않았습니다.(itrt이 같은 요소를 가리킬 때 거리는 정확하게 1입니다.)

+0

대단히 고마워요! 너는 큰 도움이된다! 그러나 프로그램을 실행하고 "Hello noon, I love you!"라고 입력하면 문장의 수를 2로 표시합니다. 왜 그렇게 궁금하니 ... 그렇다. 네가 나를 분명히 설명했기 때문에 정말 고마워. 정말 고맙습니다! –

+0

오, 나는 고쳐 쓴다. "나는"회문 자체입니다! 다시 감사합니다! 좋은 하루 되세요! –

관련 문제