2011-11-09 16 views
1

我不是想要求你們幫我做作業,因爲我已經做了大量的研究,也嘗試自己編程,但仍然遇到問題,我覺得到目前爲止,我知道問題出在哪裏,但仍然沒有解決方案可以找出由我:返回給定數字之前的所有素數(家庭作業C++)

守則

#include <iostream> 
#include <string> 
#include <cmath> 

int main(void) 
{ 
using namespace std; 

int num; 
int max; 
string answer = ""; 

cin >> num; 

for(int i = 2 ; i < num ; i++) 
{ 
    max = sqrt(i); 

    if(max < 2) // This must be done beacuse sqrt(2) and sqrt(3) 
    {   // is 1 which will make it become nonprime. 
     answer += i; 
     answer += ' '; 
     continue; 
    } 

    for(int j = 2 ; j <= max ; j++) // Trial division ,divide each by integer 
    {        // more than 1 and less than sqrt(oftheinteger) 
     if(i % j == 0) 
      break; 

     else if(j == max) 
     { 
      answer += i + " "; 
      answer += ' '; 
     } 
    } 

    } 

     cout <<"The answer is " << answer ; 


    return 0; 
} 

問題

1)本程序w生病提示輸入用戶號碼並返回所有素數(例如,如果用戶輸入9:則答案爲2,3,5,7)。

2.)我認爲錯誤的部分是字符串和整數連接,直到現在我仍然拼圖如何在C++中連接字符串和整數(以前的Javascript程序員,所以我習慣於使用+作爲string-int concat操作符)

3.)除了上面提到的問題之外,到目前爲止我已經通過代碼並發現沒有其他問題存在。如果任何專家設法找到任何東西,請介意指出它以啓發我?

4.)如果在編碼或算法方面有任何錯誤,或者我做了什麼,請不要猶豫,指出它,我願意學習。

謝謝你花時間閱讀我的問題

+0

究竟是什麼錯誤?它打印出什麼? – talnicolas

+0

它給你什麼,而不是你期望的答案? – rcollyer

+0

它需要把所有東西放在一個字符串中嗎?發現每個素數時打印會更容易。 – madth3

回答

3

執行用C++格式的常用方法是使用streams

在這種情況下,您可以使用std::stringstream累積結果,然後在進行最終打印時將其轉換爲字符串。

包括sstream獲得所需要的類型和函數聲明:

#include <sstream> 

聲明answer是的std::stringstream代替std::string

stringstream answer; 

,然後只要您有:

answer += bla; 

,重播符合CE它:

answer << bla; 

要獲得std::stringanswer,使用answer.str()

cout << "The answer is " << answer.str(); 
0

你可以去周圍的字符串連接問題,如果你只打印你有什麼至今:

int main() 
{ 
int num; 
int max; 
string answer = ""; 

cin >> num; 

cout << "The answer is "; 

for(int i = 2 ; i < num ; i++) 
{ 
    max = sqrt((double)i); 

    if(max < 2) // This must be done beacuse sqrt(2) and sqrt(3) 
    {   // is 1 which will make it become nonprime. 
     cout << i << ' '; 
     continue; 
    } 

    for(int j = 2 ; j <= max ; j++) // Trial division ,divide each by integer 
    {        // more than 1 and less than sqrt(oftheinteger) 
     if(i % j == 0) 
      break; 

     else if(j == max) 
     { 
      cout << i << ' '; 
     } 
    } 

    } 


    return 0; 
} 

正如其他提到的一種串聯方式是std :: stringstream。

1

如果您在打印出來之前必須存儲完整的輸出(我可能會隨時打印它,但取決於您),一種簡單的方法是使用stringstream s。

在這種情況下,而不是answer作爲一個std::string,我們可以把它更改爲std::stringstream(和包括<sstream>頭)。

現在,而不是:

answer += i; 

我們只是做一個簡單的變化,並具有:

answer << i; 

,就像你,如果你被打印到cout(這是一個ostream)。

所以基本上,你的代碼中的+=會變成<<

類似於印刷cout,你也可以在一起,如:

answer << a << b 


我們打印stringstreamcout,所有你需要做的是:

cout << my_stringstream.str() 


看你怎麼走。我不想爲你提供完整的作業,因爲它是作業。

0

它不是很漂亮,但它的工作原理。我使用一個通用庫「genlib.h」,我不確定你使用了什麼,所以你可能需要替換它,或者我可以發送給你。

#include "genlib.h" 
#include <iostream> 
#include <string> 
#include <cmath> 
using namespace std; 

