Изменить строки в векторе? (Без использования петель) - PullRequest
0 голосов
/ 26 мая 2020

Я пытаюсь взять вектор строк и удалить каждый символ, который не является буквой (число, символы и т. Д. c.) Я также не пытаюсь использовать циклы.

Итак, вот пример вектора:

std::vector<std::string> a = {"he2llo*", "3worl$d"};

И я хочу, чтобы возвращаемая строка выглядела так:

std::vector<std::string> a = {"hello", "world"};

Сейчас я пытаюсь использовать алгоритмы преобразования и стирания, но Я не могу понять синтаксис.

Это явно неполно, но это базовая c настройка того, что у меня есть на данный момент:

int trim(std::vector<std::string> a){
    std::transform(a.begin(), a.end(), a.erase())

Ответы [ 6 ]

3 голосов
/ 26 мая 2020

Вы можете использовать std::for_each в векторе, а затем использовать идиому удаления-удаления в строках, как показано ниже

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

int main() {
    std::vector<std::string> a = {"he2llo*", "3worl$d"};
    std::for_each(a.begin(), a.end(),[](auto & str){
        str.erase(std::remove_if(str.begin(), str.end(), [] (auto & character){return !isalpha(character);}), str.end());
    });

    for(auto const & el : a)
        std::cout << el << " ";

}
The output:
hello world 
1 голос
/ 26 мая 2020

Рекурсивно ..

#include <iostream>
#include <vector>

std::string remove_bad_characters(std::string input, std::string result)
{
    if (input.size() == 0)
    {
        return result;
    }

    if (!isalpha(input[0]))
    {
        return remove_bad_characters(input.substr(1), result);
    }

    result += input[0];
    return remove_bad_characters(input.substr(1), result);
}

std::vector<std::string> edit_bad_strings(std::vector<std::string> input, std::size_t index)
{
    if (index == input.size())
    {
        return input;
    }

    input[index] = remove_bad_characters(input[index], "");
    return edit_bad_strings(input, index + 1);
}


int main() {

    std::cout<<remove_bad_characters("h!ello!", "")<<"\n";
    std::vector<std::string> good = edit_bad_strings(std::vector<std::string>{"h!ell@o", "wo0rl-d"}, 0);

    for (std::string str : good)
    {
        std::cout<<str<<" ";
    }

    return 0;
}
0 голосов
/ 02 июня 2020

Вы можете попробовать по-разному с STL <algorithm> s, я реализовал функтор для обработки каждого слова:

#include <iostream>
#include <vector>
#include <cctype>
#include <algorithm>

class Processing{

public:

    std::string operator()(std::string& value){

        for_each(value.begin(), value.end(), [&](char v) mutable throw() ->
                 void {
                    auto fetch = std::find_if( value.begin(), value.end(), [&](char v)mutable throw()->
                                              bool{
                                                  return(!isalpha(v));
                                                  });
                    if(*fetch){
                        value.erase( fetch );
                    }
                 });
        return value;
    }

};

int main()
{

  std::vector<std::string> values = {"44h%ello333","%w%or333ld21"};

  std::for_each(values.begin(),values.end(), Processing());

  std::for_each(values.begin(),values.end(), [](std::string& value)->
                void {
                    std::cout<<value<<" ";
                    });

    return 0;
}
0 голосов
/ 26 мая 2020

Вы можете использовать C ++ 20 std :: erase_if

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

int main() {
  std::vector<std::string> a = {"he2llo*", "3worl$d"};
  std::transform(a.begin(), a.end(), a.begin(), 
    [](auto& str) { 
      std::erase_if(str, [](const auto& chr){return !isalpha(chr);}); 
      return std::move(str);
      });
  for (const auto& str: a){
    std::cout << str << std::endl;
  }
}
0 голосов
/ 26 мая 2020

Вот один из способов сделать это с помощью заголовка algorithm и лямбда-функций:

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

int main() {
    std::vector<std::string> strArr = {"he2llo*", "3worl$d"};
    std::transform(strArr.begin(), strArr.end(), strArr.begin(), [](std::string &str) -> std::string {
        str.erase(std::remove_if(str.begin(), str.end(), [](char chr) -> bool {
            return ! isalpha(chr);
        }), str.end());
        return str;
    });

    std::for_each(strArr.begin(), strArr.end(), [](const auto &str) {
        std::cout << str << '\n';
    });

    return 0;
}

Внешняя лямбда обрабатывает каждую строку, чтобы стереть указанные c символы, используя remove_if, а внутренняя лямбда просто управляет , а символы удаляются. Является ли это более читаемым, чем решение на основе al oop, остается предметом споров: -)

0 голосов
/ 26 мая 2020

Вы можете использовать std::for_each вместо l oop для обхода каждого элемента. Затем вы можете применить std::transform к каждому элементу вектора.

Вы можете ссылаться -

http://www.cplusplus.com/reference/algorithm/for_each/ http://www.cplusplus.com/reference/algorithm/transform/

...