使用循环替换字符串中的字符(需要帮助优化)

时间:2015-10-21 19:08:11

标签: c++

对于我的一项CS任务,我被告知

"(1)从用户那里获得一个输入词。输出这个词。如果单词包含某些字符,请使用您选择的循环将其替换为相应的符号或数字。

示例输出:

    Enter word: sixteen
    You entered: sixteen
    New word: $!*t33n

你应该支持这些字符:

a - @

e - 3

我 - !

g - 9

s - $

x - *

如果您的单词不包含上述任何字符,请再次打印原始单词。"

现在,我能够使用无数的while和for循环来解决这个问题。但是,我认为必须有一种更有效的方法来完成这项任务。

以下是我希望优化的相关代码:

while (userWord.find('a') != string::npos) {
     hasA = userWord.find('a');

  userWord.replace( userWord.find('a'), 1, "@");

   if (userWord.find('a') != string::npos) {
      hasA = userWord.find('a');

      userWord.replace( userWord.find('a'), 1, "@");
   }
   else if (userWord.find('e') != string::npos) {
      hasA = userWord.find('e');

      userWord.replace( userWord.find('e'), 1, "3");
   }
   else if (userWord.find('i') != string::npos) {
      hasA = userWord.find('i');

      userWord.replace( userWord.find('i'), 1, "!");
   }
   else if (userWord.find('g') != string::npos) {
      hasA = userWord.find('g');

      userWord.replace( userWord.find('g'), 1, "9");
   }
   else if (userWord.find('s') != string::npos) {
      hasA = userWord.find('s');

      userWord.replace( userWord.find('s'), 1, "$");
   }
  else if (userWord.find('x') != string::npos) {
      hasA = userWord.find('x');

      userWord.replace( userWord.find('x'), 1, "*");
   }

}

while (userWord.find('e') != string::npos) {
  hasA = userWord.find('e');

  userWord.replace( userWord.find('e'), 1, "3");

  if (userWord.find('a') != string::npos) {
      hasA = userWord.find('a');

      userWord.replace( userWord.find('a'), 1, "@");
  }
  else if (userWord.find('e') != string::npos) {
      hasA = userWord.find('e');

      userWord.replace( userWord.find('e'), 1, "3");
  }
  else if (userWord.find('i') != string::npos) {
      hasA = userWord.find('i');

      userWord.replace( userWord.find('i'), 1, "!");
  }
  else if (userWord.find('g') != string::npos) {
      hasA = userWord.find('g');

      userWord.replace( userWord.find('g'), 1, "9");
  }
  else if (userWord.find('s') != string::npos) {
      hasA = userWord.find('s');

      userWord.replace( userWord.find('s'), 1, "$");
  }
  else if (userWord.find('x') != string::npos) {
      hasA = userWord.find('x');

      userWord.replace( userWord.find('x'), 1, "*");
  }

}

while (userWord.find('i') != string::npos) {
  hasA = userWord.find('i');

  userWord.replace( userWord.find('i'), 1, "!");

if (userWord.find('a') != string::npos) {
      hasA = userWord.find('a');

      userWord.replace( userWord.find('a'), 1, "@");
  }
  else if (userWord.find('e') != string::npos) {
      hasA = userWord.find('e');

      userWord.replace( userWord.find('e'), 1, "3");
  }
  else if (userWord.find('i') != string::npos) {
      hasA = userWord.find('i');

      userWord.replace( userWord.find('i'), 1, "!");
  }
  else if (userWord.find('g') != string::npos) {
      hasA = userWord.find('g');

      userWord.replace( userWord.find('g'), 1, "9");
  }
  else if (userWord.find('s') != string::npos) {
      hasA = userWord.find('s');

      userWord.replace( userWord.find('s'), 1, "$");
  }
  else if (userWord.find('x') != string::npos) {
      hasA = userWord.find('x');

      userWord.replace( userWord.find('x'), 1, "*");
  }

}

while (userWord.find('g') != string::npos) {
  hasA = userWord.find('g');

  userWord.replace( userWord.find('g'), 1, "9");
  if (userWord.find('a') != string::npos) {
      hasA = userWord.find('a');

      userWord.replace( userWord.find('a'), 1, "@");
  }
  else if (userWord.find('e') != string::npos) {
      hasA = userWord.find('e');

      userWord.replace( userWord.find('e'), 1, "3");
  }
  else if (userWord.find('i') != string::npos) {
      hasA = userWord.find('i');

      userWord.replace( userWord.find('i'), 1, "!");
  }
  else if (userWord.find('g') != string::npos) {
      hasA = userWord.find('g');

      userWord.replace( userWord.find('g'), 1, "9");
  }
  else if (userWord.find('s') != string::npos) {
      hasA = userWord.find('s');

      userWord.replace( userWord.find('s'), 1, "$");
  }
  else if (userWord.find('x') != string::npos) {
      hasA = userWord.find('x');

      userWord.replace( userWord.find('x'), 1, "*");
  }

}

while (userWord.find('s') != string::npos) {
  hasA = userWord.find('s');

  userWord.replace( userWord.find('s'), 1, "$");
 if (userWord.find('a') != string::npos) {
      hasA = userWord.find('a');

      userWord.replace( userWord.find('a'), 1, "@");
  }
  else if (userWord.find('e') != string::npos) {
      hasA = userWord.find('e');

      userWord.replace( userWord.find('e'), 1, "3");
  }
  else if (userWord.find('i') != string::npos) {
      hasA = userWord.find('i');

      userWord.replace( userWord.find('i'), 1, "!");
  }
  else if (userWord.find('g') != string::npos) {
      hasA = userWord.find('g');

      userWord.replace( userWord.find('g'), 1, "9");
  }
  else if (userWord.find('s') != string::npos) {
      hasA = userWord.find('s');

      userWord.replace( userWord.find('s'), 1, "$");
  }
  else if (userWord.find('x') != string::npos) {
      hasA = userWord.find('x');

      userWord.replace( userWord.find('x'), 1, "*");
  }

}

