Вернуть все простые числа перед заданным числом (домашнее задание C ++) - PullRequest
1 голос
/ 09 ноября 2011

Я не пытаюсь попросить вас, ребята, помочь мне сделать домашнее задание, потому что я провел много исследований, а также сам пытаюсь его запрограммировать, но все же я сталкиваюсь с проблемой, и я думаю, что пока знаю, где проблема но я до сих пор не могу найти решение:

Код

#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.) Эта программа запросит у пользователя номер и вернет все простые числа перед ним (например, если пользователь введет 9: тогда ответ - 2, 3, 5, 7).

2.) Я думаю, что неправильная часть - это конкатенация строк и целых чисел, до сих пор я ломаю голову над тем, как объединить строку и целое число в C ++ (предыдущий программист Javascript, поэтому я привык использовать + как concat string-int оператор)

3.) Помимо проблемы, о которой я упоминал выше, пока я прошёл код и не обнаружил никакой другой проблемы. Если кому-то из экспертов удастся найти такую ​​проблему, не забудьте указать ей, чтобы просветить меня ??

4.) Если есть какая-либо ошибка с точки зрения кодирования или алгоритма или чего-либо сделанного мной, пожалуйста, не стесняйтесь указывать на это, я готов учиться.

Спасибо, что потратили время на чтение моего вопроса

Ответы [ 7 ]

3 голосов
/ 09 ноября 2011

Обычный способ выполнить форматирование в C ++ - использовать streams.

В этой ситуации вы можете использовать std::stringstream для накопления результатов, а затем преобразовать его в строку при окончательной печати. ​​

Включите sstream, чтобы получить требуемые объявления типов и функций:

#include <sstream>

Объявите answer как std::stringstream вместо std::string:

stringstream answer;

и тогда, где у вас есть:

answer += bla;

, замените его на:

answer << bla;

Чтобы получить std::string из answer, используйте answer.str():

cout << "The answer is " << answer.str();
1 голос
/ 09 ноября 2011

Если вам необходимо сохранить весь вывод перед печатью (я бы, вероятно, распечатал его по ходу дела, но на ваше усмотрение), простой способ - использовать stringstream с.

В этом случае вместо answer, являющегося std::string, мы можем изменить его на std::stringstream (и включить заголовок <sstream>).

Теперь вместо того, чтобы:

answer += i;

Мы можем просто сделать простое изменение и иметь:

answer << i;

Точно так же, как если бы вы печатали на cout (то есть ostream).

Так что, в принципе, += в вашем коде станет <<.

Как и в случае печати с cout, вы также можете цепь вместе, например:

answer << a << b


Теперь, чтобы напечатать ваш stringstream в cout, все, что вам нужно сделать, это:

cout << my_stringstream.str()


Посмотрите, как вы идете. Я не хочу давать вам полное, потому что это домашнее задание.

0 голосов
/ 09 ноября 2011

Вы можете выполнить более быстрый поиск, сохранив свои известные простые числа в 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, ...). Не стесняйтесь сравнивать свои результаты с Первые 1000 простых чисел .

Удачи

0 голосов
/ 09 ноября 2011

Проблема в том, что оператор + std :: string принимает строки в качестве параметра, указатели на массив символов или отдельные символы.

Если в операторе + используется один символ, то в конец строки добавляется один символ.

Ваш компилятор C ++ преобразует целое число в char перед передачей его оператору + (и char, и int являются целочисленными значениями со знаком, с разным битовым номером), и поэтому ваша строка должна содержать странный символ вместо цифр.

Вы должны явно преобразовать целое число в строку перед добавлением его в строку, как это предлагается в других ответах, или просто вывести все в std :: cout (его оператор << принимает также int в качестве параметра и правильно преобразовывает их в строку) . </p>

В качестве примечания вы должны получить предупреждение от компилятора C ++ о том, что ваше целое число i было преобразовано в char при добавлении его в строку (целое число было преобразовано в более низкое разрешение или что-то в этом роде). Вот почему всегда хорошо устанавливать высокий уровень предупреждения и пытаться создавать приложения, которые не генерируют никаких предупреждений во время компиляции.

0 голосов
/ 09 ноября 2011

вам нужно преобразовать целое число в строку (в точности *), используя:

answer += itoa(i);

или с использованием стандартной функции:

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

и если вы хотите избежать использования функции sqrt, вы можете заменить:

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

с:

for(int i = 2 ; i*i < num ; i++)
{
0 голосов
/ 09 ноября 2011

это не очень красиво, но работает. Я использую общую библиотеку "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 голосов
/ 09 ноября 2011

Вы можете обойти проблему конкатенации строк, если просто распечатаете то, что у вас есть:

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.

...