Count matches in an array - c++

I can't figure out how to do this.
The question: Implement the function
int count_matches(const string arr[], int size, string query);
Return the number of strings in the array that are equal to query or
-1 if size if less than 0.
My answer:
#include <iostream>
#include <cmath>
#include<string>
using namespace std;
int count_matches(const string arr[], int size, string query){
int i = 0;
int numMatches;
for (;i<size;i++) {
if (string[i] == (string[i]+1)){
numMatches++;
}
}
return numMatches;
}
int main(){
string selection;
const string array[4]={"dog", "cat", "dog", "dog"};
cout<<"which animal do you want?"<<endl;
cin>> selection;
cout<< "there are " << count_matches(array, 4, selection)<< " matches"<<endl;
return 0;
}
What is wrong?

int count_matches(const string arr[], int size, string query){
int numMatches(0);
for (int i=0; i<size; ++i)
{
if (arr[i] == string)
{
++numMatches;
}
}
return numMatches;
}
This should be a solution to your problem but you will never learn anything from gaining the answer this way. I'd advise reading this tutorial on arrays and loops to better understand how to tackle the problem next time.

Once you get your code to compile, you need to look carefully at this block:
if (string[i] == (string[i]+1)) {
numMatches++;
}
What do you actually want to compare here? string is a type. Take another look at the arguments that you pass into the function and that should make it clear.
Then, once you have a match, you increment numMatches. But what value does this have to start with? What value should it have to start with?
Note that std::count() does exactly what your count_matches() function should do:
std::count(array, array + 4, selection)
This will probably not statisfy whomever marks your homework, but it is worth playing with and learning if you want to advance your C++ skills.
Good luck!

Related

Logical Issue or Syntax issue with sorting String function

I'm new to C++ and coding in general. I'm attempting to make a simple program that essentially takes in two words and will tell you if these two words are anagrams or not.I also understand that there is likely a pre-made function to sort a string, like an array however I am trying to grasp the concept itself and hence why I'm attempting to make the function.
Here is a quick snippet of the code I've written so far.
Snippet of code
The issue that I'm currently having is that when I call the function to sort the string, the string isn't sorted! Sorry if there is a simple solution to this, I'm fairly new. Is this a logical issue or syntax based? Thank you so much!
#include <iostream>
#include <string>
using namespace std;
//Function Declarations
string sortString(string user_input);
//Program Body
int main()
{
string user_input_one, user_input_two;
cout << "Welcome to Sandip's Anagram Checker! \nPlease Input two words that you'd like the check!";
sortString(user_input_one);
sortString(user_input_two);
if (user_input_one == user_input_two)
cout << "These two words are Anagrams of each other!";
else
cout << "These are not Anagrams!";
return 0;
}
//Function Definations
string sortString(string user_input)
{
string temp_string = user_input;
int i,j;
for (i = 0; i<user_input.length();i++)
{
for (j=0; j<user_input.length();j++)
{
if (user_input[i] == user_input[j])
{
temp_string[i] = user_input[j];
}
else if (user_input[i] > user_input[j])
{
temp_string[i] = user_input[j];
}
else if (user_input[i] < user_input[j])
{
temp_string[i] = user_input[i];
}
}
}
return temp_string;
}
Adding to Daniel's answer, you don't need a temporary string in the sorting function, just process the passed string and return it. Also consider supporting letter cases as well, you can use std::transform from the STL algorithm library.
#include <algorithm>
Add this before looping in your sorting function or after taking inputs in main.
transform(user_input.begin(), user_input.end(), user_input.begin(), ::tolower);
There are a couple issues. You're not actually reading any user input. You can fix this by adding cin >> user_input_one >> user_input_two;.
Your sorting also doesn't work quite right. It looks similar to selection sort, so I tweaked it to be a variation of that. For each character in the string, it goes through the rest of the string and swaps letters if the later one should be first.
string temp_string = user_input;
int i, j;
for (i = 0; i < user_input.length(); i++)
{
for (j = i + 1; j < user_input.length(); j++)
{
if (temp_string[j] < temp_string[i]) {
swap(temp_string[i], temp_string[j]);
}
}
}
return temp_string;
Lastly, as #cigien commented, you aren't using the sorted result. You can change this by replacing your lines calling sortstring() with this:
user_input_one = sortString(user_input_one);
user_input_two = sortString(user_input_two);