while (userWord.find('x') != string::npos) {
  hasA = userWord.find('x');

  userWord.replace( userWord.find('x'), 1, "*");
  if (userWord.find('a') != string::npos) {
      hasA = userWord.find('a');

      userWord.replace( userWord.find('a'), 1, "@");
  }
  else if (userWord.find('e') != string::npos) {
      hasA = userWord.find('e');

      userWord.replace( userWord.find('e'), 1, "3");
  }
  else if (userWord.find('i') != string::npos) {
      hasA = userWord.find('i');

      userWord.replace( userWord.find('i'), 1, "!");
  }
  else if (userWord.find('g') != string::npos) {
      hasA = userWord.find('g');

      userWord.replace( userWord.find('g'), 1, "9");
  }
  else if (userWord.find('s') != string::npos) {
      hasA = userWord.find('s');

      userWord.replace( userWord.find('s'), 1, "$");
  }
  else if (userWord.find('x') != string::npos) {
      hasA = userWord.find('x');

      userWord.replace( userWord.find('x'), 1, "*");
  }

}
cout << "New word: " << userWord << endl;

必须有一种比在每个while循环之后重新嵌套每个if语句更好的方法,以确保任何可替换字母的每个实例都将被实际替换。

非常感谢任何见解!

3 个答案:

答案 0 :(得分:1)

使用C ++的标准模板库这应该很容易。使用std::transformstd::map<..>关联容器。

(假设C ++ 11可用请参阅下面的&#39;真正的C ++ 11实现!

#include <map>
#include <iostream>
#include <string>
#include <algorithm>
#include <iterator>

// A functor (object posing as function call)
struct charmapper {
    charmapper( const std::map<char, char>& cm):
       charmap( cm )
    {}

    // If the character 'in' is present in the std::map<>
    // return the mapped character, otherwise the original character
    char operator()(char in) const {
        std::map<char, char>::iterator entry = charmap.find(in);
        return (entry == charmap.end()) ? in : entry->second;
    }
    std::map<char, char>  charmap;
};

int main(void) {
   // Here define your character replacements
   std::map<char, char>  toreplace{ {'a', '@'}, {'i', '1'} }; // etc

   std::string  input{ "This is an input string" };
   std::string  output;

   // Now transform the input string, using the charmapper functor
   std::transform(input.begin(), input.end(), std::back_inserter(output),
                  charmapper(toreplace) );

   // Display to check what transform has done
   std::cout << output << std::endl;
   return 0;
}

见&amp;在这里运行程序:https://ideone.com/GROl6p

修改 考虑到它的更多思考,使用更多C ++ 11的功能可以做得更好。下面的基本思想是我们用函数调用操作符来装饰std::map;对于转换,没有什么但是地图应该是必要的。这是通过继承std::map并定义operator()

来完成的

在此派生类中,使用可变参数模板参数定义C ++ 11的转发构造函数。这意味着可以使用std::map的初始化列表构造函数原位创建派生类型;无需创建std::map和派生(修饰)类型的单独实例。

现在代码类型更安全了,更重要的是,&#39;映射器&#39;现在是通用的,可以简单地用于任何替换映射操作。

#include <map>
#include <iostream>
#include <string>
#include <algorithm>
#include <iterator>

using std::string; using std::map;

template <typename ...Types>
struct mapper : public map<Types...> {
    typedef map<Types...> Self;
    using map<Types...>::map;

    // C++11 forwarding constructor!
    template <typename ...Args>
    mapper(Args... args) : map<Types...>(args...) {}

    // Decorate the std::map<> with function call operator
    typename Self::mapped_type operator()(const typename Self::key_type& k) const {
        typename Self::const_iterator  ptr = this->find(k);
        return (ptr==this->end()) ? typename Self::mapped_type(k) : ptr->second;
    }
};

int main(void) {
   string  input{ "This is an input string" };
   string  output;

   // Now transform the input string, using the mapperr
   std::transform(input.begin(), input.end(), std::back_inserter(output),
                  mapper<string::value_type, string::value_type>({{'a', '@'}, {'i','1'}}) );

   // Display to check what transform has done
   std::cout << output << std::endl;
   return 0;
}

在此处查看此行动:https://ideone.com/vmON0E

答案 1 :(得分:0)

你可以在一个循环中完成所有这些。

int main()
{
  string myWord;
  cout << "enter a word: ";
  cin >> myWord;
  for(unsigned int i = 0; i < myWord.size(); i++)
  {
    if(myWord[i]=='a')
      myWord[i] = '@';
    else if(myWord[i] == 'e')
      myWord[i] = '3';
    else if(myWord[i] == 'i')
      myWord[i] = '!';
    else if(myWord[i] == 'g')
      myWord[i] = '9';
    else if(myWord[i] == 's')
      myWord[i] = '$';
    else if(myWord[i] == 'x')
      myWord[i] = '*';
  }
  cout << myWord;
}

看到它在这里运行http://cpp.sh/86qh

答案 2 :(得分:0)

不会提供完整的代码示例,因为这有点像家庭作业。

最有效的方法是创建一个ASCII替换映射:

for (int i = 0; i < myWord.size(); i++)
{
    myWord[i] = substitution[myWord[i] - 32];
}

然后循环输入并用替换映射中的相应字符替换每个字符:

#!/usr/bin/env bash
cat fifo | while read line
do
  echo $line
done