使用循环替换字符串中的字符(需要帮助优化)
Using loops to replace characters in a string (need help optimizing)
对于我的一个CS作业,我被告知
"(1)从用户那里获得一个单词的输入。输出单词。如果单词包含某些字符,使用您选择的循环将它们替换为相应的符号或数字。
示例输出:
Enter word: sixteen
You entered: sixteen
New word: $!*t33n
你应该支持这些字符:
a—@
e—3
i——!
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语句更好的方法来确保任何可替换字母的每个实例都将被替换。
任何见解将不胜感激!
使用c++的标准模板库,这应该很容易。使用std::transform
和std::map<..>
关联容器
(假设c++ 11可用见下面的'真正的' 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;
}
看到,在这里运行程序:https://ideone.com/GROl6p
编辑:再多考虑一下,使用更多c++ 11的特性,它可以做得更好。下面的基本思想是,我们用一个函数调用操作符修饰std::map
;对于转换来说,只有映射才是必需的。这是通过继承std::map
并定义operator()
来实现的。
在这个派生类中定义c++ 11的转发构造函数,并使用可变的模板参数。这意味着可以使用std::map
的初始化列表构造函数原位创建派生类型;不需要创建std::map
和派生(装饰)类型的单独实例。
代码现在类型更安全,更重要的是,'mapper'现在是泛型的,可以轻松地用于任何替换映射操作。
#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
不打算提供完整的代码示例,因为这听起来像是家庭作业。
最有效的方法是创建一个ASCII替换映射:const substitution[] = " !"#$%&'()*+,-./0123456789:;<=>?@BCD3F9H!JKLMNOPQR$TUVW*YZ[]^_`@bcd3f9h!jklmnopqr$tuvw*yz{|}~";
然后循环遍历输入并将每个字符替换为替换映射中的相应字符:
for (int i = 0; i < myWord.size(); i++)
{
myWord[i] = substitution[myWord[i] - 32];
}
你可以在一个循环中完成所有这些。
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
- 空基优化子对象的地址
- 需要帮助设置在C++中使用的Potrace
- 在指针的帮助下,文本文件中单词的频率
- 关闭||运算符优化
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- 计算每个节点的树高,帮助我解释这个代码解决方案
- 需要帮助优化C++中循环/点积函数的速度
- 使用 assert 帮助编译器更好地优化
- 具有查找表的可选帮助的对象查找,如果未使用,则必须对其进行优化
- 需要帮助优化C++
- 需要帮助在 c++ 中优化埃拉托色尼筛
- 优化运行帮助
- 向指针添加"const"可以帮助优化吗?
- 需要帮助优化找到所有可能子字符串的程序
- 使用循环替换字符串中的字符(需要帮助优化)
- 返回值的c++函数,需要帮助优化
- OpenCV / c++中的优化帮助
- 帮助编译器优化分支代码序列
- constexpr vs const:将使用constexpr而不是const更好地帮助编译以优化
- 帮助将数学函数转换为代码:线性卡尔曼粒子群优化