I wrote a simple algorithm to display the nth prime. Simply put, it uses a vector of found primes to check if the next number is prime as well; if it is, it pushes it into the vector and repeats until the nth prime is found.
Unfortunately, I am getting a segmentation fault in the for loop nested in the while loop and I have no idea why. More specifically, the error occurs in the header of the for loop; I added a cerr << "Check " << z++ << endl; to the body of the for loop (and one before it altogether) to see where it occurred so I believe the error is related to the iterators.
The program is very small and I don't mind sharing it (if you have a use for it have at it) so here's the whole thing:
#include <iostream>
#include <iomanip>
#include <cstring>
#include <cmath>
#include <vector>
using std::cout;
using std::cerr;
using std::endl;
using std::vector;
int main( int argc, char* argv[] )
{
if( argc != 2 )
{
cerr << "USAGE: nthPrime n" << endl;
return 1;
}
vector< unsigned > primes;
vector< unsigned >::iterator it;
bool isPrime;
char *sffx = ( char ) 0;
unsigned n = atoi( argv[ 1 ] ),
x = 3,
max;
primes.push_back( 2 );
while( primes.size() != n )
{
isPrime = true;
max = ( unsigned )sqrt( x );
for( it = primes.begin(); *it <= max; ++it )
if( !( x % *it ) ) isPrime = false;
if( isPrime ) primes.push_back( x );
x += 2;
}
if( n == 1 ) strcpy( sffx, "st" );
else if( n == 2 ) strcpy( sffx, "nd" );
else if( n == 3 ) strcpy( sffx, "rd" );
else strcpy( sffx, "th" );
cout << "The " << n << sffx << " prime is " << primes.back() << endl;
return 0;
}
Here's the makefile too for convienience:
CCFLAGS = -Wall -std=c++11
nthPrime: nthPrime.o
g++ $(CCFLAGS) -o nthPrime nthPrime.o
nthPrime.o: nthPrime.cpp
g++ $(CCFLAGS) -c nthPrime.cpp
clean:
-rm *.o nthPrime
I have neglected to add any comments as I just wrote it an hour ago so please let me know if you would like me to.
Thanks in advance.
P.S. I have tried adding && it != primes.end() to the for loop but it shouldn't be required due to the properties of the algorithm and it didn't help anyway.
Some issues I can see:
1) using argv without checking
unsigned n = atoi( argv[ 1 ] ),
x = 3,
max;
2) This:
char *sffx = ( char ) 0;
Does not allocate space for this:
if( n == 1 ) strcpy( sffx, "st" );
else if( n == 2 ) strcpy( sffx, "nd" );
else if( n == 3 ) strcpy( sffx, "rd" );
else strcpy( sffx, "th" );
Ok thank you everyone for getting back to me so quickly! I thought I'd be waiting all day! The issue turned out to be the line char *sffx = ( char ) 0;. Changing it to char *sffx = new char[ 3 ]; fixed everything.
For anyone who may end up having a similar issue or just wants the program for whatever reason, here it is:
#include <iostream>
#include <iomanip>
#include <cstring>
#include <cmath>
#include <vector>
using std::cout;
using std::cerr;
using std::endl;
using std::vector;
int main( int argc, char* argv[] )
{
vector< unsigned > primes;
vector< unsigned >::iterator it;
bool isPrime;
char *sffx = new char[ 3 ];
unsigned n = atoi( argv[ 1 ] ),
x = 3,
max;
if( argc != 2 || n < 1)
{
cerr << "USAGE: nthPrime n>0" << endl;
return 1;
}
primes.push_back( 2 );
while( primes.size() < n )
{
isPrime = true;
max = ( unsigned )sqrt( x );
for( it = primes.begin(); *it <= max; ++it )
if( !( x % *it ) ) isPrime = false;
if( isPrime ) primes.push_back( x );
x += 2;
}
if( n % 10 == 1 && n % 100 != 11 ) strcpy( sffx, "st" );
else if( n % 10 == 2 && n % 100 != 12 ) strcpy( sffx, "nd" );
else if( n % 10 == 3 && n % 100 != 13 ) strcpy( sffx, "rd" );
else strcpy( sffx, "th" );
cout << "The " << n << sffx << " prime is " << primes.back() << endl;
return 0;
}
Enjoy and thank you all again!
P.S. the 86626th prime is a cool one I just ran into randomly to test the program at a high value; check it out!
Related
I am trying to convert a small code of Matlab in c++.
In matlab normalization of random number can be done easily as below:
val = x / norm(x)
where x contains random generated real and img part between 0 and 255 as below:
70.0000000000000 + 112.000000000000i
11.0000000000000 + 97.0000000000000i
24.0000000000000 + 195.000000000000i
210.000000000000 + 203.000000000000i
177.000000000000 + 47.0000000000000i
81.0000000000000 + 125.000000000000i
243.000000000000 + 114.000000000000i
8.00000000000000 + 165.000000000000i
After the normalization, the values in val are as below:
0.126554761381164 + 0.202487618209862i
0.0198871767884686 + 0.175368740771041i
0.0433902039021132 + 0.352545406704670i
0.379664284143491 + 0.367008808005375i
0.320002753778085 + 0.0849724826416384i
0.146441938169632 + 0.225990645323507i
0.439325814508897 + 0.206103468535038i
0.0144634013007044 + 0.298307651827029i
I really donot know how to do the similar work in c++.
I thought of doing something like below but soon got stuck.
int random_real_number;
int random_img_number;
vector<int > real_number;
vector<int> img_number;
int data_size_val= 8;
srand (time(NULL)); // Initialize random seed
for(int i=0;i< data_size_val;i++){
random_real_number = rand() % 255 + 0;
std::cout << random_real_number << std::endl;
random_img_number= rand() % 255 + 0;
std::cout << random_img_number << std::endl;
real_number.push_back(random_real_number);
img_number.push_back(random_img_number);
}
It would be great help if someone can help me in it.
Thanks in advance.
The function std::norm() computes something called the field norm, which is the sum of the squares of real and imag. You get the square root of that with std::abs(). So in the same vein as the example on the C++ website, you can do:
#include <vector>
#include <cassert>
#include <complex>
#include <iostream>
#include <iomanip>
int main() {
std::vector < std::complex < double > >
zarray { { 70, 112 }, { 11, 97 }, { 24, 195 }, { 210, 203 },
{ 177, 47 }, { 81, 125 }, { 243, 114 }, { 8, 165 } };
for ( auto z: zarray ) {
assert ( std::norm ( z ) == ( z.real() * z.real() + z.imag() * z.imag() ) );
assert ( std::norm ( z ) == ( z * std::conj ( z ) ) );
// assert ( std::norm ( z ) == ( std::abs ( z ) * std::abs ( z ) ) );
std::cout << "std::abs ( " << std::setw(9) << z << " ) = "
<< std::setw(7) << std::abs ( z )
<< ", z/abs = " << std::setw(19) << z / std::abs ( z ) << '\n';
}
}
which should return
std::abs ( (70,112) ) = 132.076, z/abs = (0.529999,0.847998)
std::abs ( (11,97) ) = 97.6217, z/abs = (0.11268,0.993631)
std::abs ( (24,195) ) = 196.471, z/abs = (0.122155,0.992511)
std::abs ( (210,203) ) = 292.077, z/abs = (0.718988,0.695022)
std::abs ( (177,47) ) = 183.134, z/abs = (0.966506,0.256643)
std::abs ( (81,125) ) = 148.95, z/abs = (0.543808,0.83921)
std::abs ( (243,114) ) = 268.412, z/abs = (0.905325,0.42472)
std::abs ( (8,165) ) = 165.194, z/abs = (0.048428,0.998827)
The first complex number in your example is divided by 553.12, but I don't really see how that would be the L2-norm of 70+112i.
For the C++ experts: compared to the example I had to comment out the last assert because it fails on some of the inputs, I'm not sure why that is.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
Could someone answer the below C++ interview question:
Given string: "song singing in hindi"
find repeated strings like as below :
single characters repetition:
Count of "s" = 2 Count of "o" = 0 Count of "n" = 5 Count of "g" = 3
..... etc
two character repetition
Count of "so" = 0 Count of "on" = 0 Count of "ng" = 3 Count of "in" = 4..... etc
Three character repetition
Count of "son" = 0 ....Count of "ing" = 1.... etc
Four character repetition
Count of "song" = 0 .....etc
Rs
Or even a recursive function would do. To remove the 'patterns' with a white space you can follow Vlad's approach with the string::find function.
#include <iostream>
#include <string>
#include <map>
class FRQ {
void Func(std::map<std::string, size_t> &frequencyTable, const std::string &m_str, const int stepping = 1) {
if (stepping == m_str.size()) {
frequencyTable[m_str]++;
return;
}
for (std::string::size_type i = 0, iMAX = m_str.size(); i < iMAX; ++i) {
frequencyTable[m_str.substr(i, stepping)]++;
}
Func(frequencyTable, m_str, stepping + 1);
}
public:
std::map<std::string, size_t> *operator()(const std::string &str) {
std::map<std::string, size_t> *fTable = new std::map<std::string, size_t>();
Func(*fTable, str);
return fTable;
}
};
int main(void) {
using namespace std;
string s = "HiYo HiYo";
FRQ frq;
map<string, size_t> *frequenceTable = frq(s);
cout << "Patterns: " << frequenceTable->size() << endl;
for (const auto& ptr : *frequenceTable)
cout << "[ '" << ptr.first << "'::" << ptr.second << " ]" << endl;
delete frequenceTable;
return 0;
}
Here is a straightforward approach
#include <iostream>
#include <string>
#include <map>
int main()
{
std::string s = "song singing in hindi";
for ( std::string::size_type i = 1; i <= s.size(); i++ )
{
std::map<std::string, size_t> m;
for ( std::string::size_type j = 0; j < s.size() - i + 1; j++ )
{
m[std::string( s, j, i )]++;
}
for ( const auto &p : m )
{
std::cout << "( \"" << p.first << "\", " << p.second << " ) ";
}
std::cout << std::endl;
}
return 0;
}
If you want to exclude patters with an embedded blank you can rewrite the program the following way
#include <iostream>
#include <string>
#include <map>
int main()
{
std::string s = "song singing in hindi";
for ( std::string::size_type i = 1; i <= s.size(); i++ )
{
std::map<std::string, size_t> m;
for ( std::string::size_type j = 0; j < s.size() - i + 1; j++ )
{
std::string t( s, j, i );
if ( t.find( ' ' ) == std::string::npos )
{
m[t]++;
}
}
if ( !m.empty() )
{
for ( const auto &p : m )
{
std::cout << "( \"" << p.first << "\", " << p.second << " ) ";
}
std::cout << std::endl;
}
}
return 0;
}
The output is
( "d", 1 ) ( "g", 3 ) ( "h", 1 ) ( "i", 5 ) ( "n", 5 ) ( "o", 1 ) ( "s", 2 )
( "di", 1 ) ( "gi", 1 ) ( "hi", 1 ) ( "in", 4 ) ( "nd", 1 ) ( "ng", 3 ) ( "on", 1 ) ( "si", 1 ) ( "so", 1 )
( "gin", 1 ) ( "hin", 1 ) ( "ind", 1 ) ( "ing", 2 ) ( "ndi", 1 ) ( "ngi", 1 ) ( "ong", 1 ) ( "sin", 1 ) ( "son", 1 )
( "ging", 1 ) ( "hind", 1 ) ( "indi", 1 ) ( "ingi", 1 ) ( "ngin", 1 ) ( "sing", 1 ) ( "song", 1 )
( "hindi", 1 ) ( "ingin", 1 ) ( "nging", 1 ) ( "singi", 1 )
( "inging", 1 ) ( "singin", 1 )
( "singing", 1 )
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector< int > number;
bool numbersAreCorrect = false;
int input;
while( cin >> input )
number.push_back( input );
vector< int > unique_number( number.size(), 0 );
vector< int > repeated( number.size(), 1 );
for( int i = 0; i < number.size(); i++ )
{
for( int j = i + 1; j < number.size() + 1; j++ )
{
if( number[ i ] != 0 && number[ i ] == number[ j ] )
{
repeated[ i ]++;
unique_number[ i ] = number[ i ];
}
else
unique_number[ i ] = number[ i ];
if( j == number.size() )
{
for( int z = 0; z < number.size(); z++ )
{
if( number[ z ] == unique_number[ i ] )
number[ z ] = 0;
}
}
}
}
for( int i = 0; i < number.size(); i++ )
{
if( ( unique_number[ i ] != 0 && repeated[ i ] == 1 ) || ( unique_number[ i ] != 0 && repeated[ i ] % 2 != 0 ) )
{
numbersAreCorrect = false;
cout << unique_number[ i ] << endl;
break;
}
else if( repeated[ i ] == 1 )
numbersAreCorrect = true;
else if( repeated[ i ] % 2 != 0 )
{
numbersAreCorrect = false;
cout << repeated[ i ] << endl;
break;
}
else if( repeated[ i ] % 2 == 0 )
numbersAreCorrect = true;
}
if( numbersAreCorrect == true )
cout << "0" << endl;
return 0;
}
This program gets positive integers from user, checks if an integer is repeated 2k( even) times or 2k+1(odd) times. if latter is true, it prints the integer , else it prints 0; I used 20000 inputs and it takes more than 10 seconds to evaluate.. I need to know how to make it process faster.
for example this input results in "0" : 1 2 2 1
and this results in "3" : 1 2 2 1 3
How about you first sort the thing.
Then you only need to do a single for loop instead of two because to find all the repetitions you just count consecutive occurrences.
Failing that use a set or map. Again you'll drop to O(NlogN) instead of O(N^2).
I had a problem from a website. Given a string s and st, I have to found all possible combination of st in s. For example,
s = "doomdogged"
st = "dg"
answer = 4
I can choose the d from 0 or 4, and g from 6 or 7. Which gives me 4 possible combinations.
Here's my code:
#include <iostream>
#include <vector>
using namespace std;
string s, st;
bool target[26];
vector<int> positions[26];
vector<vector<int>> possibleCombinations;
void DFS_Enumeration(int, vector<int>*);
int DFS_index_max = 0;
int main(int argc, char *argv[])
{
int answer = 0;
cin >> s; //Given a string s
cin >> st; //Given a string st
//Find all possible combination of st in s
for ( int i = 0 ; i < 26 ; ++ i )
target[i] = 0;
for ( int i = 0 ; i < st.length() ; ++ i )
target[st[i] - 97] = 1;
for ( int i = 0 ; i < 26 ; ++ i )
{
if ( target[i] == 0 ) continue;
for ( int j = 0 ; j < s.length() ; ++ j )
{
if ( s[j] == i + 97 ) positions[i].push_back(j);
}
}
DFS_index_max = st.length();
vector<int> trail(0);
DFS_Enumeration(0, &trail); //Here I got an runtime error
for ( vector<int> vi : possibleCombinations )
{
int currentMax = 0;
for ( int i = 0 ; i < vi.size() ; ++ i )
{
if ( vi[i] > currentMax )
{
if ( i == vi.size() - 1 ) ++ answer;
currentMax = vi[i];
continue;
}
else
break;
}
}
cout << answer;
}
void DFS_Enumeration(int index, vector<int>* trail)
{
if ( index == DFS_index_max )
{
possibleCombinations.push_back(*trail);
return;
}
for ( int i = 0 ; i < positions[st[index] - 97].size() ; ++ i )
{
trail -> push_back(positions[st[index] - 97][i]);
DFS_Enumeration(++index, trail);
trail -> pop_back();
}
return;
}
First I look for characters in st, and mark them as needed to found in my boolean array target.
Then, I use DFS to enumerate all possible combinations. For the above example of "doomdogged" and "dg", d exists in 0, 4, 9. And g exist in 6, 7. I will get 06, 07, 46, 47, 96, 97.
Lastly, I count those which make sense, and output the answer. For some reason, my code doesn't work and generate an runtime error concerning memory at the line I've marked.
DFS_Enumeration might increment index any number of times, so st[index] could likely be past the end of the string st.
I wrote a program to calculate (adding) 2 positive big integer using vector to store the numbers.
#include <cstdlib>
#include <cstdio> // sd sprintf()
#include <iostream>
#include <vector>// sd vector
typedef short TYPE;// alias
void input();
void makeArray();
void display(const std::vector<TYPE> Ar);
TYPE convertChar2T( char * ch);
void add();
static std::string num1;//store big integer as string
static std::string num2;
static std::vector<TYPE> Arr1;//store as vector
static std::vector<TYPE> Arr2;
static std::vector<TYPE> result;
int main(int argc, char** argv) {
input();
makeArray();
display(Arr1);
display(Arr2);
add();
display(result);
return 0;
}
//input 2 big integer number
void input(){
std::cout << "Enter 1st number : " ;
if (! std::getline(std::cin , num1) )
std::cerr << "Not OK\n";
std::cout << "Enter 2nd number : ";
if (! std::getline(std::cin , num2) )
std::cerr << "Not OK\n";
}
//grab into 2 arrays
void makeArray(){
for (std::size_t i = 0; i < num1.size(); i++){
char temp1[2] = { num1[i], '\0'}; //use array-of-char as it need '\0'
Arr1.push_back( convertChar2T(temp1) ); //push what is converted
}
for (std::size_t i = 0; i < num2.size(); i++){
char temp2[2] = { num2[i], '\0'};
Arr2.push_back( convertChar2T(temp2) );
}
}
//convert char -> TYPE by using sscanf()
TYPE convertChar2T( char * ch){
TYPE numb ;
sscanf( ch, "%d", &numb );//NGUOC LAI SPRINTF
return numb;
}
//display array
void display(const std::vector<TYPE> Ar){
for (std::size_t i = 0; i < Ar.size(); i++)
std::cout << Ar.at(i) << '\t';
std::cout << '\n';
}
void add(){
std::size_t i = Arr1.size(); // NEVER COMES TO ZERO ( 1 AT LEAST )
std::size_t j = Arr2.size();
//check original one and later one
//3 cases : 1 - original one , not yet processed
// 2 - original # one, not yet processed
// -1 - original # one or one, processed
//NOTE: at first only value 1 or 2 ( not process )
short check_one[2] = {
( i == 1 ) ? 1 : 2,
( j == 1 ) ? 1 : 2,
};
bool boost = 0;
bool Arr1_isgood = true;// whether count to 1 or not
bool Arr2_isgood = true;// good -> not yet 1
short temp_result = 0;//temporary result to push into vector
while ( Arr1_isgood || Arr2_isgood ){// while not all comes to 1
// i == j : 2 cases
// 1st: both 1 now - 3 cases
// 1.1 #1+not process original and processed
// 1.2 processed and #1+not processed
// 1.3 both 1 original + not processed
// 2nd: both # 1
if ( i == j ) {
if ( check_one[0] == 2 && check_one[1] == -1 ){//#1+not process original and processed
temp_result = Arr1[i-1] + boost;
check_one[0] == -1;
}
else if ( check_one[0] == -1 && check_one[1] == 2 ){//processed and #1+not processed
temp_result = Arr2[j-1] + boost;
check_one[1] = -1;
}
else//both 1 original + not processed OR both # 1
temp_result = Arr1[i-1] + Arr2[j-1] + boost;
//check result >= 10 or < 10
if ( temp_result >= 10 ){
temp_result = temp_result - 10 ;
boost = 1;
}
else
boost = 0;
//result.begin() return iterator at beginning
result.insert( result.begin() ,temp_result );
//update info
if ( i == j && i == 1){ // NOTE : NEU SD i==j==1 -> sai (vi luon true)
Arr1_isgood = Arr2_isgood = false;
continue;
}
else if ( i == j && i != 1){ // i == j # 1
i--;
j--;
}
}
if (i != j){
//check to set flag ( if one of two die )
if ( i == 1 && j > 1 )
Arr1_isgood = false;
else if ( i > 1 && j == 1 )
Arr2_isgood = false;
// i die && j live OR vice versa
if ( (!Arr1_isgood && Arr2_isgood) ||
(Arr1_isgood && !Arr2_isgood ) ){
if (!Arr1_isgood && Arr2_isgood ){ //1st case
if ( check_one[0] == 1 || check_one[0] == 2){//not yet processed as SET FLAG ABOVE first
temp_result = Arr1[i-1] + Arr2[j-1] + boost;
check_one[0] = -1 ;
}
else
temp_result = Arr2[j-1] + boost;
j--;
}
else if ( Arr1_isgood && !Arr2_isgood ){ //2nd case
if ( check_one[1] == 1 || check_one[1] == 2 ){//not yet processed as SET FLAG ABOVE first
temp_result = Arr1[i-1] + Arr2[j-1] + boost;
check_one[1] = -1 ;
}
else
temp_result = Arr1[i-1] + boost;
i--;
}
}
else {// both is good
temp_result = Arr1[i-1] + Arr2[j-1] + boost;
i--;
j--;
}
//check result >= 10 or < 10
if (temp_result >= 10) {
temp_result -= 10;
boost = 1;
} else
boost = 0;
result.insert( result.begin() ,temp_result );
}
}
//insert boost (if any exists)
if (boost == 1)
result.insert( result.begin(), boost);
}
I'm torn between the use of "Arr1_isgood" bool variable and the check_one variable, it seems that they can be combined into one variable ? I tried to do it and it takes a lot of time without correct result.
Can the digit be store in some kind of smaller data structure rather than "short" type ? as "short" takes more than needed bits.
Another thing is : it seems that std::size_t only reach up to 4 billion in size, as when size_t reach 1, I decreased it several times and it comes to 4 billion ? Isn't it?
I wonder if these codes somehow can be optimized more?
If you want to manipulate big integers, you should use a big-integer library, e.g. GMP.
In your machine has 32-bit ints, suppose you represent each number (unsigned) as an array of 31-bit signed ints, starting from the least significant.
Then maybe you could do something like this:
// do c = a + b
int a[n], b[n], c[n];
int carry = 0;
for (i = 0; i < n; i++){
// do the addition with carry
c[i] = a[i] + b[i] + carry;
// if the addition carried into the sign bit
carry = (c[i] < 0);
// detect it and remove it from the sum
if (carry){
c[i] &= 0x7fffffff;
}
}
Then you could figure out how to handle negatives.