2016-11-27 11 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 принимает итераторы или указатели в качестве аргументов, а не значения в массиве/контейнере для сортировки. Ваш призыв к 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() дает размер строки. На первой итерации i будет равен size(), но доступ к s[i] приведет к неопределенному поведению, и ошибка, так как s[i], очевидно, не существует. В строке, содержащей n символов, символы: s[0] - s[n-1], конечно.

Вам нужно будет исправить алгоритм, так что last_char заканчивает тем, что индекс следующего символа после одному вы хотите, чтобы перетасовать, а затем использовать фиксированный std::random_shuffle вызов, выше.

Или, наоборот, вычислить 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