Home > Enterprise >  Remove strings that contain digits and convert others in upper case and separate them with comma
Remove strings that contain digits and convert others in upper case and separate them with comma

Time:05-31

I've almost finished this task but have a little trouble in result. Here's the problem description: Given a vector of strings, please implement the following 2 functions to process and output it:

  1. process(): remove strings that contain digits and convert others in upper case

  2. output(): print the strings and separate them with comma. Hints:

  3. If possible, manipulate the vector elements in place to avoid copying vector.

  4. It is encouraged to leverage STL functions/algorithms. Expected Output: ==========================================

    Before: abc, 123, 456, xyz

    After: ABC, XYZ

But my code caused the input is not as expected

before process: abc, 123, 456, xyz,
after process: ABC, XYZ,

Please tell me how to remove the comma in the end of string in both case before/after process

Here's my code:

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

void process(std::vector<std::string>& v)
{
    
    // Remove strings that contain digits
    for(std::string &s : v)
        s.erase(std::remove_if(std::begin(s), std::end(s), 
                           [](unsigned char ch) { return std::isdigit(ch); }), 
            s.end()); 
 
    // Convert other characters into upper case
// std::toupper has several overloads
// template <class charT> charT toupper(charT, const locale&)
// int toupper(int ch)
// So taking its address might be complicated.
// We can use lambda to let compiler found the right overload:
// (In addition, as char might be signed or not, and toupper expects unsigned char value (or EOF))
    for(std::string &s : v)
    {
        std::transform(s.begin(), s.end(), s.begin(), 
        [](unsigned char c){ return std::toupper(c); }); 
    }
    std::cout << '\n';
}

void output(std::vector<std::string>& v) 
{
    for(std::string &str : v)
        if(str != "\0")
            std::cout << str << ", "; 
        
}

int main() 
{ 
    std::vector<std::string> v = { "abc", "123", "456", "xyz" };
    std::cout << "Before: "; output(v);
    process(v);
    std::cout << "After: "; output(v);
    return 0;
} 

CodePudding user response:

Print first element of your vector. Make comma be printed with next elements.

void output(const std::vector<std::string> &v) {
  if (v.empty()) {  // make sure v is not empty or v[0] will cause U.B.
    return;
  }

  std::cout << v[0];                       // 1st element printed
  for (size_t i = 1; i < v.size();   i) {  // loop starts with 2nd element
    std::cout << ", " << v[i];
  }

  std::cout << '\n';
}

CodePudding user response:

Sometimes, good old syntax is a good thing.

void output(std::vector<std::string>& v)  {
    
    // clean array
    size_t n = v.size();
    while(n--) if(v[n] == '\0') v.erase(v.begin()   n);
    
    // print words
    for(size_t i = 0; i < v.size();   i) {
        std::cout << v[i];
        if(i < (v.size() - 1) std::cout << ", "; 
    }
}

another method

void output(std::vector<std::string>& v)  {

    // clean array
    size_t n = v.size();
    while(n--) if(v[n] == '\0') v.erase(v.begin()   n);

    // print words
    size_t max = v.size() - 1;

    for(size_t i = 0; i < max;   i) 
        std::cout << v[i] << ", "; 

    std::cout << v[max];
}
  • Related