error: variable or field 'Palindrome' declared void in c++

I'm getting this error hence I am new to c++ I could not understand
please help me!!!
I am writing a palindrome code
This is the code given below:.............
I am basically here using some extra concepts not doing in-direct fashion.
if anyone can post the correct code he/she is most welcome...
//palindrome
#include <cstring> //or use #include <string.h>
#include <iostream>
using namespace std;
void Palindrom(string& );
void Palindrome(string& word)// same as (const string& word)
{
int n = word.length();
string word2;
char reverse[n];
for(int i = 0; i <=n; i++){
word[i]=tolower(word[i]);
}
word2=word; //now both are small
for(int i = n-1; i >=0; i--){
reverse[n-1-i]=word2[i];
cout<<reverse[n-1-i];
}
for(int i =0; i >n; i++){ //printing reversed
cout<< " Reverse: "<<reverse[i]<<endl;
}
// word is ok and word2 gets reversed
for (int i = 0; i <= n; i++){
if(word[i]==reverse[i])
{
cout<<"\nit is palandrome ";
}
cout<<"\nit is not a palindrome ";
}
}
int main()
{ string k="YuUuy";
void Palindrome(k);
return 0;
}
Correct syntax for calling a function is Palindrome(k); without the void.
Few remarks:
Get a good c++
book.
// same as (const string& word) is not true.
You did not include <string> header.
It's good practice to use std::size_t for indices, but beware of unsigned>=0 condition being always true.
char reverse[n]; is wrong, n must be a compile-time constant, VLA are not part of the C++ standard.
Function calls should not have return type. Change void Palindrome(k); in main() function to Palindrome(k);
While declaring array, the expression should have constant value. So you can't use char reverse[n];. Change it to char *reverse = new char[n]; and deallocate it using delete[] reverse; after you are done using it.
I would recommend you to use smart pointer. You should also take a look at std::string instead of using stream of char.

Debug my reimplementation of strtok and split

I'm supposed to be writing code that takes a string of comma separated values without spaces (ex. my,name,is,jack). First we had to write a function
string nextstring(string str, int start_index)
that returns a single "value" from your initial string depending on the start index. The second part of the problem was to write a function
int split(string str, string a[], int max_size)
that will identify all the values in the initial string and put them in a string array and then return the total number of values stored in the array; i.e. if you had initially input my,name,is it would return 3.
My function never returns the correct value and whatever it returns changes depending on what the length of the words are.
#include <iostream>
#include <string>
using namespace std;
string nextstring(string str, int start_index);
int split(string str, string a[], int max_size);
int main()
{
string str;
int cnt;
string a[100];
cout<< "what is your string" << endl;
getline(cin, str);
cnt= split(str, a, 100);
cout << "There are " << cnt << " values in this string" << endl;
for(int i=0; i<cnt; i++)
{
cout << a[i] << endl;
}
return 0;
}
string nextstring(string str, int start_index)
{
string ans;
if(str[start_index] == ',' || str[start_index] == '\0')
{
ans=" ";
}
else{
ans=str[start_index]+nextstring(str, start_index+1);
}
return ans;
}
int split(string str, string a[], int max_size)
{
int j=0;
int ans=0;
double k=0;
while(j<max_size)
{
a[j]= nextstring(str,k);
string check=a[j];
if(isalpha(check[0])!= 0)
{
ans++;
}
k=k+a[j].length();
j++;
}
return ans;
}
It seems that your problem is that while(j<max_size){...} leads to j being incremented up to max_size. The line a[j]= nextstring(str,k); is at some points reading values that are outside your string which is really bad!
Replacing while(j<max_size){...} by while(j<max_size && k<str.length()){...} seems to be enough to make your code work!
Apart from that:
k has no reason to be a double! It should be an int (or something similar).
Since you are already using string, you should also learn to use vector. split is better written as:
int split(string str, vector<string> &a, int max_size)
{
int ans=0;
int k=0;
while(k<str.length())
{
string next = nextstring(str,k);
if(isalpha(next[0])!= 0)
{
ans++;
a.append(next);
}
k += next.length();
}
return ans;
}
The problem in your approach is to identify the end of the string, as there is no null terminator in a c++ string. Consider to update nextstring() to look for the end of string in a different manner:
string nextstring(string str, int start_index)
{
...
if(start_index == str.size() || str[start_index] == ',' ) //<===
{
ans=" ";
}
...
}
online demo
Additional recommendation
Note that it is not very nice to return a blank string when in reality it should be empty to reflect its real value (e.g. ",,"). You have no choice because otherwise you would have no mean in the calling function, to determine that the end of string was reached. But the consequence is thar all your strings have a trailing blank.
When you call recursively the function adding char to build the return string, you risk to have a considerable overhead. You could consider avoiding this, by replacing the else part:
ans=str.substr(start_index, str.find(',', start_index+1)-start_index);
However, as you have no trailing blank anymore, you need to adapt split() so to adapt its way to count the total number of chars parsed:
k=k+a[j].length()+1; // +1 because there's no longer a trailing blank.
Online demo

