I am trying to write a code that uses quicksort to sort words by alphabetical order, but when I run my code it gets stuck on inputting the user's words. What's the reason behind this? It works fine when I leave the array as an integer array. Thanks in advance!
#include <iostream>
#include <cstdlib>
#include <cstring>
using namespace std;
void quicksort(char a[], int size, int left, int right)
{
int i = left;
int j = right;
int pivot = a[(left+right)/2];
char temp;
while (i <= j)
{
while (a[i] < pivot) i++;
while (a[j] > pivot) j--;
if (i <= j)
{
temp = a[i];
a[i] = a[j];
a[j] = temp;
i++;
j--;
}
}
if (i < right)
quicksort(a, size, i, right);
if (j > left)
quicksort(a, size, left, j);
}
int main()
{
char a[10], n;
system("clear");
cout << "Enter the number of elements to be sorted: " << endl;
cin >> n;
cout << "Enter the elements to be sorted (press ENTER after each word): " << endl;
for (int i = 0; i < n; i++)
cin >> a[i];
quicksort(a, n, 0, n-1);
cout << endl;
cout << "The sorted elements are: " << endl;
for (int i = 0; i < n; i++)
cout << a[i] << " ";
cout << endl;
return 0;
}
You code may work but you're trying to read words in an array of char. You need to use a string (store a whole word) or an array of string (store multiple strings).
Your code may look like this:
int main()
{
string a[10], n;
system("clear");
cout << "Enter the number of elements to be sorted: " << endl;
cin >> n;
cout << "Enter the elements to be sorted (press ENTER after each word): " << endl;
for (int i = 0; i < n; i++)
{
cin >> a[i];
quicksort(a, n, 0, a[i].length -1);
}
cout << "The sorted elements are: " << endl;
for (int i = 0; i < n; i++)
cout << a[i] << " " << endl;
return 0;
}
Please have in mind the that the code structure in c++ it's different than python. Have a look to this coding and naming conventions
http://www.dofactory.com/reference/csharp-coding-standards
Thank you all for helping! This is the final solution:
#include <iostream>
#include <cstdlib>
#include <cstring>
using namespace std;
void quicksort(std::string a[], int size, int left, int right)
{
int i = left;
int j = right;
std::string pivot = a[(left+right)/2];
std::string temp;
while (i <= j)
{
while (a[i] < pivot) i++;
while (a[j] > pivot) j--;
if (i <= j)
{
temp = a[i];
a[i] = a[j];
a[j] = temp;
i++;
j--;
}
}
if (i < right)
quicksort(a, size, i, right);
if (j > left)
quicksort(a, size, left, j);
}
int main()
{
std::string a[100];
int n;
system("clear");
cout << "Enter the number of elements to be sorted: " << endl;
cin >> n;
cout << "Enter the elements to be sorted (press ENTER after each word): " << endl;
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
quicksort(a, n, 0, n-1);
cout << endl;
cout << "The sorted elements are: " << endl;
for (int i = 0; i < n; i++)
cout << a[i] << " ";
cout << endl;
return 0;
}
Related
I'm a C++ newb. I need to insert numbers to an array and then display first the odd numbers and then the even numbers in a single array. I've managed to create two separate arrays with the odd and even numbers but now I don't know how to sort them and put them back in a single array. I need your help to understand how to do this with basic C++ knowledge, so no advanced functions. Here's my code:
#include <iostream>
using namespace std;
int main()
{
int N{ 0 }, vector[100], even[100], odd[100], unify[100], i{ 0 }, j{ 0 }, k{ 0 };
cout << "Add the dimension: " << endl;
cin >> N;
cout << "Add the elements: " << endl;
for (int i = 0; i < N; i++) {
cout << "v[" << i << "]=" << endl;
cin >> vector[i];
}
for (i = 0; i < N; i++) {
if (vector[i] % 2 == 0) {
even[j] = vector[i];
j++;
}
else if (vector[i] % 2 != 0) {
odd[k] = vector[i];
k++;
}
}
cout << "even elements are :" << endl;
for (i = 0; i < j; i++) {
cout << " " << even[i] << " ";
cout << endl;
}
cout << "Odd elements are :" << endl;
for (i = 0; i < k; i++) {
cout << " " << odd[i] << " ";
cout << endl;
}
return 0;
}
If you don't need to store the values then you can simply run through the elements and print the odd and the even values to different stringstreams, then print the streams at the end:
#include <sstream>
#include <stddef.h>
#include <iostream>
int main () {
std::stringstream oddStr;
std::stringstream evenStr;
static constexpr size_t vecSize{100};
int vec[vecSize] = {10, 5, 7, /*other elements...*/ };
for(size_t vecIndex = 0; vecIndex < vecSize; ++vecIndex) {
if(vec[vecIndex] % 2 == 0) {
evenStr << vec[vecIndex] << " ";
} else {
oddStr << vec[vecIndex] << " ";
}
}
std::cout << "Even elements are:" << evenStr.rdbuf() << std::endl;
std::cout << "Odd elements are:" << oddStr.rdbuf() << std::endl;
}
Storing and sorting the elements are always expensive.
Basically, it would be better to sort them first.
#include <iostream>
using namespace std;
int main()
{
int numbers[5];
int mergedArrays[5];
int evenNumbers[5];
int oddNumbers[5];
for(int i=0;i<5;i++){
cin>>numbers[i];
}
int temp=numbers[0];
//bubble sort
for(int i = 0; i<5; i++)
{
for(int j = i+1; j<5; j++)
{
if(numbers[j] < numbers[i])
{
temp = numbers[i];
numbers[i] = numbers[j];
numbers[j] = temp;
}
}
}
int nEvens=0;
int nOdds=0;
for(int i = 0; i<5; i++)
{
if(numbers[i]%2==0)
{
evenNumbers[nEvens]=numbers[i];
nEvens++;
}
else if(numbers[i]%2!=0)
{
oddNumbers[nOdds]=numbers[i];
nOdds++;
}
}
int lastIndex=0;
//copy evens
for(int i = 0; i<nEvens; i++)
{
mergedArrays[i]=evenNumbers[i];
lastIndex=i;
}
//copy odds
for(int i =lastIndex; i<nOdds; i++)
{
mergedArrays[i]=oddNumbers[i];
}
return 0;
}
If you have to just output the numbers in any order, or the order given in the input then just loop over the array twice and output first the even and then the odd numbers.
If you have to output the numbers in order than there is no way around sorting them. And then you can include the even/odd test in the comparison:
std::ranges::sort(vector, [](const int &lhs, const int &rhs) {
return ((lhs % 2) < (rhs % 2)) || (lhs < rhs); });
or using a projection:
std::ranges::sort(vector, {}, [](const int &x) {
return std::pair<bool, int>{x % 2 == 0, x}; });
If you can't use std::ranges::sort then implementing your own sort is left to the reader.
I managed to find the following solution. Thanks you all for your help.
#include <iostream>
using namespace std;
int main()
{
int N{0}, vector[100], even[100], odd[100], merge[100], i{0}, j{0}, k{0}, l{0};
cout << "Add the dimension: " << endl;
cin >> N;
cout << "Add the elements: " << endl;
for (int i = 0; i < N; i++)
{
cout << "v[" << i << "]=" << endl;
cin >> vector[i];
}
for (i = 0; i < N; i++)
{
if (vector[i] % 2 == 0)
{
even[j] = vector[i];
j++;
}
else if (vector[i] % 2 != 0)
{
odd[k] = vector[i];
k++;
}
}
cout << "even elements are :" << endl;
for (i = 0; i < j; i++)
{
cout << " " << even[i] << " ";
cout << endl;
}
cout << "Odd elements are :" << endl;
for (i = 0; i < k; i++)
{
cout << " " << odd[i] << " ";
cout << endl;
}
for (i = 0; i < k; i++)
{
merge[i] = odd[i];
}
for (int; i < j + k; i++)
{
merge[i] = even[i - k];
}
for (int i = 0; i < N; i++)
{
cout << merge[i] << endl;
}
return 0;
}
You can use Bubble Sort Algorithm to sort whole input. After sorting them using if and put odd or even numbers in start of result array and and others after them. like below:
//Bubble Sort
void bubbleSort(int arr[], int n)
{
int i, j;
for (i = 0; i < n - 1; i++)
// Last i elements are already
// in place
for (j = 0; j < n - i - 1; j++)
if (arr[j] > arr[j + 1])
swap(arr[j], arr[j + 1]);
}
// Insert In array
int result[100];
if(odd[0]<even[0])
{
for (int i = 0; i < k; i++)
{result[i] = odd[i];}
for (int i = 0; i < j; i++)
{result[i+k] = even[i];}
}else
{
for (int i = 0; i < j; i++)
{result[i] = even[i];}
for (int i = 0; i < k; i++)
{result[i+k] = odd[i];}
}
Code:
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
void partition(int *A, int start, int end){ //end is the position of the last number
cout<<"start is "<<start<<" end is "<<end<<endl;
if(end - start+1 > 1){
int i = start + 1, j = start + 1, pivot = A[start];
while(j <= end){
if(A[j] <= pivot){
swap(A[j], A[i]);
i++;
}
j++;
}
swap(A[start], A[i-1]);
partition(A, start, i-1);
partition(A, i, end);
}
}
void QuickSort(int *A, int n){
partition(A, 0, n-1);
}
int main() {
int n, method;
string sortMethod[ ] = {
"Insertion sort", "Selection sort", "Bubble sort", "Merge sort", "Quick sort"
};
int m = sizeof(sortMethod)/sizeof(string);
srand(time(0));
while (true){
cout << "Number of test marks: ";
cin >> n;
if ( n==0 ) break;
int *A = new int[n];
for (int i=0; i < n; i++) cin>>A[i];
//A[i] = rand()%101;
for (int i=0; i < n; i++)cout << A[i] << " ";
cout<<endl<<endl;
cout << "Sorting method: \n";
for (int i=0; i < m; i++) cout << i+1 << ": " << sortMethod[i] << endl;
// cin >> method;
method = 5;
cout<<endl;
int t = time(0);
QuickSort(A,n);
if (method > m) continue;
cout << sortMethod[method-1] << endl;
if (n <= 100) {
for (int i=0; i < n; i++) {
if (i> 0 && i%10==0) cout << endl;
cout << A[i] << " ";
}
cout << endl;
}
else {
cout << "Sorting completed in " << time(0) - t << " sec.\n";
}
cout << endl;
}
cout << "Program ends here."<<endl;
return 0;
}
When some of my input numbers have the same value, I get a "Segmentation fault: 11".
For example, an input of "4 7 7 3 1" would produce infinite lines of the following output: "start is 1 end is 3".
May I ask how should I improve my code? I know that Segfault 11 happens when you try to access an invalid memory, and i think that's likely what I did here, although i cant seem to identify the error. Thanks!
So this is what's happening here. Imagine that in a certain partition the first element (the pivot) is also the largest.
This means that in every iteration of the while loop the value of A[j]<=pivot will be true and i will be increased.
Since both i and j are increased by 1 in every iteration there value is the same, so at the end of the loop they are both equal to end+1.
Then you are invoking partition(A, start, i-1) which is really the same as partition(A, start, end) - meaning you have an infinite recursion which continues until you reach... well, stack overflow and the program crush with segfault.
The minimal fix will be to make sure that the sub partitions are strictly smaller than the original one by excluding the pivot from them. So something like this:
partition(A, start, i-2); // i-1 is the pivot, so we don't need to include it
partition(A, i, end);
In the code below, I am trying to output the integers in ascending order. It works, however I want the final integer to be put on a newline (final integer only- not the other integers). I have tried
cout << myVec[i] << " "; endl
and...
cout << myVec[i] << endl;
but, both do not give the output I am looking for (these affect the other integers which is not what I want.
#include <iostream>
#include <vector>
using namespace std;
void SortVector(vector<int>& myVec)
{
int n = myVec.size();
int i, j;
for (i = 0; i < n - 1; i++)
for (j = 0; j < n - i - 1; j++)
if (myVec[j] > myVec[j + 1])
{
int temp = myVec[j];
myVec[j] = myVec[j + 1];
myVec[j + 1] = temp;
}
}
int main()
{
int i, n, value;
cin >> n;
vector<int> myVec;
for (i = 0; i < n; i++)
{
cin >> value;
myVec.push_back(value);
}
SortVector(myVec);
for (i = 0; i < n; i++)
cout << myVec[i] << " ";
return 0;
}
Print all but the last element on one line:
for (i = 0; i < n-1; i++) // notice n-1
std::cout << myVec[i] << ' ';
std::cout << '\n';
Then you can print the last afterwards:
if(myVec.size())
std::cout << myVec.back() << '\n';
I am new, not that good with functions, and I am trying to solve this question:
Suppose A, B, C are arrays of integers of size [M], [N], and [M][N], respectively. The user will enter the values for the array A and B. Write a user defined function in C++ to calculate the third array C by adding the elements of A and B. If the elements have the same index number, they will be multiplied. C is calculated as the following: -
Use A, B and C as arguments in the function.
Below is my attempt at the problem.
#include<iostream>
using namespace std;
void Mix(int(&A)[], int(&B)[], int(&C)[][100], int N, int M);
//dont understand why you used Q
int main()
{
//variable declaration
int A[100], B[100], C[100][100], n, m, l = 0;
//input of size of elements for first ararys
cout << "Enter number of elements you want to insert in first array: ";
cin >> n;
cout << "-----------------" << endl;
cout << "-----------------" << endl;
cout << "Enter your elements in ascending order" << endl;
//input the elements of the array
for (int i = 0; i < n; i++)
{
cout << "Enter element " << i + 1 << ":";
cin >> A[i];
}
cout << endl << endl;
//input of size of elements for first ararys
cout << "Enter number of elements you want to insert in second array: ";
cin >> m;
cout << "-----------------" << endl;
cout << "-----------------" << endl;
cout << "Enter your elements in descending order" << endl;
//input the elements of the array
for (int i = 0; i < m; i++)
{
cout << "Enter element " << i + 1 << ":";
cin >> B[i];
}
Mix(A, B, C, n, m);
cout << "\nThe Merged Array in Ascending Order" << endl;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++)
{
cout << C[i][j] << " ";
}
cout << "\n"; //endline never use endl its 10 times slower
}
system("pause");
return 0;
}
void Mix(int(&A)[], int(&B)[], int(&C)[][100], int N, int M)
{
// rows is the index for the B array, cols is index for A array
int rows = 0;
int cols = 0;
while (rows < M) {
while (cols < N) {
if (rows == cols) { // remember ==
C[rows][cols] = B[rows] * A[cols];
}
else {
C[rows][cols] = B[rows] + A[cols];
}
cols++; // increment here
}
rows++; // increment here
}
return;
}
Here is an example of the output:
enter image description here
In order to make the C array two-dimensional, it needs to be expressed as C[100][100], instead of C[200]. That is the first step. Next, in your Mix() function, you need to cycle through each element of both A and B (ex. two for loops). Your rows change as B changes, and your columns change as A changes. Include a check for identical indices that will determine whether to add or multiply the two values together.
void Mix(int A[], int B[], int C[][], int N, int M) {
// rows is the index for the B array, cols is index for A array
for (int rows = 0; rows < M; rows++) {
for (int cols = 0; cols < N; cols++) {
if (rows == cols) { // remember ==
C[rows][cols] = B[rows] * A[cols];
} else {
C[rows][cols] = B[rows] + A[cols];
}
}
}
}
Make sure your arrays are properly defined and print out the C array by row and column to match the specifications.
UPDATE: If you want to use while loops, I would default to deconstructing the for loops and apply the same logic:
void Mix(int A[], int B[], int C[][], int N, int M) {
// rows is the index for the B array, cols is index for A array
int rows = 0;
int cols = 0;
while (rows < M) {
while (cols < N) {
if (rows == cols) { // remember ==
C[rows][cols] = B[rows] * A[cols];
} else {
C[rows][cols] = B[rows] + A[cols];
}
cols++; // increment here
}
rows++; // increment here
}
}
I would definitely recommend the for loop approach, as it is more compact, yet does the exact same operations.
There are a lot of things wrong with your code. First off an 2D array must be declared with 2 squared brackets so C[200][200]. In the Mix function the logical operator is == not = in if (A[I] = B[J])
Anyway here's the function that you need:
#include<iostream>
using namespace std;
void Mix(int A[], int B[], int C[], int N, int M) {
//dont understand why you used Q
int i, j;
for(i=0; i<N; i++) {
for(j=0; j<M; j++) {
if(i==j){
C[i][j] = A[i] * B[j];
}
else {
C[i][j] = A[i] + B[j];
}
}
}
return C[i][j];
}
int main()
{
//variable declaration
int A[100], B[100], C[200], j, i, n, m, l = 0;
string Comma;
//input of size of elements for first ararys
cout << "Enter number of elements you want to insert in first array: ";
cin >> n;
cout << "-----------------" << endl;
cout << "-----------------" << endl;
cout << "Enter your elements in ascending order" << endl;
//input the elements of the array
for (i = 0; i < n; i++)
{
cout << "Enter element " << i + 1 << ":";
cin >> A[i];
}
cout << endl << endl;
//input of size of elements for first ararys
cout << "Enter number of elements you want to insert in second array: ";
cin >> m;
cout << "-----------------" << endl;
cout << "-----------------" << endl;
cout << "Enter your elements in descending order" << endl;
//input the elements of the array
for (j = 0; j < m; j++)
{
cout << "Enter element " << j + 1 << ":";
cin >> B[j];
}
C = Mix(A, B, C, n, m);
cout << "\nThe Merged Array in Ascending Order" << endl;
for(i=0; i<n; i++) {
for(j=0; j<m; j++) {
cout<<C[i][j]<<" ";
}
cout<<"\n" //endline never use endl its 10 times slower
}
system("pause");
return 0;
}
Because M and N are defined at run time, you'll really want to use vectors to represent them. Additionally consider returning a 2D container so as to leverage return value optimization.
I'm going to write an example using a vector of vectors for simplicity (see What are the Issues with a vector-of-vectors? for more on why that's really just good for a toy example):
vector<vector<int>> Mix(const vector<int>& A, const vector<int>& B) {
vector<vector<int>> result(size(B), vector<int>(size(A)));
for(size_t i = 0U; i < size(B); ++i) {
for(size_t j = 0U; j < size(A); ++j) {
result[i][j] = A[j] * B[i];
}
}
return result;
}
Live Example
EDIT:
If you must use arrays you'll miss out on return value optimization. I'd only choose this as a good option in the situations:
That you weren't returning anything, in which case your function would probably look something like:
void Mix(const int* A, const int* B, const size_t size_A, const size_t size_B)
{
for(size_t i = 0U; i < size_B; ++i) {
for(size_t j = 0U; j < size_A; ++j) {
cout << '[' << i << "][" << j << "]: " << A[j] * B[i] << '\t';
}
cout << endl;
}
}
That you weren't calling a function and you'd already been given int A[M] and int B[N] as inputs and int C[N][M] as an output, in which case the code you'd inline would probably look something like this:
for(size_t i = 0U; i < size(B); ++i) {
for(size_t j = 0U; j < size(A); ++j) {
C[i][j] = A[j] * B[i];
}
}
I have an array of numbers input by the user, the program then sorts it in ascending order. I just need to find a way to get the factors of each number in the array and have it be printed out
#include "stdafx.h"
#include <iostream>
#include <limits>
#define MAX 200
using namespace std;
int arr[MAX];
int n, i, j, k;
int temp;
int main()
{
//array declaration
int arr[MAX];
int n, i, j;
int temp;
//read total number of elements to read
cout << "Enter total number of numbers to read: ";
cin >> n;
//check bound
if (n<0 || n>MAX)
{
cout << "Input valid range!!!" << endl;
return -1;
}
//read n elements
for (i = 0; i < n; i++)
{
cout << "Enter element [" << i + 1 << "] ";
cin >> arr[i];
cout << endl;
}
//print input elements
cout << "Unsorted Array elements:" << endl;
for (i = 0; i < n; i++)
cout << arr[i] << "\t";
cout << endl;
//sorting - ASCENDING ORDER
for (i = 0; i<n; i++)
{
for (j = i + 1; j < n; j++)
{
if (arr[i]>arr[j])
{
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
//print sorted array elements
cout << endl;
cout << "Sorted (Ascending Order) Array elements:" << endl;
for (i = 0; i < n; i++)
cout << arr[i] << "\t";
cout << endl <<endl;
//trying to find factors
cout << "Factors of " << arr[i] << " are: " << endl;
for (k = 1; k <= arr[i]; ++i)
{
if (arr[i] % k == 0)
cout << k << endl;
}
system ("pause")
return 0;
}
I want it to print each number from the array with
"The factors of (number) are ...'
"The factors of (next number) are ..."
and so on
The final for-loop should be loop with k and you forgot to increment k.
You should also write i-loop:
//trying to find factors
for (i = 0; i < n; i++)
{
cout << "Factors of " << arr[i] << " are: " << endl;
for (k = 1; k <= arr[i]; ++k)
{
if (arr[i] % k == 0)
cout << k << endl;
}
}
In addition, as pointed out by #LocTran, the upper bound of outer loop should be n-1.
Alternatively, you can easily sort arr using std::sort as follows:
std::sort(arr, arr+n);
Then your code would well work for you:
Live Demo
There are some issues with your source code.
1> Sorting problem with for outer loop
//sorting - ASCENDING ORDER
for (i = 0; i < (n-1); i++)
{
for (j = i + 1; j < n; j++)
{
if (arr[i] > arr[j])
{
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
The upper bound of outer loop should be (n-1), not n as following but maybe you're lucky you won't see the problem when n < MAX. In case of n == MAX you will see the problem
//sorting - ASCENDING ORDER
//for (i = 0; i < n; i++)
for (i = 0; i < (n-1); i++)
{
for (j = i + 1; j < n; j++)
{
if (arr[i] > arr[j])
{
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
2> The print functionality for entire array, you should add the outer loop for index of your array, and change the i++ by k++ in your loop as well
//trying to find factors
cout << "Factors of " << arr[i] << " are: " << endl;
for (k = 1; k <= arr[i]; ++i)
{
if (arr[i] % k == 0)
cout << k << endl;
}
should be replaced by
//trying to find factors
for (i = 0; i < n; i++)
{
cout << "Factors of " << arr[i] << " are: " << endl;
//for (k = 1; k <= arr[i]; ++i)
for (k = 1; k <= arr[i]; ++k)
{
if (arr[i] % k == 0)
cout << k << endl;
}
}
Here is my solution based on modified source code
#include <iostream>
#include <limits>
#define MAX 200
using namespace std;
int arr[MAX];
int n, i, j, k;
int temp;
int main()
{
//array declaration
int arr[MAX];
int n, i, j;
int temp;
//read total number of elements to read
cout << "Enter total number of numbers to read: ";
cin >> n;
//check bound
//if (n<0 || n>MAX)
if (n<0 || n>MAX)
{
cout << "Input valid range!!!" << endl;
return -1;
}
//read n elements
for (i = 0; i < n; i++)
{
cout << "Enter element [" << i + 1 << "] ";
cin >> arr[i];
cout << endl;
}
//print input elements
cout << "Unsorted Array elements:" << endl;
for (i = 0; i < n; i++)
cout << arr[i] << "\t";
cout << endl;
//sorting - ASCENDING ORDER
//for (i = 0; i < n; i++)
for (i = 0; i < (n-1); i++)
{
for (j = i + 1; j < n; j++)
{
if (arr[i] > arr[j])
{
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
//print sorted array elements
cout << endl;
cout << "Sorted (Ascending Order) Array elements:" << endl;
for (i = 0; i < n; i++)
cout << arr[i] << "\t";
cout << endl << endl;
//trying to find factors
for (i = 0; i < n; i++)
{
cout << "Factors of " << arr[i] << " are: " << endl;
//for (k = 1; k <= arr[i]; ++i)
for (k = 1; k <= arr[i]; ++k)
{
if (arr[i] % k == 0)
cout << k << endl;
}
}
return 0;
}