Я должен написать функцию, которая сохраняет первую и последнюю букву строки одинаковыми и игнорирует любые не буквы после последней буквы. Я должен использовать std :: random_shuffle (). Я прочитал документацию, но, похоже, не понимаю концепцию этой функции. Это мой код:

#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;
}

Edit: Теперь, однако, я продолжаю получать сообщение об ошибке: ошибка сегментации (ядро сброшено). У кого-нибудь есть идея, почему? Не могу найти проблему.

1
mthe25 27 Ноя 2016 в 03:55

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]);

Любой подход подойдет.

3
Sam Varshavchik 27 Ноя 2016 в 01:01
  1. Вам нужно будет найти крайнее левое «не буквенное» в правой части строки.

  2. Одно место слева от него - это позиция последней буквы.

  3. Одно место справа - ваше первое письмо.

  4. Просто вызовите random_shuffle с вашими «первым» и «последним».

Вот несколько полезных ссылок:

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

Помните, что «начало» - включающее, «конец» - исключающее »

1
paulsm4 27 Ноя 2016 в 01:01

Что-то для начала. У него есть как минимум один угловой корпус, который вам придется исправить. Посетите 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
-1
Escualo 27 Ноя 2016 в 01:13