用字符串中的双精度替换每个匹配项
Replace every occurrence with double in string
我正在尝试编写一个函数,其第一个参数是字符串,第二个参数是实数向量。该函数应该 return 作为一个新字符串的结果,其中每次出现都将序列“%d”或“%f”替换为向量中的一个数字,按照它们出现的顺序。这样做时,如果序列是“%d”,数字中的任何小数都将被截断,而在序列“%f”中,它们将被保留。
例如,如果字符串为“abc%dxx%fyy %d”并且向量包含数字 12.25、34.13、25 和 47,则新字符串应为“abc12xx34.13yy 25”(数据 47这是“多余的”被简单地忽略了)。
#include <iostream>
#include <string>
#include <vector>
std::string Replace(std::string s, std::vector < double > vek) {
std::string str;
int j = 0;
for (int i = 0; i < s.length(); i++) {
while (s[i] != '%' && i < s.length()) {
if (s[i] != 'f' && s[i] != 'd')
str += s[i];
i++;
}
if (s[i] == '%' && (s[i + 1] == 'd' || s[i + 1] == 'f')) {
if (s[i + 1] == 'd')
str += (std::to_string(int(vek[j])));
if (s[i + 1] == 'f') {
std::string temp = std::to_string(vek[j]);
int l = 0;
while (temp[l] != '0') {
str += temp[l];
l++;
}
}
j++;
if (j > vek.size())
throw std::range_error("Not enough elements");
if (i == s.length()) break;
}
}
return str;
}
int main() {
try {
std::cout<<Replace("abc%dxx%fyy %d",{12.25, 34.13, 25});
std::cout << "\n" << "abc12xx34.13yy 25";
} catch (std::range_error e) {
std::cout << e.what();
}
return 0;
}
OUTPUT:
abc12xx34.13yy 25
abc12xx34.13yy 25
输出正确。我如何修改它以使用更少的代码行?有没有办法让它更优雅、更高效?
#include <iostream>
#include <vector>
#include <string>
std::string replace(std::string str, std::vector<double> vec) {
std::string result = "";
int i = 0;
// loop through the string
while (i < str.size()) {
// if the current character is a %
if (str[i] == '%') {
// if the next character is a d
if (str[i+1] == 'd') {
// if the vector is not empty
if (vec.size() > 0) {
// add the first element of the vector to the result
result += std::to_string(vec[0]);
// remove the first element of the vector
vec.erase(vec.begin());
}
// move the index to the next character
i += 2;
}
// if the next character is a f
else if (str[i+1] == 'f') {
// if the vector is not empty
if (vec.size() > 0) {
// add the first element of the vector to the result
result += std::to_string(vec[0]);
// remove the first element of the vector
vec.erase(vec.begin());
}
// move the index to the next character
i += 2;
}
// if the next character is not a d or f
else {
// add the current character to the result
result += str[i];
// move the index to the next character
i += 1;
}
}
// if the current character is not a %
else {
// add the current character to the result
result += str[i];
// move the index to the next character
i += 1;
}
}
// return the result
return result;
}
int main() {
std::vector<double> vec = {12.25, 34.13, 25, 47};
std::string str = "abc%dxx%fyy %d";
std::cout << replace(str, vec);
return 0;
}
您可以使用:
- 用于搜索模式
(%d|%f)
的正则表达式,即 %d
或 %f
,以及
- 创建字符串的字符串流 return。
进入更多细节:
- 代码基本上就是一个
while (std::regex_search)
.
std::regex_search
将 return 匹配模式之前的输入字符串中的任何内容(输出字符串中您想要的内容),匹配的模式(您需要检查以决定的内容如果你想写出一个 int 或 double),以及剩下的任何解析。
- 通过使用
std::ostringstream
,您可以简单地写出整数或双精度数,而无需自己将它们转换为字符串。
vek.at()
如果您 运行 向量中的数据不足,将抛出 std::out_of_range
异常。
- 还请注意,对于此实现,最好按值传递字符串
s
(因为我们在函数内修改它),您应该将 vek
作为常量引用传递避免复制整个向量。
#include <iostream>
#include <regex>
#include <stdexcept>
#include <sstream>
#include <string>
#include <vector>
std::string Replace(std::string s, const std::vector<double>& vek) {
std::regex pattern{"(%d|%f)"};
std::smatch match{};
std::ostringstream oss{};
for (auto i{0}; std::regex_search(s, match, pattern); ++i) {
oss << match.prefix();
auto d{vek.at(i)};
oss << ((match[0] == "%d") ? static_cast<int>(d) : d);
s = match.suffix();
}
return oss.str();
}
int main() {
try {
std::cout << Replace("abc%dxx%fyy %d", {12.25, 34.13, 25});
std::cout << "\n"
<< "abc12xx34.13yy 25";
} catch (std::out_of_range& e) {
std::cout << e.what();
}
}
// Outputs:
//
// abc12xx34.13yy 25
// abc12xx34.13yy 25
[编辑] 没有 std::regex_search
的一种可能方法是手动搜索 (%d|%f)
模式,在循环中使用 std::string::find
直到字符串末尾是达到。
下面的代码考虑到了:
- 输入字符串不能有那个模式,那个
- 它可以有一个
%
字符,后面既没有 d
也没有 f
。
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <string>
#include <vector>
std::string Replace(std::string s, const std::vector<double>& vek) {
std::ostringstream oss{};
size_t previous_pos{0};
size_t pos{0};
auto i{0};
while (previous_pos != s.size()) {
if ((pos = s.find('%', previous_pos)) == std::string::npos) {
oss << s.substr(previous_pos);
break;
}
oss << s.substr(previous_pos, pos - previous_pos);
bool pattern_found{false};
if (s.size() > pos + 1) {
auto c{s[pos + 1]};
if (c == 'd') {
oss << static_cast<int>(vek.at(i));
pattern_found = true;
} else if (c == 'f') {
oss << vek.at(i);
pattern_found = true;
}
}
if (pattern_found) {
++i;
previous_pos = pos + 2;
} else {
oss << s[pos];
previous_pos = pos + 1;
}
}
return oss.str();
}
int main() {
try {
std::cout << Replace("abc%%dx%x%fyy %d", {12.25, 34.13, 25}) << "\n";
std::cout << "abc%12x%x34.13yy 25\n";
std::cout << Replace("abcdxxfyy d", {12.25, 34.13, 25}) << "\n";
std::cout << "abcdxxfyy d\n";
} catch (std::out_of_range& e) {
std::cout << e.what();
}
}
// Outputs:
//
// abc%12x%x34.13yy 25
// abc%12x%x34.13yy 25
// abcdxxfyy d
// abcdxxfyy d
我正在尝试编写一个函数,其第一个参数是字符串,第二个参数是实数向量。该函数应该 return 作为一个新字符串的结果,其中每次出现都将序列“%d”或“%f”替换为向量中的一个数字,按照它们出现的顺序。这样做时,如果序列是“%d”,数字中的任何小数都将被截断,而在序列“%f”中,它们将被保留。
例如,如果字符串为“abc%dxx%fyy %d”并且向量包含数字 12.25、34.13、25 和 47,则新字符串应为“abc12xx34.13yy 25”(数据 47这是“多余的”被简单地忽略了)。
#include <iostream>
#include <string>
#include <vector>
std::string Replace(std::string s, std::vector < double > vek) {
std::string str;
int j = 0;
for (int i = 0; i < s.length(); i++) {
while (s[i] != '%' && i < s.length()) {
if (s[i] != 'f' && s[i] != 'd')
str += s[i];
i++;
}
if (s[i] == '%' && (s[i + 1] == 'd' || s[i + 1] == 'f')) {
if (s[i + 1] == 'd')
str += (std::to_string(int(vek[j])));
if (s[i + 1] == 'f') {
std::string temp = std::to_string(vek[j]);
int l = 0;
while (temp[l] != '0') {
str += temp[l];
l++;
}
}
j++;
if (j > vek.size())
throw std::range_error("Not enough elements");
if (i == s.length()) break;
}
}
return str;
}
int main() {
try {
std::cout<<Replace("abc%dxx%fyy %d",{12.25, 34.13, 25});
std::cout << "\n" << "abc12xx34.13yy 25";
} catch (std::range_error e) {
std::cout << e.what();
}
return 0;
}
OUTPUT:
abc12xx34.13yy 25
abc12xx34.13yy 25
输出正确。我如何修改它以使用更少的代码行?有没有办法让它更优雅、更高效?
#include <iostream>
#include <vector>
#include <string>
std::string replace(std::string str, std::vector<double> vec) {
std::string result = "";
int i = 0;
// loop through the string
while (i < str.size()) {
// if the current character is a %
if (str[i] == '%') {
// if the next character is a d
if (str[i+1] == 'd') {
// if the vector is not empty
if (vec.size() > 0) {
// add the first element of the vector to the result
result += std::to_string(vec[0]);
// remove the first element of the vector
vec.erase(vec.begin());
}
// move the index to the next character
i += 2;
}
// if the next character is a f
else if (str[i+1] == 'f') {
// if the vector is not empty
if (vec.size() > 0) {
// add the first element of the vector to the result
result += std::to_string(vec[0]);
// remove the first element of the vector
vec.erase(vec.begin());
}
// move the index to the next character
i += 2;
}
// if the next character is not a d or f
else {
// add the current character to the result
result += str[i];
// move the index to the next character
i += 1;
}
}
// if the current character is not a %
else {
// add the current character to the result
result += str[i];
// move the index to the next character
i += 1;
}
}
// return the result
return result;
}
int main() {
std::vector<double> vec = {12.25, 34.13, 25, 47};
std::string str = "abc%dxx%fyy %d";
std::cout << replace(str, vec);
return 0;
}
您可以使用:
- 用于搜索模式
(%d|%f)
的正则表达式,即%d
或%f
,以及 - 创建字符串的字符串流 return。
进入更多细节:
- 代码基本上就是一个
while (std::regex_search)
. std::regex_search
将 return 匹配模式之前的输入字符串中的任何内容(输出字符串中您想要的内容),匹配的模式(您需要检查以决定的内容如果你想写出一个 int 或 double),以及剩下的任何解析。- 通过使用
std::ostringstream
,您可以简单地写出整数或双精度数,而无需自己将它们转换为字符串。 vek.at()
如果您 运行 向量中的数据不足,将抛出std::out_of_range
异常。- 还请注意,对于此实现,最好按值传递字符串
s
(因为我们在函数内修改它),您应该将vek
作为常量引用传递避免复制整个向量。
#include <iostream>
#include <regex>
#include <stdexcept>
#include <sstream>
#include <string>
#include <vector>
std::string Replace(std::string s, const std::vector<double>& vek) {
std::regex pattern{"(%d|%f)"};
std::smatch match{};
std::ostringstream oss{};
for (auto i{0}; std::regex_search(s, match, pattern); ++i) {
oss << match.prefix();
auto d{vek.at(i)};
oss << ((match[0] == "%d") ? static_cast<int>(d) : d);
s = match.suffix();
}
return oss.str();
}
int main() {
try {
std::cout << Replace("abc%dxx%fyy %d", {12.25, 34.13, 25});
std::cout << "\n"
<< "abc12xx34.13yy 25";
} catch (std::out_of_range& e) {
std::cout << e.what();
}
}
// Outputs:
//
// abc12xx34.13yy 25
// abc12xx34.13yy 25
[编辑] 没有 std::regex_search
的一种可能方法是手动搜索 (%d|%f)
模式,在循环中使用 std::string::find
直到字符串末尾是达到。
下面的代码考虑到了:
- 输入字符串不能有那个模式,那个
- 它可以有一个
%
字符,后面既没有d
也没有f
。
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <string>
#include <vector>
std::string Replace(std::string s, const std::vector<double>& vek) {
std::ostringstream oss{};
size_t previous_pos{0};
size_t pos{0};
auto i{0};
while (previous_pos != s.size()) {
if ((pos = s.find('%', previous_pos)) == std::string::npos) {
oss << s.substr(previous_pos);
break;
}
oss << s.substr(previous_pos, pos - previous_pos);
bool pattern_found{false};
if (s.size() > pos + 1) {
auto c{s[pos + 1]};
if (c == 'd') {
oss << static_cast<int>(vek.at(i));
pattern_found = true;
} else if (c == 'f') {
oss << vek.at(i);
pattern_found = true;
}
}
if (pattern_found) {
++i;
previous_pos = pos + 2;
} else {
oss << s[pos];
previous_pos = pos + 1;
}
}
return oss.str();
}
int main() {
try {
std::cout << Replace("abc%%dx%x%fyy %d", {12.25, 34.13, 25}) << "\n";
std::cout << "abc%12x%x34.13yy 25\n";
std::cout << Replace("abcdxxfyy d", {12.25, 34.13, 25}) << "\n";
std::cout << "abcdxxfyy d\n";
} catch (std::out_of_range& e) {
std::cout << e.what();
}
}
// Outputs:
//
// abc%12x%x34.13yy 25
// abc%12x%x34.13yy 25
// abcdxxfyy d
// abcdxxfyy d