string repetition replaced by hyphen c++

2020-04-21 06:58发布

问题:

I am a beginner at coding, and was trying this question that replaces all repetitions of a letter in a string with a hyphen: i.e ABCDAKEA will become ABCD-KE-.I used the switch loop and it works, but i want to make it shorter and maybe use recursion to make it more effective. Any ideas?

    #include<iostream>
    #include<string.h>
    using namespace std;
    int main()
    {
    char x[100];    
    int count[26]={0}; //initialised to zero
    cout<<"Enter string: ";
    cin>>x;
    for(int i=0; i<strlen(x); i++)
    {
    switch(x[i])
    {
    case 'a':
        {
        if((count[0]++)>1)
        x[i]='-';
        }
    case 'b':
        {
        if((count[1]++)>1)
        x[i]='-';
        }
    case 'c':
        {
        if((count[2]++)>1)
        x[i]='-';
        }
        //....and so on for all alphabets, ik not the cutest//
      }
      }

回答1:

First, notice English capital letters in ASCII table fall in this range 65-90. Casting a capital letter static_cast<int>('A') will yield an integer. If after casing the number is between 65-90, we know it is a capital letter. For small letters, the range is 97-122. Otherwise the character is not a letter basically.

Check create an array or a vector of bool and track the repetitive letters. Simple approach is

#include <iostream>
#include <string>
#include <vector>
using namespace std;

int main()
{
    string str("ABCDAKEAK");
    vector<bool> vec(26,false);

    for(int i(0); i < str.size(); ++i){
        if(  !vec[static_cast<int>(str[i]) - 65]  ){
            cout << str[i];
            vec[static_cast<int>(str[i]) - 65] = true;
        }else{
            cout << "-";
        }   
    }
    cout << endl;

    return 0;
}

Note: I assume the input solely letters and they are capital. The idea is centered around tracking via bool.



回答2:

Iterate through the array skipping whitespace, and put characters you've never encountered before in std::set, if you find them again you put them in a duplicates std::set if you'd like to keep track of how many duplicates there are, otherwise change the value of the original string at that location to a hyphen.

#include <iostream> 
#include <string>
#include <cctype>
#include <set>

int main() {
    std::string s("Hello world");
    std::set<char> characters;
    std::set<char> duplicates;

    for (std::string::size_type pos = 0; pos < s.size(); pos++) {
        char c = s[pos];

        // std::isspace() accepts an int, so cast c to an int
        if (!std::isspace(static_cast<int>(c))) {
            if (characters.count(c) == 0) {
                characters.insert(c);
            } else {
                duplicates.insert(c);
                s[pos] = '-';
            }
        }
    }

return 0;
}


回答3:

Naive (inefficient) but simple approach, requires at least C++11.

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

std::string f(std::string s)
{
  auto first{s.begin()};
  const auto last{s.end()};
  while (first != last)
  {
    auto next{first + 1};
    if (std::isalpha(static_cast<unsigned char>(*first)))
      std::replace(next, last, *first, '-');
    first = next;
  }
  return s;
}

int main()
{
  const std::string input{"ABCDBEFKAJHLB"};
  std::cout << f(input) << '\n';
  return 0;
}


回答4:

When you assume input charactor encode is UTF-8, you can refactor like below:

#include <iostream>
#include <string>
#include <optional>
#include <utility>
std::optional<std::size_t> char_to_index(char u8char){
    if (u8'a' <= u8char && u8char <= u8'z'){
        return u8char - u8'a';
    }
    else if (u8'A' <= u8char && u8char <= u8'A'){
        return u8char - u8'A';
    }
    else {
        return std::nullopt;
    }
}
std::string repalce_mutiple_occurence(std::string u8input, char u8char)
{
    bool already_found[26] = {};
    for(char& c : u8input){
        if (const auto index = char_to_index(c); index && std::exchange(already_found[*index], true)){
            c = u8char;
        }
    }
    return u8input;
}
int main(){
    std::string input;
    std::getline(std::cin, input);
    std::cout << repalce_mutiple_occurence(input, u8'-');
}

https://wandbox.org/permlink/UnVJHWH9UwlgT7KB

note: On C++20, you should use char8_t instead of using char.