String array homework

So i have a hw problem for my class where i have to store ten names, capitalize them and then sort them alphabetically. We just started using strings and there are some things that are still a little confusing to me. This code can store all the names in a string array, but the UpperCase seems to not be working. I dont know for sure but i think it is because I have second for loop running cap amount of times, which would be 10. And since not every string will have 10 elements, i'm running into problems?..Is that it or is it something else? Well i tried to fix this by using the .length (function?), to find the length of each name in the array, but I always get errors. Any help is appreciated, thanks!
#include<iostream>
#include<string>
using namespace std;
void UpperCase(string names[],int cap);
void print(string names[],int cap);
void swap(string names[],int &x,int &y);
string names[10];
int main(){
char a;
cout<<sizeof(a);
for(int i=0;i<10;i++){
cout<<"Enter a name for student "<<i+1<<" : ";
cin>>names[i];
cout<<endl;
}
UpperCase(names,10);
cout<<endl;
print(names,10);
cout<<endl;
print(names,10);
return 0;
}
void print(string names[],int cap){
for(int i=0;i<cap;i++)
cout<<names[i]<<endl;
}
void UpperCase(string names[],int cap){
for(int student=0;student<cap;student++){
for(int letter=0;letter<names[student].length();letter++){
if(names[student][letter]>='a')
names[student][letter]-=('a'-'A');
}
}
}
Your inner loop should be iterating for the length of the string. string::length() is a function, not a field, so you need the parentheses. There's also a standard library function for converting a character to upper case.
#include <cctype>
using std::toupper;
void UpperCase(string names[],int cap){
for(int student=0;student<cap;student++){
for(int letter=0;letter<names[student].length();letter++){
names[student][letter] = toupper(names[student][letter]);
}
}
}
..., but the UpperCase seems to not be working
So write a minimal program that just calls UpperCase on known input. It makes it easy to debug, and would also make a much better question. We don't need to see the print or swap to help with that, and prompting the user for input isn't relevant to whether UpperCase works or not.
Having said that, you should use std::string::length() - however, you say
Well i tried to fix this by using the .length (function?), to find the length of each name in the array, but I always get errors
but don't show what you actually tried, or what the errors were.
Here's a minimal, complete and self-contained program, using std::toupper as per T.C.'s answer. I changed it to demonstrate more modern style, and to show there are easier ways to confirm your functions work than to write a whole program and then find out it's broken.
#include <algorithm> // for transform, for_each
#include <cctype> // for toupper
#include <string>
#include <vector> // easier to use (correctly) than bare arrays
// change a string to upper case
void str_toupper(std::string &s) {
std::transform(s.begin(), s.end(),
s.begin(),
[](char c) -> char { return std::toupper(c); });
}
// change a vector of strings to upper case
void vec_toupper(std::vector<std::string>& v) {
std::for_each(v.begin(), v.end(), str_toupper);
}
using namespace std;
int main() {
vector<string> const input = { "bob", "alice cooper", "Eve" };
vector<string> const expected = { "BOB", "ALICE COOPER", "EVE" };
vector<string> working = input;
vec_toupper(working);
return working == expected ? 0 : -1;
// use cout or debugger to solve problem only if program returns nonzero
}

