我正在嘗試撰寫一個函式,其第一個引數是字串,第二個引數是實數向量。作為結果,該函式應回傳一個新字串,其中每次出現都將序列“%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;
}
輸出:
abc12xx34.13yy 25
abc12xx34.13yy 25
輸出正確。我如何修改它以使用更少的代碼行?有什么辦法可以讓這更優雅、更高效?
uj5u.com熱心網友回復:
你可以使用:
- 正則運算式來搜索模式
(%d|%f)
, ie,%d
or%f
, and - 用于創建要回傳的字串的字串流。
進入更多細節:
- 代碼基本上是一個
while (std::regex_search)
. std::regex_search
將回傳匹配模式之前的輸入字串中的任何內容(您想要的輸出字串中的內容)、匹配的模式(您需要檢查的內容以確定您是要寫出 int 還是 double),以及剩下要決議的東西。- 通過使用
std::ostringstream
,您可以簡單地寫出整數或雙精度數,而無需自己將它們轉換為字串。 vek.at()
std::out_of_range
如果向量中的資料用完,將引發例外。- 還要注意,雖然對于這個實作,最好
s
按值傳遞字串(因為我們在函式中修改它),但您應該vek
作為 const 參考傳遞以避免整個向量的副本。
[演示]
#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
下面的代碼考慮到:
- 輸入字串不能具有該模式,并且
- 它可以有一個
%
字符,后跟 noned
或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 << "abcx%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:
//
// abcx%x34.13yy 25
// abcx%x34.13yy 25
// abcdxxfyy d
// abcdxxfyy d
uj5u.com熱心網友回復:
#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;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/470094.html