用字符串中的双重替换每次发生
我正在尝试编写一个函数,其第一个参数是字符串,第二个参数是实数的向量。该函数应结果返回一个新的字符串,其中每次发生的新字符串替代了序列“%d”或“%f”,每个数字从向量中,以它们出现的顺序为单位。在这样做时,如果序列为“%d”,则数字中的任何小数是截断的,而在序列“%f”中,它们被保留。
例如,如果字符串读为“ ABC%DXX%fyy%d”,并且矢量包含数字12.25、34.13、25和47,则新字符串应读为“ ABC12XX34.13YY 25”(数据47(数据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;
}
输出:
abc12xx34.13yy 25
abc12xx34.13yy 25
输出是正确的。我如何修改它以减少代码行的工作?有什么方法可以使这种更优雅和高效?
I'm trying to write a function whose first parameter is a string and the second parameter is vector of real numbers. The function should return as a result a new string in which each occurrence replaces the sequences "%d" or "%f" with one number each from the vector, in the order in which they appear. In doing so, if the sequence is "%d", any decimals in the number are truncated, while in the sequence "%f" they are retained.
For example, if the string reads “abc%dxx%fyy %d” and if the vector contains the numbers 12.25, 34.13, 25 and 47, the new string should read “abc12xx34.13yy 25” (data 47 which is “redundant” is simply ignored).
#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
Output is correct. How could I modify this to work with less lines of code? Is there any way to make this more elegant and efficient?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以使用:
(%d |%f)
的正则表达式,进一步详细说明:
while(std :: regex_search)
。std :: Regex_search
将在匹配模式之前返回输入字符串中的所有内容(输出字符串中您想要的内容),匹配的模式(您需要检查的内容以确定是否需要写出int或double),以及剩下的任何东西。std :: Ostringstream
,您可以简单地写出INT或双打而无需将它们转换为字符串。vek.at()
如果您的数据用完了,则会抛出std :: out_of_range
异常。s
(由于我们在函数中修改它),但您应该将vek
作为const传递参考以避免整个向量的副本。[demo]
[edit] [edit]无需
std :: regex_search 将是手动搜索
(%d |%f)
模式,使用std :: string :: find
在循环中,直到字符串的结尾为到达。下面的代码考虑了:
%
字符,后跟d
notd
也不是f 。
[demo]
You could use:
(%d|%f)
, i.e.,%d
or%f
, andGoing into some more detail:
while (std::regex_search)
.std::regex_search
will return whatever was in the input string before the matched pattern (what you want in the output string), the matched pattern (what you will need to check in order to decide if you want to write out an int or a double), and whatever is left to parse.std::ostringstream
, you can simply write out ints or doubles without converting them to strings yourself.vek.at()
will throw anstd::out_of_range
exception if you run out of data in the vector.s
by value (since we are modifying it within the function), you should passvek
as a const reference to avoid a copy of the whole vector.[Demo]
[EDIT] A possible way to do it without
std::regex_search
would be to search for the(%d|%f)
pattern manually, usingstd::string::find
in a loop until the end of the string is reached.The code below takes into account that:
%
character followed by neitherd
norf
.[Demo]