Sorting Arrays/File I/O C++

I was wondering is someone could help me out of sorting this array, I am i little lost on how to exactly implement it in this project. Because it is HW do not reveal the whole answer, but push me towards the right direction. The project is as follows:
Write a program that will read a line of text and output a list of all the letters that occur in the text together with the number of times each letter occurs in the line. End the line with a period that serves as a sentinel value. The letters should be used in the following order: highest to lowest.Assume that the input used all lowercase letters.
A couple questions.
1. Am I going along the right way in sorting the array?
2. Before putting the sorting array into my code, when the code compiles it comes up with a blank screen. Any ways to fix this?
Apologies if this is written poorly, and thanks in advance for the help!
inlcude <iostream>
#inlcude <fstream>
using namespace std;
void initialize(int list[]);
void Sort(int list[],int& num);
void characterCount(char ch, int list[]);
void readText(ifstream& intext, char& ch, int list[]);
void totalCount(int list[]);
int main()
{
int index,letterCount[26];
char ch;
ifstream inFile;
infile.open("C:/temp/Data_Chapter_7_8.txt");
if (!inFile)
{
cout << " Cannot open file." <<endl;
}
initialize(letterCount);
infile.get(ch);
while (inFile)
{
int index;
readText(inFile,ch,letterCount)
index++;
inFile.get(ch);
}
totalCount(index, letterCount);
inFile.close();
system("PAUSE");
return 0;
}
//initializes array letterCount to 0
void initialize(int list[])
{
for(int x = 0;x<26;x++)
list[x] = 0
}
//increments the letter count. Makes sure counting letters.
void characterCount (char ch, int list[])
{
int index;
ch = tolower(ch);
if(static_cast<int>(ch)>=97&&(static_cast<int>(ch)<=122))
letterCount[static_cast<int>(ch)-97]++;
}
void readText(ifstream& intext, char& ch, int list[])
{
while (ch != '.')
{
characterCount (ch,list);
intext.get(ch);
}
}
//displays data
void totalCount(int list[])
{
for(int x=0;x<26;x++)
if(letterCount[x]>0)
cout<<static_cast<char>(x+97)<<" "<<letterCount[x]<<endl;
}
void Sort(int list[],int& num)
{
int i,j,flag = 1;
int temp;
int numLength = num.length();
for (i=1;(i<=numLength)&&flag; i++)
{
flag = 0;
for (j=o; j<(numLength-1);j++0
{
if(num[j+1]>num[j])
{
temp = num[j];
num[j] = num[j+1];
num[j+1]=temp;
flag = 1;
}
}
}
return;
}
Instead of using messy bubble sorts and other fun stuff, we can simply keep track of the number of occurrences of each letter, since there are only 26 possibilities. This should result in a bit cleaner (and much faster) code:
int numOccur[26];
...
for (int i = 0; i < numCh; i ++)
numOccur[letters[i] - 'a'] ++;
for (i = 25; i >= 0; i --)
if (i > 0)
cout<<static_cast<char>(i+97)<<" "<<numOccur[i]<<endl;
Of course, you should replace the for loop with the appropriate file-reading loop.
Just a few comments.
I don't see any good reason for most of the casting here.
Use isalpha, isupper or islower to check for letters, and tolower or toupper to covnert them (Note: using these functions is one of the few justifications for casting).
Probably easiest to initialize your lettercount array with `int lettercount[26] ={0};
Unless you're absolutely required to write your own sort routine, just use std::sort.
It's usually easiest to open a file as you define your ifstream:
std::ifstream infile("whatever");
Don't use while (infile). It's pretty much a guaranteed bug. Do a read, and check whether it succeeded, like: while (infile.get(ch)) ...