I wrote the following to try to use the qsort() function. My goal is to input several lines of text and print an alphabetical listing of each word. This code crashes every time I run it and i am not sure as to why or how to fix it. I also need to add something to count the number of times a word occurs and print that as well but I an mot too sure how to do that. Any advice would be very helpful. Thanks!
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
struct to_lower
{
int operator() ( int ch )
{
return tolower ( ch );
}
};
int compare (const void * a, const void * b)
{
//return ( *(int*)a - *(int*)b );
return (strcmp(*(const char **)a, *(const char **)b));
}
int main()
{
string list[900];
int nLength;
int i=0, q=0;
string nTemp;
int word[900];
cout
<< "Enter some lines of text "
<< "(Enter Ctrl-Z on a line by itself to exit)\n"
<< endl;
while ( !cin.eof() )
{
cin >> list[i];
transform(list[i].begin(), list[i].end(), list[i].begin(), to_lower());
word[q]=1;
if (list[i]==list[i-1])
{
word[q]=+1;
}
i++;
}
nLength = i;
cout << "The sorted words would be:\n";
qsort(list, nLength, sizeof list[0],&compare);
int n;
for (n = 0; n < nLength; n++)
{
cout <<" \n"<< n << list[n]<< word[n];
}
return 0;
}
std::string is not a char* as your qsort compare function pretends. Also, you should never use qsort with C++ objects. qsort does not know about objects and won't call copy constructors and may damage the internal structure.
When i=0, using list[i-1] is a bug.
You need to count your duplicate words after sorting or you have no guarantee that duplicates are next to each other.
Related
As part of my homework assignment, I have to split a char[] by its indices. So for example, the main function looks like:
int main()
{
char str[] = "A string to be split into given number of parts";
int split_size;
cout << "Enter the size of the part: ";
cin >> split_size;
int size = sizeof(str) / sizeof(str[0]);
SplitString(str, split_size, size);
int wait;
cin >> wait;
return 0;
}
Then using the function SplitString, the first x elements are printed, new line, then the next.
My first idea, was to use two for loops. One loops through the splits (i.e. if there are 4 splits, the range on this loop is 0 to 3), then the second loops through the split itself, iterating over the array elements.
My SplitString() function looks like this:
void SplitString(char str[], int split_size, int size) {
int parts = size / split_size;
for (int i = 0; i < parts; i++) {
for (int j = 0; j < split_size; j++) {
j = split_size * i;
cout << str[j];
}
cout << endl;
}
}
Is there an easier way to do this? I know in Python, you can use the arr[1:] to grab a range of elements from the array. Is there anything similar in C++? Is there some flaw in my logic? Is there something wrong with my code?
cout comes with a write function that takes a pointer and a size argument.
for (int i = 0; i < parts; i++) {
cout.write (str+i*split_size, split_size)
cout << endl;
}
Note that the code above does not check if the string is actually long enough. If the total size is not equal the split_size times a whole number, you will have to add an additional check.
Also, note that this:
int size = sizeof(str) / sizeof(str[0]);
can be written as:
int size = sizeof(str);
instead because the size of a char is always 1.
You can use std::string for this. Alternatively, if your compiler supports C++17, you can use std::string_view as the first argument of SplitString to avoid unnecessary copying.
#include <algorithm>
#include <iostream>
#include <string>
void SplitString(std::string s, std::size_t split_size)
{
while(!s.empty())
{
auto size = std::min(split_size, s.size());
std::cout << s.substr(0, size) << '\n';
s = s.substr(size, std::string::npos);
}
}
int main()
{
char str[] = "A string to be split into given number of parts";
int split_size = 5;
SplitString(str, split_size);
return 0;
}
Live example.
I have to count the vowels of evey word in a given text. My attempt :
#include <iostream>
#include <string.h>
using namespace std;
char s[255], *p, x[50][30];
int c;
int main()
{
cin.get(s, 255);
cin.get();
p = strtok(s, "?.,;");
int n = 0;
while (p)
{
n++;
strcpy(x[n], p);
p = strtok(NULL, "?.,;");
}
for (int i = 1; i <= n; i++)
{
c = 0;
for (int j = 0; j < strlen(x[i]); j++)
if (strchr("aeiouAEIOU", x[i][j]))
c++;
cout << c << " ";
}
return 0;
}
PS: I know that my code is a mix between C and C++, but this is what I am taught in school.
Case closed in the comments.
However, for the fun, I propose you another variant that avoids to use the terrible strtok(), doesn't require a risky strcpy(), and processes each input character only one.
As you are bound to your teacher's mixed style and apparently are not supposed to use c++ strings yet, I also respected this constraint:
const char separators[]=" \t?.,;:"; // I could put them in the code directly
const char vowels[]="aeiouyAEIOUY"; // but it's for easy maintenance
int vowel_count=0, word_count=0;
bool new_word=true;
char *p=s;
cout << "Vowels in each word: ";
do {
if (*p=='\0' || strchr(separators,*p)) {
if (!new_word) { // here, we've reached the end of a word
word_count++;
cout << vowel_count << " ";
vowel_count = 0;
new_word=true;
} // else it's still a new word since consecutive separators
}
else { // here we are processing real chars of a word
new_word=false; // we have at least on char in our word
if (strchr(vowels, *p))
vowel_count++;
}
} while (*p++); // It's a do-while so not to repeat the printing at exit of loop
cout << endl<<"Words: "<<word_count<<endl;
Demo
This is my solution:
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
char s[255];
int n,i,counter=0;
cin.get(s,255);
for(i=0; i<=strlen(s)-1; i++)
if(s[i]=='a' || s[i]=='e' || s[i]=='i' || s[i]=='o' || s[i]=='u') counter++;
cout<<counter;
return 0;
}
If you have a vowel( a, e, i, o or u) you are adding up to the counter.
You can also use strchr but this is a more simple, understandable method.
I have to find the minimum and maximum value of elements in a array using divide and conquer. I have written a code but it is not working for more then 6 elements in array. I don't know whats the problem
#include<iostream>
using namespace std;
int minimum=999,maximum,mi,ma;
void result(int mi,int ma)
{
if(maximum<ma)
{
maximum=ma;
}
if(minimum>mi)
{
minimum=mi;
}
}
void maxmin(int arr[],int i,int j)
{
cout<<" i ="<<i<<" j= "<<j<<endl;
if(i==j)
{
mi=ma=arr[i];
result(mi,ma);
}
else if(i==j-1)
{
if(arr[i]>arr[j])
{
ma=arr[i];
mi=arr[j];
}
else
{
mi=arr[i];
ma=arr[j];
}
result(mi,ma);
}
else
{
int mid=i+j/2;
maxmin(arr,i,mid);
maxmin(arr,mid+1,j);
}
}
int main()
{
int arr[10],n;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>arr[i];
}
maxmin(arr,0,n-1);
cout<<" max "<<maximum<<" min "<<minimum<<endl;
return 0;
}
Your code has a few mistakes
Your code reads n from the user input, but you provided only 10 sized array, and user can try to input 10+ numbers, so we will have an undefined behavior in that case.
You write it very bad and unreadable. If you want somebody else to read your code, check in the your favourite book or in the internet information about how to write beautiful and readable code.
You implemented that algorithm yourself. It is a bad habit, use the standard library algorithms and you will not encounter such mistake.
.
#include <iostream> // std::cin, std::cout
#include <cstddef> // std::size_t
#include <algorithm> // std::min_element, std::max_element
int main ()
{
std::size_t array_size;
std::cin >> array_size;
int *some_array = new int[array_size]; // Allocate memory dynamically
for(std::size_t i = 0; i < array_size; ++i)
{
std::cin >> some_array[i];
}
/* Standard library operate on iterators, they are special classes
* that have interface that is similar in many cases to pointers (so we can use pointers as iterators).
* std::min/max_element needs one iterator for the sequence beginning
* and one iterator after the end. It returns iterator to a found element.
*/
int min = *std::min_element(some_array, some_array + array_size);
int max = *std::max_element(some_array, some_array + array_size);
delete[] some_array;
std::cout << "Min = " << min << std::endl << "Max = " << max;
std::cout << std::endl;
}
Code isn't well written and first dry run your code, you will find the problem easily.
Change
else
{
int mid=i+j/2;
maxmin(arr,i,mid);
maxmin(arr,mid+1,j);
}
To
else
{
int mid=(i+j)/2; /*** Adding brackets ***/
maxmin(arr,i,mid);
maxmin(arr,mid+1,j);
}
And check the logic for calling the result function (because according to your logic the two subsets are individually calculating MIN and MAX in itself not in whole array)
I know that you probably gona again vote me down, I really don't understand this but im really stuck at something and cant figure it out , there is no such information anywhere in the web , neither in my book for the course, so I have this assignment where I need make 2 sums of containers where the difference between 2 sums is the lowest , so the program is done is working perfectly calculated everything however , in my assignment:
The user enter on one row unkwonw length numbers so after that I do all kind of sums between them and find the one with lowest difference between.
Ok but the way I wrote the code I use one while(true) so that to work with infinity testcases(as from assignment) and in this while(true) I have another while(cin>>(SOMEINT)) loop and push it back in a vector , and after it reads new line it just break the wile and continue with the calculation.
However in our test software this one give runtime error since after finding some cases then it start print infinity 0 0 since there is nothing to enter but the while(true) just continues.
I mean I just want to make it that way that the while is till user enters something , for instance you enter 30 50 90 it will return 80 90 , then wiat for another entry and so on.
CODE:
#include <iostream>
#include <string>
#include<vector>
#include <sstream>
#include <cmath>
#include <string.h>
#include <stdio.h>
#include <climits>
using namespace std;
const int length = 17000;
int power(int x){
int sum =2;
for(int i = 0;i<x;i++) {
sum *= 2;
}
return sum;
}
bool ison(int i,int x)
{
if((i>>x) & 1)return true;
return false;
}
int main()
{
while(true){
vector<int> Vec;
int cur = 0;
while (cin >> cur) {
Vec.push_back(cur);
if (cin.get() == '\n') {
break;
}
}
int * sumOfarr1 = new int[length];
int * sumOfarr2 = new int[length];
for(int i = 0; i<length;i++){
sumOfarr1[i] = 0;
}
for(int i = 0; i<length;i++){
sumOfarr2[i] = 0;
}
int index=0;
for(int i=1;i<length;i++)
{
for(int j=0;j<Vec.size();j++)
{
if(ison(i,j))
{
sumOfarr1[index]+=Vec[j];
}
else
{
sumOfarr2[index]+=Vec[j];
}
}index++;
}
int ans=INT_MAX;
int ii;
for(int i=0;i<index;i++)
{
if(abs(sumOfarr1[i]-sumOfarr2[i])<ans)
{
ii=i;
ans=abs(sumOfarr1[i]-sumOfarr2[i]);
}
}
if(sumOfarr1[ii]<sumOfarr2[ii]){
cout << sumOfarr1[ii] << " " << sumOfarr2[ii];
}
else{
cout << sumOfarr2[ii] << " " << sumOfarr1[ii];
}
cout << endl;
delete[] sumOfarr1;
delete[] sumOfarr2;
Vec.clear();
}
return 0;
}
Yes I found the solution just using getline and stringstream.
aka this
vector<int> Vec;
string line;
while(getline( cin, line ))
{
istringstream iss( line );
int number;
while( iss >> number )
Vec.push_back(number);
}
im creating a hangman game that has to use CHAR and not strings. I was wondering how i would choose a single random word form a Char array and display it to the console as a symbol e.g. ****** instead of the word. My current array; Thank you.
char words [6][10] =
{
"Pistachio",
"Avocado",
"Salami",
"Bologna",
"Christmas",
"Giraffes",
};
This is what i have so far (i know it not much im a bit confused)
cout <<"Test " <<words <<endl;
and that just out put a random number ??
To output a cstring from an array of cstrings you need to provide the index of that string.
cout <<"Test " <<words <<endl;
Will just print the address of the first element of the array since that is what an array name is reduced to. So the correct way to display from the array is:
cout <<"Test " <<words[indexOfTheStringYouWant] <<endl;
words is a char** an array of char[10]. The << operator knows how to print simple types (int, float), std::string and char *, but not char ** arrays nor pointers to C strings (char arrays). So it only print the address of the array of char *. char[10]
I think that what you want is :
for (int i=0; i< sizeof(words)/sizeof(char *); i++) cout << words[i] << " ";
cout << endl;
If I have understood correctly what you need is the following
#include <iostream>
#include <algorithm>
#include <numeric>
#include <cstdlib>
#include <ctime>
int main()
{
const size_t N = 6;
const size_t M = 10;
char words[N][M] =
{
"Pistachio",
"Avocado",
"Salami",
"Bologna",
"Christmas",
"Giraffes",
};
size_t index[N];
std::iota( index, index + N, 0 );
std::srand( ( unsigned int )std::time( nullptr ) );
std::random_shuffle( index, index + N );
for ( size_t i = 0; i < N; i++ ) std::cout << words[index[i]] << std::endl;
return 0;
}
The program output might look like
Giraffes
Bologna
Pistachio
Avocado
Salami
Christmas
I think you are looking for this:
#include<cstdlib>
int v;
for(int i=0; i<10; i++)
{
v = rand() %6;
printf("%s\n", words[v]);
}