2016-07-03 85 views
1

我正在通過解決Euler項目中的問題來學習自己的C++。其中一個練習是要找到最大的主要因素,這是我找到解決的最快方法是使用分而治之,使用下面的代碼片段:在C++中連接並返回數組

long primeFactor1(long n); 

long primeFactor(long n) 
{ 
    long divisorR = findDivisor(n); 
    long divisorL = n/divisorR; 

    if (divisorR == n){ 
     return divisorR; 
    } 

    long primeFactorDivL = primeFactor1(divisorL); 
    long primeFactorDivR = primeFactor1(divisorR); 

    return std::max(primeFactorDivL,primeFactorDivR); 
} 

long primeFactor1(long n) 
{ 
    std::cout << "Is "<<n<< " a prime? " << checkPrime(n) << std::endl; 
    if (checkPrime(n)){ 
     return n; 
    } 
    else{ 
     return primeFactor(n); 
    } 
} 

哪裏checkPrime是檢查它的一些功能是一個質數,findDivisor找到數n的最小偶數除數。所以這個程序很好地工作,並且即使給出問題中給出的數字(這是相當大的,至少可以說)也立即給出和輸出。

我的問題是,但是,我想轉換程序返回所有的素因子,而不是最大的。這意味着我基本上已經改變:

return std::max(primeFactorDivL,primeFactorDivR); 

的東西,符連接兩個替代和調整,使得它們能夠返回所產生的陣列功能。

在Matlab中,我來自我只是把方括號括在s.t.

[primeFactorDivL,primeFactorDivR] 

什麼是最好的(最好也是最簡單的)方式來做到這一點在C + +?

UPDATE:

我曾嘗試使用載體,它可以在下面的葉子使用類型轉換的代碼可以看出實現它。但是,試圖編譯它,我得到的編譯錯誤:

primeFactor.cpp:51:9: error: no viable conversion from 'typename 
     enable_if<__is_forward_iterator<__wrap_iter<long *> >::value && is_constructible<value_type, typename 
     iterator_traits<__wrap_iter<long *> >::reference>::value, iterator>::type' (aka 
     'std::__1::__wrap_iter<long *>') to 'std::vector<long>' 
    ...primeFactorDivL.insert(primeFactorDivL.end(), primeFactorDivR.begin(), primeFactorDivR.end()); 
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:568:5: note: candidate constructor not 
     viable: no known conversion from 'typename enable_if<__is_forward_iterator<__wrap_iter<long *> 
     >::value && is_constructible<value_type, typename iterator_traits<__wrap_iter<long *> 
     >::reference>::value, iterator>::type' (aka 'std::__1::__wrap_iter<long *>') to 'const 
     std::__1::vector<long, std::__1::allocator<long> > &' for 1st argument 
    vector(const vector& __x); 
    ^
1 error generated. 

在哪裏我的代碼現在是:用C

std::vector<long> primeFactor1(long n); 

std::vector<long> primeFactor(long n) 
{ 
    long divisorR = findDivisor(n); 
    long divisorL = n/divisorR; 

    if (divisorR == n){ 
     return std::vector<long>(divisorR); 
    } 

    std::vector<long> primeFactorDivL(primeFactor1(divisorL)); 
    std::vector<long> primeFactorDivR(primeFactor1(divisorR)); 

    return primeFactorDivL.insert(primeFactorDivL.end(), primeFactorDivR.begin(), primeFactorDivR.end()); 
} 

std::vector<long> primeFactor1(long n) 
{ 
    std::cout << "Is "<<n<< " a prime? " << checkPrime(n) << std::endl; 
    if (checkPrime(n)){ 
     return std::vector<long>(n); 
    } 
    else{ 
     return primeFactor(n); 
    } 
} 
+0

通過'std :: vector '你可以創建一個兩個數字的向量,就像'{a,b}'一樣。我相信這個練習的有趣之處在於(但我沒有分析過,而且對我來說晚了),以避免O(n^2)行爲。我認爲這主要涉及將結果向量作爲參考參數傳遞。另一種可能性是使用鏈表(比如'std :: list '),但我想我會選擇vector參數。或者你可以重新表達你的算法迭代。在這種情況下,推送項目只需使用'std :: vector :: push_back'。 –

+2

你沒有做你的功能狀態。你應該在該函數中返回一個'std :: vector ',但是你要返回'insert()'的值。在完成需要完成的任何工作後,您應該簡單地返回'primeFactorDivL;'。 – PaulMcKenzie

+0

我終於認爲我明白這是如何工作的。謝謝。 –

回答

3

陣列++有一個固定的大小,所以你必須動態地各新建一個你連接的時候,你必須記住delete舊的。所以我建議只使用vectors

已經有a question on concatenating vectors其這樣做:

vector1.insert(vector1.end(), vector2.begin(), vector2.end()); 
+0

在這種情況下,我該如何啓動這個過程?在葉子上,我返回長整數,如何將這兩個結合成一個向量? –

+0

由於'primeFactor()'和'primeFactor1()'之間的調用是遞歸的,因此您需要將參數的類型和這兩個函數的返回類型更改爲'std :: vector '。然後改變它們中的邏輯,根據它們接收的數組中的更大(或最後一個,取決於如何實現插入)元素作爲參數進行計算。 你也可以單獨保留你的代碼的邏輯,並保留一個全局數組,在你從'primeFactor()' –

+0

返回之前推入。我試圖用給定的內容更新它,但是現在我收到顯示的錯誤以上。 –

2

這裏有多種可能性。既然你只想返回一對數字,你可以返回一個std :: pair。您將需要

  • #include <utility>
  • 變化primeFactor的返回類型爲std ::對
  • 變化return語句return {primeFactorDivL, primeFactorDivR};

最後一點依靠的C++特性11,所以你將不得不確保這是爲你的編譯器啓用的。在早期的C++中,您可以改爲return std::make_pair(primeFactorDivL, primeFactorDivR)

+0

我可能會誤解它,但我不只是返回一對數字。我正在創建一個二叉樹,其中最低層是兩個連接的數字,但高於一個連接兩個數字對的層,等等。 –

+0

不,這是我的不好 - 我只看你的最低水平。在那種情況下,我同意KevinPeña的回答 – Spacemoose