[英]Creating a recursion in c++
我正在學習如何編寫遞歸,我對如何將 function 的主體簡化為遞歸感到困惑。
對於我目前的任務,我必須“通過交替的字符來對兩個字符串進行網格划分。如果一個字符串在另一個之前用完,只需從較長的那個中挑選。例如,mesh("Fred", "Wilma") 是 "FWrieldma “。使用遞歸。不要使用循環。”
嗯......我創建了循環......
string result;
for (int i = 0; i < a.size(); ++i)
{
result += a.at(i) + b.at(i)
}
但是把它變成一個遞歸讓我很難過。
這是我到目前為止所擁有的(我們不允許在標記的位置上方或下方更改任何內容):
#include <string>
using namespace std;
/**
Combines alternate characters from each string.
@param a the first string.
@param b the second string
*/
string mesh(string a, string b)
{
// INSERT CODE BENEATH HERE
string result;
if (a.size() < 1) result = b;
if (b.size() < 1) result = a;
else
{
result = a.at(0) + b.at(1);
}
return result;
// ENTER CODE ABOVE HERE
}
但我知道這是不對的,因為沒有遞歸而且它完全不起作用
我認為這可以滿足您的要求,並保持 function 原型完好無損。 它看起來也類似於您建議的代碼。
#include <iostream>
using namespace std;
string mesh(string a, string b) {
if (!a.size()) return b;
if (!b.size()) return a;
return a[0] + (b[0] + mesh(a.substr(1), b.substr(1)));
}
int main(int argc, char const *argv[])
{
printf("%s\n", mesh("Fred", "Wilma").c_str());
return 0;
}
首先嘗試找出遞歸的單步。 有不止一種方法可以做到這一點,一種可能性是通過使用一些索引pos
遍歷字符串,並在一個步驟中從字符串的各個位置添加字符:
std::string mesh(const std::string& a, const std::string& b,size_t pos) {
/*...*/
std::string result;
if (pos < a.size()) result += a[pos];
if (pos < b.size()) result += b[pos];
/*...*/
}
為了遞歸,我們再次為下一個索引和 append 調用該方法以得到結果:
std::string mesh(const std::string& a, const std::string& b,size_t pos = 0) {
/*...*/
std::string result;
if (pos < a.size()) result += a[pos];
if (pos < b.size()) result += b[pos];
return result + mesh(a,b,pos+1);
}
最后我們需要一個停止條件。 當兩個字符串在索引pos
處沒有更多字符時,遞歸應該停止:
std::string mesh(const std::string& a, const std::string& b,size_t pos = 0) {
if (pos >= a.size() && pos >= b.size()) return "";
std::string result;
if (pos < a.size()) result += a[pos];
if (pos < b.size()) result += b[pos];
return result + mesh(a,b,pos+1);
}
例如:
int main() {
std::cout << mesh("Fred","Wilma");
}
將產生所需的FWrieldma
output。
免責聲明:正如 SergeyA 所指出的,我在寫這個答案時並沒有過多關注性能。 我想這是一個練習遞歸的練習,而實際上我看不出有理由通過遞歸來實現它。
只需添加到 large_prime_is_463035 的答案。 如果您必須保持mesh
的簽名相同,那么您將創建另一個具有實際實現的 function,現在mesh
只能被稱為兩個字符串 arguments。
#include <string>
#include <iostream>
using namespace std;
/**
Combines alternate characters from each string.
@param a the first string.
@param b the second string
*/
void meshInternal(const string a, const string b, string& result, unsigned int index=0){
if(index >= a.size()){
result += b.substr(index);
return;
}
if(index >= b.size()){
result += a.substr(index);
return;
}
result.push_back(a[index]);
result.push_back(b[index]);
meshInternal(a, b, result, ++index);
}
string mesh(const string a, const string b)
{
string result = "";
meshInternal("Fred", "Wilma", result);
return result;
}
int main() {
string result = mesh("Fred", "Wilma");
std::cout << result << std::endl;
return 2;
}
由於不可能在mesh
function 中傳遞另一個參數,但在每個遞歸調用中,我們需要知道string a
和string b
中的哪個字符將附加到結果中。 一個簡單的解決方案可能是從string a
和string b
中刪除第一個字符,並將 append 刪除到結果中。 現在,當我們傳遞string a
和string b
作為引用時,刪除第一個字符最終會在一段時間后使字符串為空。 因此,我們可以檢查string a
和string b
是否都為空,並將其設置為遞歸調用的基本情況。
這段代碼解決了這個問題:
std::string mesh(string& a, string& b) {
if (a.size() == 0 && b.size() == 0) return "";
std::string result;
if (a.size()) {
result += a[0];
a.erase(0, 1);
}
if (b.size()) {
result += b[0];
b.erase(0, 1);
}
return result + mesh(a,b);
}
int main()
{
string a = "Fred";
string b = "Wilma";
std::cout << mesh(a,b);
return 0;
}
#include <string>
#include <iostream>
#include <string_view>
// recursive mesh function.
// passing the result object for effeciency.
void mesh(std::string& result, std::string_view l, std::string_view r)
{
// check the exit condition.
// If either the left of right are empty add the other to the result.
if (std::begin(l) == std::end(l)) {
result += r;
return;
}
if (std::begin(r) == std::end(r)) {
result += l;
return;
}
// Add letter from the left and right to the result.
result += *std::begin(l);
result += *std::begin(r);
// Adjust the size of the view
l.remove_prefix(1);
r.remove_prefix(1);
// recursively call to get the next letter.
mesh(result, l, r);
}
// Utility wrapper to get view of strings and create
// the result object to be passed to the recursive function.
std::string mesh(std::string const& l, std::string const& r)
{
std::string result;
mesh(result, std::string_view(l), std::string_view(r));
return result;
}
int main()
{
std::cout << mesh("Fred", "Wilma");
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.