2016-11-27 2 views
1

문자열의 첫 번째와 마지막 문자를 동일하게 유지하고 마지막 문자 뒤의 비 문자를 모두 무시하는 함수를 작성하려고합니다. 나는 std :: random_shuffle()을 사용하기로되어있다. 나는이 문서의 내용을 읽었지만이 기능의 개념을 이해하지 못하는 것 같습니다. 이것은 내 코드입니다 :문자열에서 문자 뒤섞기 C++

#include <iostream> 
#include <algorithm> 
#include <string> 

std::string mix(std::string s){ 
    int last_char; 
    if(std::isalpha(s[s.size()-1]) == true){ 
     last_char = s.size()-1; 
    } else { 
    for(int i=s.size()-1 ; i>0; --i){ 
     if((std::isalpha(s[i]) == false) && (std::isalpha(s[i-1])==true)){ 
      last_char = i -1; 
      break; 
     } 
     } 
    } 
    std::random_shuffle(&s[1],&s[last_char]); 
    return s; 

} 

int main(){ 
    std::string test = "Hello"; 
    std::cout << mix(test) << std::endl; 
} 

편집 : 이제는 오류가 계속 발생합니다 : 분할 오류 (코어 덤프). 누구도 왜 그런 생각을 가지고 있니? 문제를 찾을 수없는 것 같습니다.

+0

그것은 무작위로 당신은 디버거를 사용하는 방법을 배울 필요가 – Alex

+0

제공 한 인수의 내용을 섞는다. 한편, 다음 질문에 답하십시오 : last_letter의 최종 가치는 무엇입니까? 할당 된 라인은 무엇입니까? –

답변

3

std::random_shuffle은 정렬 자/포인터의 값이 아니라 인수로 iterator 또는 포인터를 사용합니다. std::random_shuffle에 대한 귀하의 호출은 아마해야합니다 : 두 번째 매개 변수는 끝 반복자 값입니다

std::random_shuffle(&s[1],&s[last_char]); 

하는 것으로. 끝 반복자는 정렬 할 마지막 값을 가리 키지 않지만 그 다음의 값을 가리 킵니다.

표시된 코드의 문제 만있는 것은 아닙니다. std::random_shuffle을 호출하기 전에 코드에서 몇 가지 버그를 수정해야합니다. 예를 들어 :

for(int i=s.size() ; i>0; --i){ 
    if((std::isalpha(s[i]) == false) && (std::isalpha(s[i-1])==true)){ 

s.size() 당신에게 문자열의 크기를 제공합니다. 첫 번째 반복에서 isize()과 같지만 s[i]에 액세스하면 정의되지 않은 동작이 발생하고 s[i]은 분명히 존재하지 않으므로 버그가 발생합니다. 문자가 n 인 문자열의 경우 문자는 s[0]에서 s[n-1]입니다. 당신은 위의 고정 std::random_shuffle 호출을 사용하여 다음 last_char가 당신이 셔플하고 싶은 한 후 다음 문자 의 인덱스 인 것을 끝나도록 알고리즘을 수정하고해야합니다

.

또는 선택적으로 정렬 할 마지막 문자의 인덱스로 last_char을 계산하고, 잘 될 것입니다

std::random_shuffle(&s[1],&s[last_char+1]); 

어느 방법을 문의하십시오.

+0

답변 해 주셔서 감사합니다. 극도로 유익하고 도움이되었지만 포인터를 아직 다루지 않았으므로 그러한 운동이 전달 된 것은 매우 이상합니다. 나는 내 코드를 고쳤다 고 생각한다.하지만 이제는 오류가 계속 발생한다. 분할 오류 (코어 덤프)가 발생하고 문제를 찾지 못하는 것 같다. 내 코드를 내 게시물에 고정했습니다. – mthe25

+0

내가 원래 지적한 것과 같은 버그. 당신의 수학은 꺼져 있습니다. 한 무리의 장소에서 1 씩 나옵니다. 나는이 문제를's.size()'로 지적했지만 다른 여러 곳에서 같은 버그가있다. 또한 종료 반복자 값의 계산을 올바르게 구현하지 않았습니다. 끝 반복자 값이 무엇인지에 대한 내 설명을 검토 한 다음 디버거를 사용하여 한 번에 한 줄씩 코드를 단계별로 실행하십시오. –

1
  1. 문자열의 오른쪽에 가장 왼쪽의 "비 문자"가 있어야합니다.

  2. 왼쪽의 한 자리는 마지막 문자의 위치입니다.

  3. 첫 번째 문자는 첫 번째 문자입니다.

  4. "처음"과 "마지막"으로 random_shuffle을 호출하기 만하면됩니다. 여기

은 몇 가지 유용한 링크입니다 :

http://www.cplusplus.com/reference/algorithm/random_shuffle/

포함입니다 "시작"기억 "끝"당신이 시작하는

-1

뭔가 "독점이있다 적어도. 당신이 고쳐야 할 하나의 코너 케이스. cppreference를 방문하십시오.com에서 알고리즘 작동 방식을 이해할 수 있습니다.

#include <iostream> 
#include <cctype> 
#include <algorithm> 
#include <string> 

std::string 
special_shuffle(std::string s) 
{ 
    if (s.size() < 3) return s; 
    auto begin = std::find_if(s.begin(), s.end(), ::isalpha); 
    auto end = std::find_if(s.rbegin(), s.rend(), ::isalpha).base(); 
    std::random_shuffle(++begin, --end); 
    return s; 
} 

int 
main() 
{ 
    std::string s1 = "Hello World!"; 
    std::string s2 = "AB"; 
    std::string s3 = "A"; 
    std::string s4 = ""; 
    std::string s5 = "a string going from a to z"; 

    std::cout << s1 << " --> " << special_shuffle(s1) << "\n" 
      << s2 << " --> " << special_shuffle(s2) << "\n" 
      << s3 << " --> " << special_shuffle(s3) << "\n" 
      << s4 << " --> " << special_shuffle(s4) << "\n" 
      << s5 << " --> " << special_shuffle(s5) << "\n"; 
} 

컴파일 및 실행

$ g++ example.cpp -std=c++14 -Wall -Wextra 
$ ./a.out 
Hello World! --> Hooll eWlrd! 
AB --> AB 
A --> A 
--> 
a string going from a to z --> aarfritomgi nnso t g goz