bool IsPrime(int num); 

int main() 
{ 
    int num; 
    int i = 2; 

    cout << "Enter an integer to print previous primes up to: "; 
    cin >> num; 

    cout << endl << "The primes numbers are: " << endl; 
    while(i < num){ 
     if (IsPrime(i) == true){ 
      cout << i << ", "; 
     } 
     i++; 
    } 
    return 0; 
} 

bool IsPrime(int num){ 

    if((num == 2) || (num == 3)) { 
     return true; 
    }else if ((num % 2) == 0){ 
     return false; 
    }else{ 
     for (int i = 3; i < sqrt(double(num))+1; i++){ 
      if ((num % i) == 0){ 
       return false; 
      } 
      return true; 
     } 
    } 
} 
0

您使用需要TN整數轉換爲字符串(字符*,準確):

answer += itoa(i); 

或使用標準功能:

char str[10]; 
sprintf(str,"%d",i); 
answer += str; 

,如果你想避免使用開方功能,您可以取代:

for(int i = 2 ; i < num ; i++) 
{ 
    max = sqrt(i); 

用:

for(int i = 2 ; i*i < num ; i++) 
{ 
+0

我會避免itoa和C++ sprintf,除了itoa是一個非標準的功能,並使用sprintf你應該使用它的一些安全版本,如果你的stdlib支持它 –

+0

你是什麼意思的安全版本的sprintf? –

+0

sprintf具有這種煩人的能力來溢出你餵它的緩衝區。安全版本需要一個額外的參數來指定最大長度,包括將'\ 0'放入緩衝區。我相信微軟稱他們的sprintf_s和C99似乎宣稱它是snprintf –

0

的問題是,的std :: string的+操作員接受字符串作爲參數,指向字符或單字符數組。

在+運算符中使用單個字符時,會在字符串的末尾添加一個字符。

您的C++編譯器在將整數傳遞給運算符+(char和int都是有符號整數值,不同位數)之前將整數轉換爲char,因此您的字符串應該包含奇怪的char而不是數字。

你應該明確地轉換成整數的字符串將它添加到字符串之前,在其他的答案,或者只是輸出的一切建議到std ::法院(其操作< <也接受詮釋爲參數,並將其正確地轉換爲字符串)。

作爲一個附註,你應該從C++編譯器收到一條警告,告訴你你的整數i在你將它添加到字符串(整數已經轉換爲較低分辨率或類似的東西)時已經轉換爲char。這就是爲什麼將警告級別設置爲高並嘗試生成在編譯期間不會生成任何警告的應用程序總是很好的做法。

0

通過將已知的素數存儲在set中,可以執行更快的查找。這兩個樣本函數應該做的伎倆:

#include <iostream> 
#include <set> 
#include <sstream> 
#include <string> 

typedef std::set< unsigned int > PrimeNumbers; 

bool isComposite(unsigned int n, const PrimeNumbers& knownPrimeNumbers) 
{ 
    PrimeNumbers::const_iterator itEnd = knownPrimeNumbers.end(); 

    for (PrimeNumbers::const_iterator it = knownPrimeNumbers.begin(); 
     it != itEnd; ++it) 
    { 
     if (n % *it == 0) 
      return true; 
    } 
    return false; 
} 


void findPrimeNumbers(unsigned int n, PrimeNumbers& primeNumbers) 
{ 
    for (unsigned int i = 2; i <= n; ++i) 
    { 
     if (!isComposite(i, primeNumbers)) 
      primeNumbers.insert(i); 
    } 
} 

然後,您可以調用findPrimeNumbers像這樣:

unsigned int n; 

std::cout << "n? "; 
std::cin >> n; 

PrimeNumbers primeNumbers; 
findPrimeNumbers(n, primeNumbers); 

如果你真的需要轉儲結果在一個字符串:

std::stringstream stringStream; 
int i = 0; 
PrimeNumbers::const_iterator itEnd = primeNumbers.end(); 
for (PrimeNumbers::const_iterator it = primeNumbers.begin(); 
    it != itEnd; ++it, ++i) 
{ 
    stringStream << *it; 
    if (i < primeNumbers.size() - 1) 
     stringStream << ", "; 
} 
std::cout << stringStream.str() << std::endl; 

由於您願意學習,您可以使用Boost String Algorithms Library對字符串/序列執行連接和分割算法。

這個解決方案並不完美,但它是基本的C++使用(簡單的容器,沒有結構,只有一個typedef,...)。 隨時將您的結果與The First 1000 Primes進行比較。

祝你好運