I keep getting the segmentation fault (core dumped) on the code below. Any ideas on why this is happening. The code is designed to read numbers from a text document, convert them to integers, perform radix sort, and print out the array.
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <time.h>
#include <sstream>
using namespace std;
int getMax(int arr[], int n)
{
int max = arr[0];
for (int i = 1; i < n; i++)
if (arr[i] > max)
max = arr[i];
return max;
}
void countSort(int arr[], int n, int exp)
{
int output[n];
int i, count[10] = {0};
for (i = 0; i < n; i++)
count[(arr[i] / exp) % 10]++;
for (i = 1; i < 10; i++)
count[i] += count[i - 1];
for (i = n - 1; i >= 0; i--)
{
output[count[(arr[i] / exp) % 10] - 1] = arr[i];
count[(arr[i] / exp) % 10]--;
}
for (i = 0; i < n; i++)
arr[i] = output[i];
}
void radixsort(int arr[], int n)
{
clock_t clockStart;
clockStart = clock();
int m = getMax(arr, n);
for (int exp = 1; m / exp > 0; exp *= 10)
countSort(arr, n, exp);
cout << "\nTime taken by radix sort: " << (double)(clock() - clockStart) / CLOCKS_PER_SEC << endl;
}
int StrToInt(string sti)
{
int f;
stringstream ss(sti); //turn the string into a stream
ss >> f;
return f;
}
int main()
{
int arr[10000];
int i = 0;
int result;
string line = "";
ifstream myfile;
myfile.open("integers2.txt");
if(myfile.is_open())
{
while(!myfile.eof())
{
getline(myfile, line);
result = StrToInt(line);
arr[i] = result;
//cout<< arr[i] <<"\n";
i++;
}
}
int n = sizeof(arr)/sizeof(arr[0]);
radixsort(arr, n);
for (int i = 0; i < n; i++)
{
cout << arr[i] << "\n";
}
return 0;
}
Contents of the text file I am using for input:
1244
3455
6565
55
765
8768
687
879
Your program has undefined behavior, because it uses more entries of the array than you initialized with data. You pass the length of the entire array for n even though only a small portion of it, from 0 to i, has been initialized.
Change the code to use n in place of i in the reading loop, and pass that n unmodified to the sort function. This is going to fix the problem (demo).
int n = 0;
myfile.open("integers2.txt");
if(myfile.is_open()) {
while (myfile >> arr[n]) {
n++;
}
}
radixsort(arr, n);
Here's your working code:
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <time.h>
#include <sstream>
using namespace std;
int getMax(int arr[], int n)
{
int max = arr[0];
for (int i = 1; i < n; i++)
if (arr[i] > max)
max = arr[i];
return max;
}
void countSort(int arr[], int n, int exp)
{
int output[n];
int i, count[10] = {0};
for (i = 0; i < n; i++)
count[(arr[i] / exp) % 10]++;
for (i = 1; i < 10; i++)
count[i] += count[i - 1];
for (i = n - 1; i >= 0; i--)
{
output[count[(arr[i] / exp) % 10] - 1] = arr[i];
count[(arr[i] / exp) % 10]--;
}
for (i = 0; i < n; i++)
arr[i] = output[i];
}
void radixsort(int arr[], int n)
{
clock_t clockStart;
clockStart = clock();
int m = getMax(arr, n);
for (int exp = 1; m / exp > 0; exp *= 10)
countSort(arr, n, exp);
cout << "\nTime taken by radix sort: " << (double)(clock() - clockStart) / CLOCKS_PER_SEC << endl;
}
int StrToInt(string sti)
{
int f;
stringstream ss(sti); //turn the string into a stream
ss >> f;
return f;
}
int main()
{
const int MAX_SIZE = 10;
int arr[ MAX_SIZE ] = { 0 };
//int i = 0;
//int result = 0;
string line = "";
ifstream myfile;
myfile.open("integers2.txt");
if(!myfile.is_open())
{
cerr << "Could not open file!\n";
return -1;
}
cout << "Reading integers...\n";
int index = 0;
//while ( index < SIZE && getline( myfile, line ) )
while ( index < MAX_SIZE && myfile >> arr[ index ] )
{
//getline( myfile, line );
//result = StrToInt( line );
//arr[index] = std::stoi( line );
cout << arr[index] <<"\n";
index++;
}
cout << "Sorting integers...\n";
//int n = sizeof(arr) / sizeof(arr[0]);
radixsort( arr, index );
for ( int i = 0; i < index; i++ )
{
cout << arr[i] << "\n";
}
return 0;
}
Some points:
Check std::stoi for string to integer conversion; BTW, you don't need to do that. Just read it directly like this: while ( file >> integer ).
Need to check if the file is open; return ERROR otherwise; in your case, the rest of the code was executing anyway even if the file was not open i.e. code after if ( myfile.open() ) { ... }
while( !myfile.eof() ) is bad practice. See: Why is iostream::eof inside a loop condition considered wrong?
You don't need to calculate the size like int n = sizeof(arr) / sizeof(arr[0]); because you already know the size. Just use a const for this.
While reading from file, you also need to validate the maximum size of your array. You should read what the size allows you. Take care of out-of-bounds read / write errors.
Use <ctime> instead of <time.h>.
Related
The formula is listed in the following article: https://en.wikipedia.org/wiki/Formula_for_primes. I am trying to implement it but to no success, for whatever reason the code is producing number which seem to be nth power of two + 1, which is obviously not what I want to achieve.
#include <iostream>
#include <cmath>
using namespace std;
int nth_prime(int n) {
double s = 1;
for (int i = 1; i <= pow(2, n); i++) {
double c = 0;
for (int j = 1; j <= i; j++) {
double f = (tgamma(j)+1)/j;
c+=floor(pow(cos(M_PI*f), 2));
}
s+=floor(pow(n/c, 1/n));
}
return s;
}
int main() {
int n;
while (cin >> n) {
cout << nth_prime(n) << endl;
}
return 0;
}
So i have 2 lines of arrays. First line is M, second line is N.
On the first line the user inputs 2 digits, first for the length of M, and second for the length of N.
On the second line user inputs M, on the third - N. All i want is to display what elements of N are not contained in m, but in ascending order.
Here's an example:
7 5
3.12 7.96 3.51 4.77 10.12 1.11 9.80
10.12 3.51 3.12 9.80 4.77
Output:
1.11 7.96
And here is my attempt at the program:
#include <stdio.h>
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <vector>
#include <algorithm>
using namespace std;
int ifexists(double z[], int u, int v)
{
int i;
if (u == 0)
return 0;
for (i = 0; i <= u; i++)
if (z[i] == v)
return (1);
return (0);
}
void main()
{
double bills[100], paid[100], result[100];
int m, n;
int i, j, k;
cin >> m >> n;
if (n > m) {
cout << "Wrong input.";
exit(3);
}
for (int i = 0; i < m; i++) {
cin >> bills[i];
}
for (int i = 0; i < n; i++) {
cin >> paid[i];
}
for (i = 0; i < n; i++)
k = 0;
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
if (bills[i] == paid[j]) {
break;
}
}
if (j == n) {
if (!ifexists(result, k, bills[i])) {
result[k] = bills[i];
k++;
}
}
}
for (i = 0; i < k; i++)
cout << result[i] << " ";
}
The output i'm getting is almost correct - 7.96 1.11. Basically in reverse order. How can i flip this around? Also, chances are my report is too slow. Is there a way to increase the speed?
You can use std::set_difference:
std::sort(bills, bills + m);
std::sort(paid, paid + n);
auto end = std::set_difference(bills, bills + m, paid, paid + n, result);
for (auto it = result; it != end; ++it) {
std::cout << *it << " ";
}
I am trying to solve the yodaness problem, but my code is not outputting anything when i run my program. I am not sure where my mistake is, because my code is compiling and running just with no output. I am trying to count the number of inversions in a string of characters, but I am not sure that I am going about it the correct way. Any help would be appreciated, thanks
#include <iostream>
#include <sstream>
#include <limits>
#include <map>
#include <string>
using namespace std;
const int MAX = 30000, LEN = 33;
int total = 0;
map<string, int> index_words(const string &line)
{
map<string, int> result;
istringstream in(line);
string word;
int index = 0;
while (in >> word)
{
if (result.find(word) == result.end())
result[word] = index++;
}
return result;
}
void merge(int *a, int p, int q, int r) {
int i, j, k, n1 = (q-p+1), n2 = (r-q);
int L[n1], R[n2];
for(i=0;i<n1;i++) L[i] = a[p+i];
for(j=0;j<n2;j++) R[j] = a[q+j+q];
for(k=p, i=j=0; k<=r; k++) {
if(j>=n2 || (i<n1 && L[i] <=R[j])) a[k] = L[i++];
else {
total += n1-i;
a[i] = R[j++];
}
}
}
void mergesort(int *a, int p, int r) {
if(p<r) {
int q = (p+r)/2;
mergesort(a,p,q);
mergesort(a,q+1,r);
merge(a,p,q,r);
total++;
}
}
char word[MAX][LEN];
int a[MAX];
int main()
{
cin >> instances;
char temp[LEN];
for (int i = 0; i < instances; ++i)
{
int numwords;
cin >> numwords;
cin.ignore(numeric_limits<streamsize>::max(), '\n';
string yoda_line, english_line;
getline(std::cin, yoda_line);
getline(std::cin, english_line);
auto yoda_idx = index_words(yoda_line);
auto english_idx = index_words(english_line);
for(int i = 0; i < instances; i++) a[i] = yoda_idx[word[i]];
mergesort(a,0, instances-1);
cout << total;
}
}
Trying to create a list of unique grades from a text file. Having issues with the output eliminating duplicates. Currently, I am trying to compare the value of each previous array entry to the next and if they are different, output the result to the outfile, but is just outputs an empty file.
I am also curious if there is an easy fix to change the sorting from 'low to high' into 'high to low'. Thank you in advance.
#include <iostream>
#include <string>
#include <limits>
#include <cmath>
#include <iomanip>
#include <fstream>
using namespace std;
int testScoreArray[100];
void selectSort(int testScoreArray[], int n);
void fileOutput(int testScoreArray[]);
int main()
{
int n = 100;
ifstream infile;
infile.open("testscoresarrayhomework.txt");
for (int i = 0; i < 100; i++) {
infile >> testScoreArray[i];
}
selectSort(testScoreArray, n);
fileOutput(testScoreArray);
infile.close();
return 0;
}
void selectSort(int testScoreArray[], int n)
{
//pos_min is short for position of min
int pos_min, temp;
for (int i = 0; i < n - 1; i++) {
pos_min = i; //set pos_min to the current index of array
for (int j = i + 1; j < n; j++) {
if (testScoreArray[j] < testScoreArray[pos_min])
pos_min = j;
//pos_min will keep track of the index that min is in, this is needed when a swap happens
}
//if pos_min no longer equals i than a smaller value must have been found, so a swap must occur
if (pos_min != i) {
temp = testScoreArray[i];
testScoreArray[i] = testScoreArray[pos_min];
testScoreArray[pos_min] = temp;
}
}
};
void fileOutput(int testScoreArray[])
{
ofstream outfile;
int gradeEvent = 0;
int previousGrade = 0;
outfile.open("testscoresoutput.txt");
outfile << "Test Score Breakdown: ";
outfile << endl
<< "Score / Occurance";
for (int i = 0; i < 100; i++) {
previousGrade = i;
if (previousGrade && previousGrade != i) {
outfile << '\n' << testScoreArray[i] << " / " << gradeEvent;
}
}
outfile.close();
};
You have declared a global variable testScoreArray and the function names use the same variable name for their parameters. It's best to avoid using global variables when possible. You can remove global declaration, then declare testScoreArray in main, and pass it to your functions. Example:
//int testScoreArray[100]; <=== comment out
void selectSort(int *testScoreArray, int n);
void fileOutput(int *testScoreArray, int n); //add array size
int main()
{
int testScoreArray[100]; //<== add testScoreArray in here
int n = sizeof(testScoreArray) / sizeof(testScoreArray[0]);
selectSort(testScoreArray, n);
fileOutput(testScoreArray, n);
...
}
In fileOutput you are basically checking to see if i != i, you need to examine the array, not indexing in the loop:
void fileOutput(int *testScoreArray, int n)
{
ofstream outfile("testscoresoutput.txt");
for(int i = 0; i < n; i++)
if(i && testScoreArray[i] != testScoreArray[i-1])
outfile << testScoreArray[i] << "\n";
};
To revers the sort, simply change the condition in this comparison
if (testScoreArray[j] < testScoreArray[pos_min])
pos_min = j;
To:
if(testScoreArray[j] > testScoreArray[pos_min])
pos_min = j;
Technically you would rename the variable to pos_max
d[i] = char(c[i]);
This is not working for me in the below example.
I need my output to be converted to its character values, but after using char(int), its still giving output using the int datatype only.
#include <bits/stdc++.h>
using namespace std;
int main()
{
string str;
cin>>str;
int size=str.size();
int len=0;
if (size % 2 == 0)
{
len=size/2;
}
else
{
len=(size/2)+1;
}
int a[len],b[len],c[len],d[len],x,y;
int i=0,j=size-1;
while(i<len)
{
x=(int)str[i];
y=(int)str[j];
if (i == j)
{
a[i]=x;
}
else
{
a[i]=x+y;
}
b[i]=a[i]%26;
c[i]=x + b[i];
d[i]=char(c[i]);
cout<<"l : "<<d[i]<<endl;
i++;
j--;
}
return 0;
}
Your code fails because you are storing the values in an int[] array. d[i]=char(c[i]); is useless because all you are doing is converting an int to a char back to an int again. You are then outputting the array values as-is as int values instead of converting them back to actual char values.
Try something more like this instead:
#include <vector>
#include <string>
using namespace std;
int main()
{
string str;
cin >> str;
int size = str.size();
int len = (size / 2) + (size % 2);
// VLAs are a non-standard compiler extension are are not portable!
// Use new[] or std::vector for portable dynamic arrays...
//
// int a[len], b[len], c[len];
// char d[len];
//
std::vector<int> a(len), b(len), c(len);
std::vector<char> d(len);
int x, y, i = 0, j = (size-1);
while (i < len)
{
x = (int) str[i];
y = (int) str[j];
if (i == j)
{
a[i] = x;
}
else
{
a[i] = x + y;
}
b[i] = a[i] % 26;
c[i] = x + b[i];
d[i] = (char) c[i];
cout << "l : " << d[i] << endl;
++i;
--j;
}
return 0;
}