Finding a Pair of character in a string [duplicate] - c++

This question already has answers here:
Counting the number of occurrences of a string within a string
(5 answers)
Closed 2 years ago.
#include<bits/stdc++.h>
using namespace std;
int main(){
int t;
cin >> t;
while(t--){
int count = 0;
vector<string> v;
string resp;
cin >> resp;
v.push_back(resp);
for(int i = 0; i < v.size(); i++){
if(find(v.begin(), v.end(), "xy") != v.end()){
count++;
}
cout << count << endl;
}
return 0;
}
I want to find the character "xy" in the string for multiple test cases.
For input xy, my count value outputs correctly as 1.
But for the input xyxxy instead of 2 it gives the value as 0
It is only finding the value once but i want to check the count of xy in whole string
I tried to use the substring function as well but it failed to work

I don't get the idea of while loop but that worked for me.
#include <iostream>
#include <vector>
int main()
{
std::string str;
std::cin >> str;
int count = 0;
for (int i(0); i < str.size()-1; ++i)
{
if ((str[i] == 'x') && (str[i + 1] == 'y'))
{
++count;
}
}
std::cout << count;
}

You're looking for "xy" within a vector of strings, which in your example, has a single element, "xyxxy". Since "xy" is not equal to "xyxxy", you're not finding any matches.
But even if you tried to std::find "xy" within "xyxxy" itself - that would fail too, since std::find looks for a single element within a range (or rather, iterator pair).
Instead, you can use the string::find() method, as described here; or, as the case may be, std::string_view::find():
#include <string>
#include <vector>
#include <iostream>
#include <string_view>
int main() {
const std::string needle{"xy"};
std::string haystack;
std::cin >> haystack;
std::size_t count{0};
std::string_view remainder{haystack};
while(true) {
auto first_pos = remainder.find(needle);
if (first_pos == std::string_view::npos) { break; }
count++;
remainder = remainder.substr(first_pos+needle.length());
}
std::cout << "Found " << count << " occurrences of \"" << needle << "\"\n";
}
Note: This does not account for overlapping occurrences. If you want those, you could either always increase the starting position by just 1; or make your solution more complex by employing something Boyer-Moore or Knuth-Morris-Pratt search (see String search algorithms), and resuming it at the correct state after each occurrence found.

Related

Trouble with strings and arrays

My goal is to make a program that inputs a phone number and outputs it in a standard format. It skips over any non-number characters, will output if there are not enough digits, and will also skip over any digits after the first ten digits. My raptor worked without a hitch, but it's been difficult to translate it to C++.
I am using Microsoft Visual Studio.
The problem is it is not running. If I put in anything more then one number in, I receive a fail error.
I am having some difficulty running this code.
Any and all help and advice would be greatly appreciated.
#include <iostream>
#include <string>
using namespace std;
void format(char outArray[], string inNumber)
{
outArray[0] = '(';
outArray[4] = ')';
outArray[5] = ' ';
outArray[9] = '-';
outArray[1] = inNumber[0];
outArray[2] = inNumber[1];
outArray[3] = inNumber[2];
outArray[6] = inNumber[3];
outArray[7] = inNumber[4];
outArray[8] = inNumber[5];
outArray[10] = inNumber[6];
outArray[11] = inNumber[7];
outArray[12] = inNumber[8];
outArray[13] = inNumber[9];
}
int main()
{
string phone, inNumber;
cout << "Please enter a phone number: ";
cin >> phone;
int index = 0;
int num = 0;
char outArray[14];
for (index; phone[index] >= '0' && phone[index] <= '9'; index++)
{
inNumber[num] = phone[index];
num++;
}
if (inNumber.size() > 10)
{
format(outArray, inNumber);
cout << "The properly formatted number is: ";
cout << outArray;
}
else {
cout << "Input must contain at least 10 digits." << endl;
}
system("pause");
return 0;
}
A few things to note:
Use std::string instead array of char array.
You do not need to check charters using a for loop unless you are not sure about the input(phone). However, if that's the case, use std::getline() to get the input and parse as follows using a range-based for loop.
You can use std::isdigit to check the character is a digit.
My goal is to make a program that inputs a phone number and outputs it
in a standard format. It skips over any non-number characters, will
output if there are not enough digits, and will also skip over any
digits after the first ten digits.
That means the number should have a minimum length of 10. Then the
if statement should be if (inNumber.size() >= 10)
Need a pass by ref call in the function format(), since you want to change the content of outArray. Additionally, inNumber could be a
const ref, since we do not change this string.
Updated code: (See a sample code online)
#include <iostream>
#include <string>
#include <cstddef> // std::isdigit, std::size_t
void format(std::string& outArray, const std::string& inNumber) /* noexcept */
{
for (std::size_t index = 0; index < 10; ++index)
{
if (index == 0) outArray += '(';
else if (index == 3) outArray += ") ";
else if (index == 6) outArray += '-';
outArray += inNumber[index];
}
}
int main()
{
std::string phone;
std::cout << "Please enter a phone number: ";
std::getline(std::cin, phone);
std::string inNumber;
for (char letter : phone)
if (std::isdigit(static_cast<unsigned char>(letter))) // check the letter == digits
inNumber += letter;
if (inNumber.size() >= 10)
{
std::string outArray;
format(outArray, inNumber);
std::cout << "The properly formatted number is: ";
std::cout << outArray;
}
else {
std::cout << "Input must contain at least 10 digits." << std::endl;
}
return 0;
}
inNumber[num] = phone[index]; //undefined behavior.
You cannot subscript inNumber now, since its capacity is 0, thus it can not store or access any element here.
You may need to use string's constructor whose parameter has a size_t type or string::reserve or string::resize.
And I'm happy to see cppreference get more complete now, learn to use it: http://en.cppreference.com/w/cpp/string/basic_string
BTW, this function won't do anything you want to:
void format(char outArray[], string inNumber)
maybe you'd like to have an signature like this?
void format(char outArray[], string& inNumber)

Can't stop reading lines in c++

The following code is for a homework assignment due on 17 October. The problem states to "write a program with a loop that lets the user enter a series of numbers. After all the numbers have been entered, the program should display the largest and smallest numbers entered."
#include "stdafx.h"
#include <algorithm>
#include <array>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
using namespace std;
bool isNumeric(string aString)
{
double n;
istringstream is;
cin >> aString;
is.str(aString);
is >> n;
if (is.fail())
{
return false;
}
return true;
}
vector<double> limits(vector<double> a)
{
// Returns [min, max] of an array of numbers; has
// to be done using std::vectors since functions
// cannot return arrays.
vector<double> res;
double mn = a[0];
double mx = a[0];
for (unsigned int i = 0; i < a.size(); ++i)
{
if (mn > a[i])
{
mn = a[i];
}
if (mx < a[i])
{
mx = a[i];
}
}
res.push_back(mn);
res.push_back(mx);
return res;
}
int main()
{
string line = " ";
vector<string> lines;
vector<double> arr;
cout << "Enter your numbers: " << endl;
while (!line.empty() && isNumeric(line))
{
getline(cin >> ws, line);
if (line.empty() || !isNumeric(line))
{
break;
}
lines.push_back(line);
transform(line.begin(), line.end(), line.begin(), [](char32_t ch) {
return (ch == ' ' ? '\000' : ch);
}); // Remove all spaces
arr.push_back(atof(line.c_str()));
}
vector<double> l = limits(arr);
cout << "\nMinimum: " << l[0] << "\nMaximum: " << l[1] << endl;
return 0;
}
The above code is what I have. However, it's not always outputting the correct maximum value and only outputs "0" for the minimum value. I can't seem to find what's wrong with this so if anyone could help that would be great.
For the minimum, your problem appears to be with the fact that in your limits() function, you initialize the value of min to 0. So if you have an array of [1, 2, 3, 4], it will check each element and, seeing that none of them is less than 0, leave 0 as the minimum. To fix this, you can set the initial value of mn to the first element of the array. Note that you will have to check to make sure the array has at least one element to avoid a possible overflow error.
For the maximum, I'm not sure what kind of inconsistencies you're having, but if your array only contained negative values, you would have the same problem as with minimum, where the initial value is higher than any of the actual values.

Searching substrings

I am a programming student. I have been asked to write a program that searches for a substring of another string, but I am not suppose to use the find() function that is provided in the string class. The code I have written thus far works, but it uses the find() function. How can I change this to not use the find function and still give me the location of the substring? Here is my code:
#include <iostream>
#include <string>
using namespace std;
int f_r(string, string);
int main()
{
string s;
string t;
cout << "\nEnter the string to be searched: ";
getline(cin,s);
cout << "Now enter the string you want to search for: ";
cin >> t;
if (f_r(s,t) == 0)
{
cout << "\n Substring could not be found.";
}
else
{
cout << "\nThe index of substring is = " << f_r(s,t) << endl;
}
system("PAUSE");
return 0;
}
int f_r(string str, string c)
{
int pos = 0;
pos = str.find(c, pos);
if (pos > str.length())
{
return 0;
}
else
{
pos++;
return pos - 1;
}
}
You need to search for matches within the string ONE character at a time, i.e. seeing the strings as if they were arrays of characters (since you're apparently working in C/C++ that is quite convenient since string and char[] are synonymous).
You will likely need to maintain indexes or pointers into the current location in both strings..
This will be the naive / initial approach, and when you get that working rather well, assuming you are a bit curious, you'll start wondering if there are more efficient ways of doing so, for example by skipping some characters in some cases, or by using general statistics about text in the underlying languages.
This art may help:
|_|_|_|_|_|_|_|_|_|_|_|
^ ^
i i+j
|
|_|_|_|_|
^
j
int search(char *a,char *b)
{
int i=0,j=0,k=0,m,n,pos;
m=strlen(a);
n=strlen(b);
while(1)
{
while((a[i]==b[j]) && b[j]!=0)
{
i++;
j++;
}
if (j==n)
{
pos=i-j;
return(pos);
}
else
{
i=i-j+1;
j=0;
}
}}
I have this code with me. I hope it will help you.
Note:- its an old code

C++ Identifying the Frequency of words occurring in a sentence

What is the best STL to use for this task? I've been using Map,
and I couldn't get it to work. I'm not sure how I am supposed to check the number of same words that occur in the sentence for example:
I love him, I love her, he love her.
So I want the program to prompt the user to enter an integer, lets say i enter 3, the output will be love as the same word occurs 3 times in the sentence. But what method to use if I want to do a program like this?
Currently my program prompts for the user to enter the word, and then it shall return how many time that word occurs, which for word love, is 3. but now i want it the other way round. Can it be done? Using which STL will be better?
I assume you use a map to store the number of occurrences.
Well,you first have to understand this,since you are using a map,the key is unique while the stored data may not be unique.
Consider a map, x
with contents
x["I"]=3
x["Love"]=3
x["C"]=5
There is unique a mapping from the key to the value,and not the other way round,if you want this one to one mapping ,i would suggest a different data structure.If you want to use map,and still search for an element,using STL search function or your own.Or you can write your search function.
search().
map<string,int>::iterator ser;
cin>>check;
for(ser=x.begin();ser!=x.end();++ser)
{
if(ser->second==check)
{
cout<<"Word"<<ser->first<<endl;
break;
}
}
First build the mapping from word to count and then build the reverse multi-mapping from that. Finally, you can determine which words occur with a given frequency:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <map>
#include <set>
#include <sstream>
#include <string>
#include <utility>
int main()
{
std::string str("I love him, I love her, he love her");
std::istringstream ss(str);
std::istream_iterator<std::string> begin(ss);
std::istream_iterator<std::string> end;
std::map<std::string, int> word_count;
std::for_each(begin, end, [&](const std::string& s)
{
++word_count[s];
});
std::multimap<int, std::string> count_words;
std::for_each(word_count.begin(), word_count.end(),
[&](const std::pair<std::string, int>& p)
{
count_words.insert(std::make_pair(p.second, p.first));
});
auto its = count_words.equal_range(3);
std::for_each(its.first, its.second,
[](const std::pair<int, std::string>& p)
{
std::cout << p.second << std::endl;
});
}
/******************************************************************
Name : Paul Rodgers
Source : HW1.CPP
Compiler : Visual C++ .NET
Action : Program will read in from standard input and determine the
frequency of word lengths found in input. An appropriate
table is also displayed. Maximum word length is 15 characters
words greater then 15 are counted as length 15.
Average word length also displayed.
Note : Words include hyphenated and ones with apostrophes. Words with
apostrophes, i.e. Jim's, will count the apostrophe as part of the
word length. Hyphen is counted if word on same line, else not.
Also an int array is used to hold the number of words with
length associated with matching subscript, with subscript 0
not being used. So subscript 1 corresponds to word length of 1,
subscript 2 to word length of 2 and so on.
------------------------------------------------------------------------*/
#include <iostream>
#include <ctype.h>
#include <iomanip>
using namespace std;
int NextWordLength(void); // function prototypes
void DisplayFrequencyTable(const int Words[]);
const int WORD_LENGTH = 16; // global constant for array
void main()
{
int WordLength; // actual length of word 0 to X
int NumOfWords[WORD_LENGTH] = {0}; // array holds # of lengths of words
WordLength = NextWordLength();
while (WordLength) // continue to loop until no word, i.e. 0
{ // increment length counter
(WordLength <= 14) ? (++NumOfWords[WordLength]) : (++NumOfWords[15]);
WordLength = NextWordLength();
}
DisplayFrequencyTable(NumOfWords);
}
/********************** NextWordLength ********************************
Action : Will determine the length of the next word. Hyphenated words and
words with apostrophes are counted as one word accordingly
Parameters : none
Returns : the length of word, 0 if none, i.e. end of file
-----------------------------------------------------------------------*/
int NextWordLength(void)
{
char Ch;
int EndOfWord = 0, //tells when we have read in one word
LengthOfWord = 0;
Ch = cin.get(); // get first character
while (!cin.eof() && !EndOfWord)
{
while (isspace(Ch) || ispunct(Ch)) // Skips leading white spaces
Ch = cin.get(); // and leading punctation marks
if (isalnum(Ch)) // if character is a letter or number
++LengthOfWord; // then increment word length
Ch = cin.get(); // get next character
if ((Ch == '-') && (cin.peek() == '\n')) //check for hyphenated word over two lines
{
Ch = cin.get(); // don't count hyphen and remove the newline char
Ch = cin.get(); // get next character then on next line
}
if ((Ch == '-') && (isalpha(cin.peek()))) //check for hyphenated word in one line
{
++LengthOfWord; // count the hyphen as part of word
Ch = cin.get(); // get next character
}
if ((Ch == '\'') && (isalpha(cin.peek()))) // check for apostrophe in word
{
++LengthOfWord; // count apostrophe in word length
Ch = cin.get(); // and get next letter
}
if (isspace(Ch) || ispunct(Ch) || cin.eof()) // is it end of word
EndOfWord++;
}
return LengthOfWord;
}
/*********************** DisplayFrequencyTable **************************
Action : Will display the frequency of length of words along with the
average word length
Parameters
IN : Pointer to array holding the frequency of the lengths
Returns : Nothing
Precondition: for loop does not go beyond WORD_LENGTH
------------------------------------------------------------------------*/
void DisplayFrequencyTable(const int Words[])
{
int TotalWords = 0, TotalLength = 0;
cout << "\nWord Length Frequency\n";
cout << "------------ ----------\n";
for (int i = 1; i <= WORD_LENGTH-1; i++)
{
cout << setw(4) << i << setw(18) << Words[i] << endl;
TotalLength += (i*Words[i]);
TotalWords += Words[i];
}
cout << "\nAverage word length is ";
if (TotalLength)
cout << float(TotalLength)/TotalWords << endl;
else
cout << 0 << endl;
}
#include<iostream>
#include<string>
#include<vector>
#include<cstddef>
#include<map>
using std::cout;
using std::cin;
using std::string;
using std::endl;
using std::vector;
using std::map;
int main() {
cout << "Please enter a string: " << endl;
string str;
getline(cin, str, '\n');
size_t str_len = str.size();
cout << endl << endl;
size_t i = 0, j = 0;
bool pop = false;
map<string, int> myMap;
for (size_t k = 0; k < str_len-1; k++) {
if (((k == 0) && isalpha(str[0])) || (!(isalpha(str[k-1])) && isalpha(str[k])))
i = k;
if ( isalpha(str[k]) && !(isalpha(str[k+1])) ) {
j = k;
pop = true;
}
if ( (k == str_len-2) && isalpha(str[k+1]) ) {
j = k+1;
pop = true;
}
if ( (i <= j) && pop ) {
string tmp = str.substr(i, j-i+1);
cout << tmp << '\t';
myMap[tmp]++;
pop = false;
}
}
cout << endl << endl;
map<string, int>::iterator itr, end = myMap.end();
for (itr = myMap.begin(); itr != end; itr++)
cout << itr->first << "\t - - - - - \t" << itr->second << endl;
cout << endl;
return 0;
}

Palindrome program isn't comparing properly

I'm currently learning about vectors and trying to make a palindrome program using them. This is a simple program and so far, I'm trying to make it identify "I am what am I." as a palindrome properly. This is my program so far:
#include <vector>
#include <string>
#include <iostream>
using namespace std;
vector <string> sentVec;
void getSent(string sent);
void readBackwards(string sent);
int main()
{
string sent;
getSent(sent);
readBackwards(sent);
return 0;
}
void getSent(string sent)
{
cout << "Enter your sentence:" << endl;
getline (cin,sent);
string currentWord, currentLetter;
for (int i = 0; i < sent.length(); i++)
{
currentLetter = sent[i];
if (currentLetter == " ") // inserts word
{
currentWord += sent[i];
sentVec.push_back(currentWord);
currentWord = "";
}
else if (currentLetter == ".") // inserts period
{
sentVec.push_back(currentWord);
currentWord = sent[i];
sentVec.push_back(currentWord);
}
else
{
currentWord += sent[i];
}
}
}
void readBackwards(string sent)
{
string sentForwards, sentBackwards;
// create sentence forwards and backwards without the period.
for (int i = 0; i < sentVec.size() - 1; i++)
{
sentForwards += sentVec[i];
}
for (int j = sentVec.size() - 2; j >= 0; j--)
{
sentBackwards += sentVec[j];
if (j == sentVec.size() - 2)
{
sentBackwards += " ";
}
}
cout << "Sentence forwards is: " << sentForwards << endl;
cout << "Sentence backwards is: " << sentBackwards << endl;
if (sentForwards == sentBackwards)
{
cout << "This sentence reads the same backwards as forwards." << endl;
}
else
{
cout << "This sentence does not read the same backwards as forwards." << endl;
}
}
When I run this program, it prints:
Enter your sentence:
I am what am I.
Sentence forwards is: I am what am I
Sentence backwards is: I am what am I
This sentence does not read the same backwards as forwards.
Why does this not trigger the if loop when comparing the two sentences?
Because sentBackwards isn't the same as sentForwards, because sentBackwards has a trailing whitespace at the end, and thus they aren't the same.
I am unsure how your program detects palindromes, but here is a simple iterative method:
#include <string>
bool isPalindrome(std::string in) {
for (int i = 0; i < in.size() / 2; i++) {
if (in[i] != in[in.size() - 1 - i]) {
return false;
}
}
return true;
}
It returns true if the string passed as an argument is a palindrome
You should not only learn about vector, but also the STL algorithm functions such as std::reverse.
As the other answer given pointed out, one vector has a trailing whitespace. You could have avoided all of that by simply taking the original vector, copying it to another vector, and calling std::reverse. There is no need to write a loop:
void readBackwards()
{
// copy the vector
std::vector<std::string> sentBackwards = sentVec;
// reverse it
std::reverse(sentBackwards.begin(), sentBackwards.end());
// see if they're equal
if (sentVec == sentBackwards)
cout << "This sentence reads the same backwards as forwards." << endl;
else
cout << "This sentence does not read the same backwards as forwards." << endl;
}
This works, since std::vector has an overloaded operator == that compares the items in each of the two vectors and returns true if all items are the same.
In addition to this, reading into a vector can be accomplished much more easily than what you attempted.
#include <sstream>
#include <algorithm>
//...
void getSent(string sent)
{
// remove the periods(s)
auto iter = std::remove_if(sent.begin(), sent.end(), [] (char ch) { return ch == '.';});
sent.erase(iter, sent.end());
// copy the data to a vector
std::istringstream iss(sent);
string currentword;
while ( iss >> currentword)
sentVec.push_back(currentword);
}
Note that we use the std::istringstream to serve as the space delimited parser, alleviating the need to write a loop looking for the space. Also, the std::remove_if algorithm is used to remove any period characters from the string before we start to store the individual strings into a vector.
So basically, the only loop in this whole setup is the while to read from the stream into the vector. Everything else is accomplished by using the algorithm functions, and taking advantage of the various member functions of std::vector (like the overloaded ==)