For my lab in school I was asked to generate random numbers and characters and pass it into a function template and then sort them after showing my work as unsorted first. I'm using visual studios as a requirement for my school, but my main issue is that it's compiling with no errors but when I run my program it's not passing my array to be sorted. I've been spending a lot of time trying to understand why it's not working any help would be very appreciated.
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <algorithm>
using namespace std;
template <typename T>
void arrayIn(T arr[], int size, char word) {
if (word == 'd') {
sort(arr, arr + size, greater<>());
}
else {
sort(arr, arr + size);
}
return;
}
template <typename O>
void arr_out(O arr[], int size) {
int j;
for (j = 0; j < size; j++) {
cout << arr[j] << endl;
return;
}
delete[] arr;
}
int main(void) {
srand(time_t(NULL));
int size,i,j;
char word;
int *arr1;
char *arr2;
cout << "Enter in the size of the array: ";
cin >> size;
cout << "How would you like to sort in ascending or descending order?: ";
cin >> word;
arr1 = new int[size];
arr2 = new char[size];
if (arr1 == 0) {
cout << "memory allocation error";
system("pause");
exit(1);
}
cout << "The first array will sort intagers." << endl;
cout << "not sorted" << endl;
for (i = 0; i < size; i++) {
arr1[i] = rand() % 100 + 1;
cout << arr1[i] << endl;
}
arrayIn(arr1, size, word);
cout << "sorted" << endl;
arr_out(arr1,size);
if (arr2 == 0) {
cout << "memory allocation error";
system("pause`enter code here`");
exit(1);
}
cout << "the secound array will sort characters." << endl;
cout << "not sorted" << endl;
for (j = 0; j < size; j++) {
arr2[j] = rand() % (126 + 1 - 33) + 33;
cout << arr2[j] << endl;
}
arrayIn(arr2, size, word);
cout << "sorted" << endl;
arr_out(arr2, size);
system("pause");
return 0;
}
You have a very simple mistake in your arr_out function, which makes it only print the first element. Correct as follows (remove the line I commented out):
template <typename O>
void arr_out(O arr[], int size) {
int j;
for (j = 0; j < size; j++) {
cout << arr[j] << endl;
// return; // This will return after printing the first element!
}
delete[] arr;
}
Related
I have this code of a dynamic array that I turned in as a lab. My instructor responded saying "wouldn't even compile, no resize of the array". I am having trouble dealing with the comment of "no resize of the array", meaning I have to add the ability to resize the array. Please help quick! (It does compile). Appreciate it.
I am supposed to make a program that asks the user to initially size the array. Create an array based on that size asking for a number, and insert the number. Then repeat getting and inserting a number, resizing the array as needed or until they enter -1 for the number.
Print the list.
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
int count;
cout << "How many values do you want to store in your array?" << endl;
cin >> count;
int* DynamicArray;
DynamicArray = new int[count];
for (int i = 0; i < count; i++) {
cout << "Please input Values: " << endl;
cin >> DynamicArray[i];
{
if (DynamicArray[i] == -1) {
delete[] DynamicArray;
cout << "The program has ended" << endl;
exit(0);
}
else {
cout << endl;
}
}
}
for (int k = 0; k < count; k++) {
cout << DynamicArray[k] << endl;
}
delete[] DynamicArray;
return 0;
}
When the array is full, we need to resize it. Here is my solution
#include <iostream>
#include <cstring>
#include <cstdlib>
using namespace std;
int main()
{
int count;
cout << "How many values do you want to store in your array?" << endl;
cin >> count;
if (count <= 0) {
cout << "The value should be greater than zero" << endl;
exit(0);
}
int* DynamicArray;
DynamicArray = new int[count];
int i = 0, value = 0;
while (1) {
cout << "Please input Values: " << endl;
cin >> value;
if (value == -1) {
cout << "The program has ended" << endl;
break;
}
else if (i < count)
{
DynamicArray[i++] = value;
}
else
{
// resize the array with double the old one
count = count * 2;
int *newArray = new int[count];
memcpy(newArray, DynamicArray, count * sizeof(int));
delete[]DynamicArray;
newArray[i++] = value;
DynamicArray = newArray;
}
}
for (int k = 0; k < i; k++) {
cout << DynamicArray[k] << endl;
}
delete[] DynamicArray;
return 0;
}
(Sorry if this is formatted terribly. I've never posted before.)
I've been working on a program for class for a few hours and I can't figure out what I need to do to my function to get it to do what I want. The end result should be that addUnique will add unique inputs to a list of its own.
#include <iostream>
using namespace std;
void addUnique(int a[], int u[], int count, int &uCount);
void printInitial(int a[], int count);
void printUnique(int u[], int uCount);
int main() {
//initial input
int a[25];
//unique input
int u[25];
//initial count
int count = 0;
//unique count
int uCount = 0;
//user input
int input;
cout << "Number Reader" << endl;
cout << "Reads back the numbers you enter and tells you the unique entries" << endl;
cout << "Enter 25 positive numbers. Enter '-1' to stop." << endl;
cout << "-------------" << endl;
do {
cout << "Please enter a positive number: ";
cin >> input;
if (input != -1) {
a[count++] = input;
addUnique(a, u, count, uCount);
}
} while (input != -1 && count < 25);
printInitial(a, count);
printUnique(u, uCount);
cout << "You entered " << count << " numbers, " << uCount << " unique." << endl;
cout << "Have a nice day!" << endl;
}
void addUnique(int a[], int u[], int count, int &uCount) {
int index = 0;
for (int i = 0; i < count; i++) {
while (index < count) {
if (u[uCount] != a[i]) {
u[uCount++] = a[i];
}
index++;
}
}
}
void printInitial(int a[], int count) {
int lastNumber = a[count - 1];
cout << "The numbers you entered are: ";
for (int i = 0; i < count - 1; i++) {
cout << a[i] << ", ";
}
cout << lastNumber << "." << endl;
}
void printUnique(int u[], int uCount) {
int lastNumber = u[uCount - 1];
cout << "The unique numbers are: ";
for (int i = 0; i < uCount - 1; i++) {
cout << u[i] << ", ";
}
cout << lastNumber << "." << endl;
}
The problem is my addUnique function. I've written it before as a for loop that looks like this:
for (int i = 0; i < count; i++){
if (u[i] != a[i]{
u[i] = a[i]
uCount++;
}
}
I get why this doesn't work: u is an empty array so comparing a and u at the same spot will always result in the addition of the value at i to u. What I need, is for this function to scan all of a before deciding whether or no it is a unique value that should be added to u.
If someone could point me in the right direction, it would be much appreciated.
Your check for uniqueness is wrong... As is your defintion of addUnique.
void addUnique(int value, int u[], int &uCount)
{
for (int i = 0; i < uCount; i++){
if (u[i] == value)
return; // already there, nothing to do.
}
u[uCount++] = value;
}
#include <string.h>
#include "BubbleSort.h"
void BubbleSort(char Str[])
{
int i;
int NumElements;
bool Sorted;
char Temp;
NumElements = strlen(Str);
do {
Sorted = true;
NumElements--;
for (i = 0; i < NumElements; i++)
if (Str[i] > Str[i + 1])
{
Temp = Str[i];
Str[i] = Str[i + 1];
Str[i + 1] = Temp;
Sorted = false;
}
} while (!Sorted);
}
/////////////////////////////////////////////
#include <iostream>
#include "Bubblesort.h"
using namespace std;
void main() {
int Num;
char Array[20];
cout << "How many numbers would you like to enter?" << endl;
cin >> Num;
cout << "Enter your numbers:" << endl;
for (int i = 0; i < Num; i++)
{
cin >> Array[i];
}
cout << "Here are the numbers you entered:" << endl;
for (int i = 0; i < Num; i++)
{
cout << Array[i] << " ";
}
cout << endl << endl;
BubbleSort (Array);
cout << "Here are your sorted numbers:" << endl;
for (int i = 0; i < Num; i++)
{
cout << Array[i] << " ";
}
cout << endl;
}
////////////////////////////////////////////////////////
#ifndef BUBBLE_SORT_H
#define BUBBLE_SORT_H
void BubbleSort(char[]);
#endif
I get a Run Time Error stating that Num was corrupted. Can anyone help pinpoint the problem in my code?
Thanks
char Array[20] while the Num you input is larger than 20, it will corrupt.
Better use vector and push_back
One mistake is that you're calling strlen on a char array that is not guaranteed to be NULL terminated:
NumElements = strlen(Str);
Thus NumElements has an undetermined value.
You need to either:
1) pass the actual number of characters that are to be sorted as a parameter, along with the array and getting rid of the call to strlen:
BubbleSort(Array, Num);
//...
void BubbleSort(char Str[], int NumElements)
or
2) Make sure the char array you're passing is null terminated
I am Having Problem with Passing a 2D array to a c++ Function. The function is supposed to print the value of 2D array. But getting errors.
In function void showAttributeUsage(int)
Invalid types for int(int) for array subscript.
I know the problem is with the syntax in which I am passing the particular array to function but I don't know how to have this particular problem solved.
Code:
#include <iostream>
using namespace std;
void showAttributeUsage(int);
int main()
{
int qN, aN;
cout << "Enter Number of Queries : ";
cin >> qN;
cout << "\nEnter Number of Attributes : ";
cin >> aN;
int attVal[qN][aN];
cout << "\nEnter Attribute Usage Values" << endl;
for(int n = 0; n < qN; n++) { //for looping in queries
cout << "\n\n***************** COLUMN " << n + 1 << " *******************\n\n";
for(int i = 0; i < aN; i++) { //for looping in Attributes
LOOP1:
cout << "Use(Q" << n + 1 << " , " << "A" << i + 1 << ") = ";
cin >> attVal[n][i];
cout << endl;
if((attVal[n][i] > 1) || (attVal[n][i] < 0)) {
cout << "\n\nTHE VALUE MUST BE 1 or 0 . Please Re-Enter The Values\n\n";
goto LOOP1; //if wrong input value
}
}
}
showAttributeUsage(attVal[qN][aN]);
cout << "\n\nYOUR ATTRIBUTE USAGE MATRIX IS\n\n";
getch();
return 0;
}
void showAttributeUsage(int att)
{
int n = 0, i = 0;
while(n != '\0') {
while(i != '\0') {
cout << att[n][i] << " ";
i++;
}
cout << endl;
n++;
}
}
I really suggest to use std::vector : live example
void showAttributeUsage(const std::vector<std::vector<int>>& att)
{
for (std::size_t n = 0; n != att.size(); ++n) {
for (std::size_t i = 0; i != att.size(); ++i) {
cout << att[n][i] << " ";
}
cout << endl;
}
}
And call it that way:
showAttributeUsage(attVal);
Looking at your code, I see no reason why you can't use std::vector.
First, your code uses a non-standard C++ extension, namely Variable Length Arrays (VLA). If your goal is to write standard C++ code, what you wrote is not valid standard C++.
Second, your initial attempt of passing an int is wrong, but if you were to use vector, your attempt at passing an int will look almost identical if you used vector.
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
typedef std::vector<int> IntArray;
typedef std::vector<IntArray> IntArray2D;
using namespace std;
void showAttributeUsage(const IntArray2D&);
int main()
{
int qN, aN;
cout << "Enter Number of Queries : ";
cin >> qN;
cout << "\nEnter Number of Attributes : ";
cin >> aN;
IntArray2D attVal(qN, IntArray(aN));
//... Input left out ...
showAttributeUsage(attVal);
return 0;
}
void showAttributeUsage(const IntArray2D& att)
{
for_each(att.begin(), att.end(),
[](const IntArray& ia) {std::copy(ia.begin(), ia.end(), ostream_iterator<int>(cout, " ")); cout << endl;});
}
I left out the input part of the code. The vector uses [] just like a regular array, so no code has to be rewritten once you declare the vector. You can use the code given to you in the other answer by molbdnilo for inputing the data (without using the goto).
Second, just to throw it into the mix, the showAttributeUsage function uses the copy algorithm to output the information. The for_each goes throw each row of the vector, calling std::copy for the row of elements. If you are using a C++11 compliant compiler, the above should compile.
You should declare the function like this.
void array_function(int m, int n, float a[m][n])
{
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
a[i][j] = 0.0;
}
where you pass in the dimensions of array.
This question has already been answered here. You need to use pointers or templates. Other solutions exists too.
In short do something like this:
template <size_t rows, size_t cols>
void showAttributeUsage(int (&array)[rows][cols])
{
for (size_t i = 0; i < rows; ++i)
{
std::cout << i << ": ";
for (size_t j = 0; j < cols; ++j)
std::cout << array[i][j] << '\t';
std::cout << std::endl;
}
}
You're using a compiler extension that lets you declare arrays with a size determined at runtime.
There is no way to pass a 2D array with such dimensions to a function, since all but one dimension for an array as a function parameter must be known at compile time.
You can use fixed dimensions and use the values read as limits that you pass to the function:
const int max_queries = 100;
const int max_attributes = 100;
void showAttributeUsage(int array[max_queries][max_attributes], int queries, int attributes);
int main()
{
int attVal[max_queries][max_attributes];
int qN = 0;
int aN = 0;
cout << "Enter Number of Queries (<= 100) : ";
cin >> qN;
cout << "\nEnter Number of Attributes (<= 100) : ";
cin >> aN;
cout << "\nEnter Attribute Usage Values" << endl;
for (int n = 0; n < qN; n++)
{
cout << "\n\n***************** COLUMN " << n + 1 <<" *******************\n\n";
for (int i = 0; i < aN; i++)
{
bool bad_input = true;
while (bad_input)
{
bad_input = false; // Assume that input will be correct this time.
cout << "Use(Q" << n + 1 << " , " << "A" << i + 1 << ") = ";
cin >> attVal[n][i];
cout << endl;
if (attVal[n][i] > 1 || attVal[n][i] < 0)
{
cout << "\n\nTHE VALUE MUST BE 1 or 0 . Please Re-Enter The Values\n\n";
bad_input = true;
}
}
}
}
cout << "\n\nYOUR ATTRIBUTE USAGE MATRIX IS\n\n";
showAttributeUsage(attVal, qN, aN);
getch();
return 0;
}
void showAttributeUsage(int att[max_queries][max_attributes], int queries, int attributes)
{
for (int i = 0; i < queries; i++)
{
for (int j = 0; j < attributes; j++)
{
cout << att[i][j] << " ";
}
cout << endl;
}
}
For comparison, the same program using std::vector, which is almost identical but with no size limitations:
void showAttributeUsage(vector<vector<int> > att);
int main()
{
cout << "Enter Number of Queries (<= 100) : ";
cin >> qN;
cout << "\nEnter Number of Attributes (<= 100) : ";
cin >> aN;
vector<vector<int> > attVal(qN, vector<int>(aN));
cout << "\nEnter Attribute Usage Values"<<endl;
for (int n = 0; n < qN; n++)
{
cout<<"\n\n***************** COLUMN "<<n+1<<" *******************\n\n";
for (int i = 0; i < aN; i++)
{
bool bad = true;
while (bad)
{
bad = false;
cout << "Use(Q" << n + 1 << " , " << "A" << i + 1 << ") = ";
cin >> attVal[n][i];
cout << endl;
if (attVal[n][i] > 1 || attVal[n][i] < 0)
{
cout << "\n\nTHE VALUE MUST BE 1 or 0 . Please Re-Enter The Values\n\n";
bad = true;
}
}
}
}
cout << "\n\nYOUR ATTRIBUTE USAGE MATRIX IS\n\n";
showAttributeUsage(attVal);
getch();
return 0;
}
void showAttributeUsage(vector<vector<int> > att);
{
for (int i = 0; i < att.size(); i++)
{
for (int j = 0; j < att[i].size(); j++)
{
cout << att[i][j] << " ";
}
cout << endl;
}
}
The Particular Logic worked for me. At last found it. :-)
int** create2dArray(int rows, int cols) {
int** array = new int*[rows];
for (int row=0; row<rows; row++) {
array[row] = new int[cols];
}
return array;
}
void delete2dArray(int **ar, int rows, int cols) {
for (int row=0; row<rows; row++) {
delete [] ar[row];
}
delete [] ar;
}
void loadDefault(int **ar, int rows, int cols) {
int a = 0;
for (int row=0; row<rows; row++) {
for (int col=0; col<cols; col++) {
ar[row][col] = a++;
}
}
}
void print(int **ar, int rows, int cols) {
for (int row=0; row<rows; row++) {
for (int col=0; col<cols; col++) {
cout << " | " << ar[row][col];
}
cout << " | " << endl;
}
}
int main () {
int rows = 0;
int cols = 0;
cout<<"ENTER NUMBER OF ROWS:\t";cin>>rows;
cout<<"\nENTER NUMBER OF COLUMNS:\t";cin>>cols;
cout<<"\n\n";
int** a = create2dArray(rows, cols);
loadDefault(a, rows, cols);
print(a, rows, cols);
delete2dArray(a, rows, cols);
getch();
return 0;
}
if its c++ then you can use a templete that would work with any number of dimensions
template<typename T>
void func(T& v)
{
// code here
}
int main()
{
int arr[][7] = {
{1,2,3,4,5,6,7},
{1,2,3,4,5,6,7}
};
func(arr);
char triplestring[][2][5] = {
{
"str1",
"str2"
},
{
"str3",
"str4"
}
};
func(triplestring);
return 0;
}
Ok, so I have a simple c++ program that's supposed to run a couple sorting algorithms on an array composed of ints and track the time each one takes.. pretty basic, however I've run into a problem.
When the program first starts, it asks how many items you would like in the array. My assignment involves setting the array at specific lengths from 100 items all the way to 750000. It'll handle many values, including up to around 600000. When I try 750000 however it immediately segfaults. A couple couts here and there led me to discover that the error happens when the fourth array (all of the same length) is initialized. The weird thing is that it only happens on my OS; at my school it works no problem. (i'm on the latest ubuntu while my school uses redhat. not sure if that's useful)
I'll include the complete code just for reference but the segfault occurs at line 27:
int array1[num], array2[num], array3[num], array4[num]; // initialize arrays
I know this because I initialized each array on separate lines and put couts in between. array1, 2, and 3 were initialized, then it segfaults. Again this ONLY happens when the arrays are longer than about 600000 or so. Anything less works fine.
Full code:
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
void insertionSort(int array[], int size);
void bubbleSort(int array[], int size);
void mergeSort(int array[], int first, int last, int size);
void quickSort(int array[], int size);
int main()
{
cout << endl << endl << "\t\t**** Extra Credit Assignment- Sorting ****" << endl << endl << endl;
cout << "Enter the number of items to sort: ";
int num;
cin >> num;
while(cin.fail()) // while cin does not recieve an integer
{
cin.clear();
cin.ignore(1000, '\n');
cout << "Invalid entry. Try again: "; // try again
cin >> num;
}
int array1[num], array2[num], array3[num], array4[num]; // initialize arrays
int randNum, sizeOfArray = sizeof(array1)/sizeof(array1[0]); // random number, size of the arrays
srand(time(NULL)); // random seed (used with rand())
for(int i = 0; i < sizeOfArray; i++) // traverse through the array
{
randNum = rand() % 2147483647+1; // establish random number (from 1 to 2147483647)
array1[i] = array2[i] = array3[i] = array3[i] = randNum; // set randNum to all arrays at current index
}
time_t beginTime, endTime;
double elapsedTime;
cout << endl << "Elapsed time:" << endl << "\tInsertion Sort-\t";
time(&beginTime);
insertionSort(array1, sizeOfArray);
time(&endTime);
elapsedTime = difftime(endTime, beginTime);
cout << elapsedTime << " seconds" << endl << "\tBubble Sort-\t";
time(&beginTime);
bubbleSort(array2, sizeOfArray);
time(&endTime);
elapsedTime = difftime(endTime, beginTime);
cout << elapsedTime << " seconds" << endl << "\tMerge Sort-\t";
time(&beginTime);
mergeSort(array3, 0, sizeOfArray-1, sizeOfArray);
time(&endTime);
elapsedTime = difftime(endTime, beginTime);
cout << elapsedTime << " seconds"<< endl;
/* ********************* TESTING *************************
// *******************************************************
cout << "Insertion->Unsorted:\t";
for(int i = 0; i < sizeOfArray; i++)
{
cout << array1[i] << " ";
}
cout << endl;
insertionSort(array1, sizeOfArray);
cout << "Insertion->Sorted:\t";
for(int i = 0; i < sizeOfArray; i++)
{
cout << array1[i] << " ";
}
cout << endl;
cout << "Bubble->Unsorted:\t";
for(int i = 0; i < sizeOfArray; i++)
{
cout << array2[i] << " ";
}
cout << endl;
bubbleSort(array2, sizeOfArray);
cout << "Bubble->Sorted:\t\t";
for(int i = 0; i < sizeOfArray; i++)
{
cout << array2[i] << " ";
}
cout << endl;
cout << "Merge->Unsorted:\t";
for(int i = 0; i < sizeOfArray; i++)
{
cout << array3[i] << " ";
}
cout << endl;
mergeSort(array3, 0, sizeOfArray-1, sizeOfArray);
cout << "Merge->Sorted:\t\t";
for(int i = 0; i < sizeOfArray; i++)
{
cout << array3[i] << " ";
}
cout << endl; */
return 0;
}
void insertionSort(int array[], int size)
{
for(int i = 1; i < size; i++)
{
int item = array[i], index = i;
while(index > 0 && array[index-1] > item)
{
array[index] = array[index-1];
index--;
}
array[index] = item;
}
}
void bubbleSort(int array[], int size)
{
bool sorted = false;
for(int i = 1; i < size && !sorted; i++)
{
sorted = true;
for(int i2 = 0; i2 < size-i; i2++)
{
int nextI = i2+1;
if(array[i2] > array[nextI])
{
swap(array[i2], array[nextI]);
sorted = false;
}
}
}
}
void merge(int array[], int first, int mid, int last, int size)
{
int tempArray[size];
int first1 = first, first2 = mid+1;
int last1 = mid, last2 = last;
int index = first1;
while(first1 <= last1 && first2 <= last2)
{
if(array[first1] < array[first2])
{
tempArray[index] = array[first1];
first1++;
}
else
{
tempArray[index] = array[first2];
first2++;
}
index++;
}
while(first1 <= last1)
{
tempArray[index] = array[first1];
first1++;
index++;
}
while(first2 <= last2)
{
tempArray[index] = array[first2];
first2++;
index++;
}
for(index = first; index <= last; index++)
{
array[index] = tempArray[index];
}
}
void mergeSort(int array[], int first, int last, int size)
{
if(first < last)
{
int mid = (first+last)/2;
mergeSort(array, first, mid, size);
mergeSort(array, mid+1, last, size);
merge(array, first, mid, last, size);
}
}
Any help is greatly appreciated. It might be a memory limitation on my system? I really don't know lol just a thought.
You can't allocate such big arrays on the stack which has a fixed limited size, try:
int* array1 = new int[num];
As others have noted, the SEGV you're getting is due to overflowing the stack. The reason it happens on your ubuntu machine and not your school's redhat machine is likely due to differences in the default stack size.
You may be able to change your default stack size with ulimit -s which, with no additional arguments, will print your current stack size in kilobytes. For example, on my machine, that prints 8192 or 8 megabytes. I can raise it to 16MB with ulimit -s 16384
An array of 750000 ints will require about 3MB of stack space (4 bytes per int), so 4 such arrays (like you have) will require 12MB...
You've allocated very large arrays on the stack and you're overflowing the stack. If you new them or make them static, they'll be allocated on the heap and you won't fail.
It's because the stack is not an infinite resource. When you do int x[big_honkin_number], it tries to allocate enough space on the stack for that array.
You can usually compile/link your code to give you more stack but a better solution is to use dynamic memory allocation (i.e., new).