C++ Find Frequency of a String in a Vector of Strings - c++

I am currently working on a little mini program that will determine if a vector of 5 strings contains a full house. A full house in my program has a pair of cards and 3 of a kind.
For example: ["A", "A", "A", "K", "K"] would be a full house, while ["10", "J", "10", "10", "10"] would not be one.
I have written my main function such that a user can read the card values into a vector with this code below:
int main()
{
vector<string> hand;
string input;
for (int i = 0; i < 5; i++)
{
cout << "Card " << i + 1 << ": ";
cin >> input;
hand.push_back(input);
}
}
I would like to write a bool function that takes the vector as a parameter and returns true if the vector contains a full house, and false if it does not. My problem is that I am not sure of an efficient way of looping through the vector in the function and finding the frequency of each string to determine if the vector has a full house.
For example, I would like my function to be somewhat like the one below:
bool isFullHouse(vector<string> hand)
{
// loop through vector
// record instance of string in vector
// determine if the string has appeared either 2 times or 3 times in the vector
// if it contains a full house
return true
// else
return false
}
Does anyone have a decent way of achieving this task?

You can use standard algorithms to write the function like this:
bool isFullHouse(vector<string> hand)
{
// put all cards matching the first one at the beginning
auto p = std::partition(hand.begin(), hand.end(),
[first_card = hand[0]] (auto card) {
return first_card == card;
});
// count cards matching the first one
auto num = std::distance(hand.begin(), p);
return (p == 2 or p == 3) // 2 or 3 cards
&& std::equal(hand.begin() + 1, p, hand.begin()) // same card at the beginning
&& std::equal(p + 1, hand.end(), p); // same card at the end
}
Efficiency is not a major concern here since you are dealing with a vector of 5 short strings, but this is an O(n) algorithm. Not that the n is relevant since you only have 5 cards, but all the algorithms used here are O(n).

You can also make your life simple and count the cards . . .
#include <iostream>
#include <unordered_map>
#include <string>
int main() {
// Define container
std::unordered_map<std::string, unsigned int> hand{};
// Read all values and count them
int i{};
for (std::string card{}; (i < 5) and (std::cin >> card); hand[card]++, ++i);
// Show result
std::cout << (((hand.size() == 2) and ((hand.begin()->second == 2) or (hand.begin()->second == 3))) ? "Full House" : "");
}

Related

Anagram of 2 string : I don't understand what is the problem with my code

I have my code which return the smallest integer deletions required to make anagram :
#include <bits/stdc++.h>
using namespace std;
int makeAnagram(string a, string b) {
int count = 0;
for(auto it=a.begin(); it!=a.end(); it++){
if(find(b.begin(), b.end(), *it) == b.end()){
a.erase(it);
count++;
}
}
for(auto it = b.begin(); it != b.end(); it++){
if(find(a.begin(), a.end(), *it) == a.end()){
b.erase(it);
count++;
}
}
return count;
}
And it doesn't work at all, I don't understand why, the main test is :
int main()
{
string a={'a','b','c'};
string b={'c','d','e'};
int res = makeAnagram(a, b);
cout << res << "\n";
return 0;
}
The console is supposed to return 4, but it return 2 instead, and the string a and b have 2 elements at the end of the program, when they should are 1-sized
Problem with your approach is you are deleting the element during the iteration but your not considering the change in the iterator i,e you should first increment iterator then delete the previous element here is simple approach
int makeAnagram(string a, string b) {
int A = a.size();
int B = b.size();
int count = 0;
if (A > B)
{
for (auto i = b.begin(); i != b.end(); i++)
{
size_t t = a.find(*i);
if (t == std::string::npos)
{
count++;
}
else
{
a.erase(a.begin() + t);
}
}
count = count + A - (b.size() - count);
}
else
{for (auto i = a.begin(); i != a.end(); i++)
{
size_t t = b.find(*i);
if (t == std::string::npos)
{
count++;
}
else
{
b.erase(b.begin() + t);
}
}
count = count + B - (a.size() - count);
}
return count;
}
Hm, I thought that I answered this question already somewhere else. But anyway. Lets try again. Important is the algorithm. And I nearly doubt that there is a faster answer than mine below. But, we never know . . .
And, as always, the most important thing is to find a good algorithm. And then, we maybe can do some good coding to get a fast solution. But most important is the algorithm.
Let's start to think about it. Let's start with 2 simple strings
abbccc
abbccc
They are identical, so nothing to erase. Result is 0. But how can we come to this conclusion? We could think of sorting, searching, comparing character by character, but the correct approach is counting the occurence of characters. That is nealy everytime done when talking about Anagrams. So, here we have for each string 1 a, 2 b, 3c.
And if we compare the counts for each character in the strings, then they are the same.
If we remember our -long time ago- school days or C-code, or even better Micro Controller assembler codes, then we know that comparing can be done by subtracting. Example. Let us look at some examples: 6-4=2 or 3-4= -1 or 7-7=0. So, that approach can be used.
Next example for 2 strings:
bbcccddd
abbccc
We already see by looking at it that we need to delete 3*"d" from the first string and one "a" from the second string. Overall 4 deletions. Let's look at the counts:
String a: b->2, c->3 d->3, String b: a->1, b->2, c->3
And, now let's compare, so subtract: a->0-1= -1, b->2-2=0, c->3-3=0, d->3-0=3.
And if we add up the absolute values of the deltas, then we have the result. 3+abs(-1)=4
OK, now, we can start to code this algorithm.
Read 2 source strings a and b from std::cin. For this we will use std::getline
Next we define a "counter" as an array. We assume that a char is 8bit wide and with that the maximum number of characters is 256
We positively count all character occurences of the first string
Now we do the comparison and counting in one step, by decrementing the counter for each occurence of a character in the 2nd string
Then we accumulate all counters (for all occurences of characters). We use the absolute value, because numbers could be negative.
Then we have the result.
Please note, you would need an array size of 26 counters only, because the requirements state an input range for 'a'-'z' for the charachters of the strings. But then we would need to map the charachter values for 'a'-'z' to indices 0-25, by subtracting always 'a' from a character. But with a little bit waste of space (230bytes), we can omit the subtraction.
Please see:
#include <iostream>
#include <string>
int main() {
// Here we will store the input, 2 strings to check
std::string a{}, b{};
// Read the strings from std::cin
std::getline(std::cin, a);
std::getline(std::cin, b);
// Here we will count the occurence of characters.
//We assume a char type with a width of 8 bit
int counter[256]{};
// Count occurence of characters in string a
// And Count occurence of characters in string b negatively
for (const char c : a) ++counter[c];
for (const char c : b) --counter[c];
// Calculate result
int charactersToDeleteForAnagram{};
for (int c : counter) charactersToDeleteForAnagram += std::abs(c);
std::cout << charactersToDeleteForAnagram << '\n';
return 0;
}
We can also convert to C++, where we use input checking, a std::unordered_map for counting and std::accumulate for summing up. Also the internal representation of a char-type doesn'matter. And the principle is the same.
I do not know, if this is that much slower . . .
Please see:
#include <iostream>
#include <string>
#include <unordered_map>
#include <numeric>
int main() {
// Here we will store the input, 2 strings to check
std::string aString{}, bString{};
// Read the strings from std::cin
if (std::getline(std::cin, aString) && std::getline(std::cin, bString)) {
// Here we will count the occurence of characters.
//We assume a char type with a width of 8 bit
std::unordered_map<char, int> counter{};
// Count occurence of characters in string a
// And Count occurence of characters in string b negatively
for (const char character : aString) counter[character]++;
for (const char character : bString) counter[character]--;
// Calculate result and show to user
std::cout << std::accumulate(counter.begin(), counter.end(), 0U,
[](size_t sum, const auto& counter) { return sum + std::abs(counter.second); }) << '\n';
}
else std::cerr << "\nError: Problem with input\n";
return 0;
}
If you should have any question, then please ask.
Language: C++ 17
Compiled and tested with MS Visual Studio 2019 Community Edition

Arranging odd and even numbers in a vector C++

I have this problem: Given a vector with n numbers, sort the numbers so that the even ones will be on odd positions and the odd numbers will be on even positions. E.g. If I have the vector 2 6 7 8 9 3 5 1, the output should be 2 7 6 9 8 3 5 1 . The count should start from 1. So on position 1 which is actually index 0 should be an even number, on position 2 which is actually index 1 should be an odd number and so on. Now this is easy if the odd and even numbers are the same, let's say 4 even number and 4 odd numbers in the vector, but what if the number of odd numbers differs from the number of even numbers like in the above example? How do I solve that. I attached the code with one of the tries I did, but it doesn't work. Can I get some help please. I ask you to keep it simple that means only with vectors and such. No weird methods or anything cause I'm a beginner and I only know the basics. Thanks in advance!
I have to mention that n initial is globally declared and is the number of vector elements and v_initial is the initial vector with the elements that need to be rearranged.
The task says to add the remaining numbers to the end of the vector. Like if there are 3 odd and 5 even numbers, The 2 extra even numbers should be thrown at the end of the vector
void vector_pozitii_pare_impare(int v_initial[])
{
int v_pozitie[50],c1=0,c2=1;
for (i = 0; i < n_initial; i++)
{
if (v_initial[i] % 2 == 0)
{
bool isTrue = 1;
for (int k = i + 1; k < n_initial; k++)
{
if (v_initial[k] % 2 != 0)
isTrue = 0;
}
if (isTrue)
{
v_pozitie[c1] = v_initial[i];
c1++;
}
else
{
v_pozitie[c1] = v_initial[i];
c1 += 2;
}
}
else
{
bool isTrue = 1;
for (int j = i + 1; j < n_initial; j++)
{
if (v_initial[j] % 2 == 0)
{
isTrue = 0;
}
if (isTrue)
{
v_pozitie[c2] = v_initial[i];
c2++;
}
else
{
v_pozitie[c2] = v_initial[i];
c2 += 2;
}
}
}
}
This may not be a perfect solution and it just popped out right off my mind without being tested or verified, but it's just to give you an idea.
(Let A,B,C,D be odd numbers and 0,1,2 even numbers correspondingly)
Given:
A 0 B C D 1 2 (random ordered list of odd/even numbers)
Wanted:
A 0 B 1 C 2 D (input sequence altered to match the wanted odd/even criteria)
Next, we invent the steps required to get from given to wanted:
// look at 'A' -> match, next
// Result: A 0 B C D 1 2
// look at '0' -> match, next
// Result: A 0 B C D 1 2
// look at 'B' -> match, next
// Result: A 0 B C D 1 2
// look at 'C' -> mismatch, remember index and find first match starting from index+1
// Result: A 0 B C D ->1<- 2
// now swap the numbers found at the remembered index and the found one.
// Result: A 0 B 1 D C 2
// continue until the whole list has been consumed.
As I said, this algorithm may not be perfect, but my intention is to give you an example on how to solve these kinds of problems. It's not good to always think in code first, especially not with a problem like this. So you should first think about where you start, what you want to achieve and then carefully think of how to get there step by step.
I feel I have to mention that I did not provide an example in real code, because once you got the idea, the execution should be pretty much straight forward.
Oh, and just a small remark: Almost nothing about your code is C++.
A simple solution, that is not very efficient would be to split the vector into 2 vectors, that contain even and uneven numbers and then always take one from the even, one from the uneven and then the remainder, from the one that is not completely entered.
some c++ (that actually uses vectors, but you can use an array the same way, but need to change the pointer arithmetic)
I did not test it, but the principle should be clear; it is not very efficient though
EDIT: The answer below by #AAAAAAAAARGH outlines a better algorithmic idea, that is inplace and more efficient.
void change_vector_even_uneven(std::vector<unsigned>& in_vec){
std::vector<unsigned> even;
std::vector<unsigned> uneven;
for (auto it = in_vec.begin(); it != in_vec.end(); it++){
if ((*it) % 2 == 0)) even.push_back(*it);
else uneven.push_back(*it);
}
auto even_it = even.begin();
auto uneven_it = uneven.begin();
for (auto it = in_vec.begin(); it != in_vec.end(); it++){
if (even_it == even.end()){
(*it) = (*uneven_it);
uneven_it++;
continue;
}
if (uneven_it == uneven.end()){
(*it) = (*even_it);
even_it++;
continue;
}
if ((it - in_vec.begin()) % 2 == 0){
(*it) = (*even_it);
even_it++;
}
else{
(*it) = (*uneven_it);
uneven_it++;
}
}
}
The solutions is simple. We sort the even and odd values into a data structure. In a loop, we iterate over all source values. If they are even (val & 2 == 0) we add them at the end of a std::deque for evens and if odd, we add them to a std::deque for odds.
Later, we we will extract the the values from the front of the std::deque.
So, we have a first in first out principle.
The std::deque is optimized for such purposes.
Later, we make a loop with an alternating branch in it. We, alternatively extract data from the even queue and then from the odd queue. If a queue is empty, we do not extract data.
We do not need an additional std::vector and can reuse the old one.
With that, we do not need to take care for the same number of evens and odds. It will of course always work.
Please see below one of millions of possible solutions:
#include <iostream>
#include <vector>
#include <deque>
int main() {
std::vector testData{ 2, 6, 7, 8, 9, 3, 5, 1 };
// Show initial data
std::cout << "\nInitial data: ";
for (const int i : testData) std::cout << i << ' ';
std::cout << '\n';
// We will use a deques to store odd and even numbers
// With that we can efficiently push back and pop front
std::deque<int> evenNumbers{};
std::deque<int> oddNumbers{};
// Sort the original data into the specific container
for (const int number : testData)
if (number % 2 == 0)
evenNumbers.push_back(number);
else
oddNumbers.push_back(number);
// Take alternating the data from the even and the odd values
bool takeEven{ true };
for (size_t i{}; !evenNumbers.empty() && !oddNumbers.empty(); ) {
if (takeEven) { // Take even numbers
if (not evenNumbers.empty()) { // As long as there are even values
testData[i] = evenNumbers.front(); // Get the value from the front
evenNumbers.pop_front(); // Remove first value
++i;
}
}
else { // Now we take odd numbers
if (not oddNumbers.empty()) { // As long as there are odd values
testData[i] = oddNumbers.front(); // Get the value from the front
oddNumbers.pop_front(); // Remove first value
++i;
}
}
// Next take the other container
takeEven = not takeEven;
}
// Show result
std::cout << "\nResult: ";
for (const int i : testData) std::cout << i << ' ';
std::cout << '\n';
return 0;
}
Here is yet another solution (using STL), in case you want a stable result (that is, the order of your values is preserved).
#include <algorithm>
#include <vector>
auto ints = std::vector<int>{ 2, 6, 7, 8, 9, 3, 5, 1 };
// split list to even/odd sections -> [2, 6, 8, 7, 9, 3, 5, 1]
const auto it = std::stable_partition(
ints.begin(), ints.end(), [](auto value) { return value % 2 == 0; });
auto results = std::vector<int>{};
results.reserve(ints.size());
// merge both parts with equal size
auto a = ints.begin(), b = it;
while (a != it && b != ints.end()) {
results.push_back(*a++);
results.push_back(*b++);
}
// copy remaining values to end of list
std::copy(a, it, std::back_inserter(results));
std::copy(b, ints.end(), std::back_inserter(results));
The result ist [2, 7, 6, 9, 8, 3, 5, 1]. The complexity is O(n).
This answer, like some of the others, divides the data and then reassembles the result. The standard library std::partition_copy is used to separate the even and odd numbers into two containers. Then the interleave function assembles the result by alternately copying from two input ranges.
#include <algorithm>
#include <iostream>
#include <vector>
template <typename InIt1, typename InIt2, typename OutIt>
OutIt interleave(InIt1 first1, InIt1 last1, InIt2 first2, InIt2 last2, OutIt dest)
{
for (;;) {
if (first1 == last1) {
return std::copy(first2, last2, dest);
}
*dest++ = *first1++;
if (first2 == last2) {
return std::copy(first1, last1, dest);
}
*dest++ = *first2++;
}
}
void reorder_even_odd(std::vector<int> &data)
{
auto is_even = [](int value) { return (value & 1) == 0; };
// split
std::vector<int> even, odd;
std::partition_copy(begin(data), end(data), back_inserter(even), back_inserter(odd), is_even);
// merge
interleave(begin(even), end(even), begin(odd), end(odd), begin(data));
}
int main()
{
std::vector<int> data{ 2, 6, 7, 8, 9, 3, 5, 1 };
reorder_even_odd(data);
for (int value : data) {
std::cout << value << ' ';
}
std::cout << '\n';
}
Demo on Compiler Explorer
As suggested, I am using vectors and STL.
No need to be a great mathematician to understand v_pozitie will start with pairs of odd and even and terminate with the integers not in the initial pairs.
I am then updating three iterators in v_positie (no need of temporary containers to calculate the result) : even, odd and end,(avoiding push_back) and would code this way :
#include <vector>
#include <algorithm>
void vector_pozitii_pare_impare(std::vector<int>& v_initial, std::vector<int>& v_pozitie) {
int nodd (0), neven (0);
std::for_each (v_initial.begin (), v_initial.end (), [&nodd] (const int& n) {
nodd += n%2;
});
neven = v_initial.size () - nodd;
int npair (neven < nodd ?neven:nodd);
npair *=2;
std::vector<int>::iterator iend (&v_pozitie [npair]), ieven (v_pozitie.begin ()), iodd (&v_pozitie [1]);
std::for_each (v_initial.begin (), v_initial.end (), [&iend, &ieven, &iodd, &npair] (const int& s) {
if (npair) {
switch (s%2) {
case 0 :
*ieven++ = s;
++ieven;
break;
case 1 :
*iodd++ = s;
++iodd;
break;
}
--npair;
}
else *iend++ = s;
});
}
int main (int argc, char* argv []) {
const int N = 8;
int tab [N] = {2, 6, 7, 8, 9, 3, 5, 1};
std::vector<int> v_initial (tab, (int*)&tab [N]);
std::cout << "\tv_initial == ";
std::for_each (v_initial.begin (), v_initial.end (), [] (const int& s) {std::cout << s << " ";});
std::cout << std::endl;
std::vector<int> v_pozitie (v_initial.size (), -1);
vector_pozitii_pare_impare (v_initial, v_pozitie);
std::cout << "\tv_pozitie == ";
std::for_each (v_pozitie.begin (), v_pozitie.end (), [] (const int& s) {std::cout << s << " ";});
std::cout << std::endl;
}

Remove duplicates from input without use of any data structures

Disclaimer: This question is more of a challenge, and the post is also quite long. Read only in free time!
The Problem:
Basically, suppose there is a single line of integer inputs:
32352\n // assuming single digits only and no spaces for simplification
We have to remove duplicates from the inputs, and then display them. So, output should be:
After removing duplicates: 2, 3, 5 // display them in any order
However, there is a catch:
Do not use any data structures containers.
Edit: I believe containers are what I meant (thanks Vlad!).
So, my question is: What is the error in my implementation, and is there another (better) way to do it?
My thought process:
Since we are not allowed use of any data structure, we cannot store the inputs (I think?).
However, since it is already stored in memory on input, that is not a problem.
More of a problem is removing the duplicates. We will have to manipulate the input stream.
The first thing that struck me is that we can sort the inputs. That is,
32352
becomes:
22335
And now, simply print the first element of each range.
Working on this idea, I came across the std::cin.get() and std::cin.putback() methods, both accepting a char.
I also realized I would have to use recursion.
And hence, the code becomes (I have used insertion sort):
The Code:
The sort() function is where the error is. It uses a running index ala arrays, and this is used to uniquely identify each element.
In each iteration, the index_of_element element is found and selected, and we determine where in the remaining (virtual) array, we need to place it. For example, if in our original input:
32352 // S = sorted subarray
SU--U // U = unsorted subarray
, the first 2 is selected, we "shift" 3 (as 3 < 2).
Now, there are no more elements left to shift, we "place" 2.
The result should become:
23352
SSU-U
The (buggy) implementation:
bool sort(int index_of_element, int index = 0, char prev_element = 0)
{
static char element;
char digit;
// retrieve an element from memory
std::cin.get(digit);
// If not end of input
if(digit != '\n')
{
// store the element for comparision
if(index == index_of_element)
{
element = digit;
}
// continue forward until '\n'
bool result = sort(index_of_element, index + 1, digit);
// if we are in sorted subarray
if(index <= index_of_element)
{
// If element belongs here(also if this is first element(prev_element is 0)), place it
if(element > prev_element)
{
digit = element;
// Signal that element has been placed
element = 0;
}
// Else, if element not already placed, we need to shift elements
else if(element != 0)
{
// Place the previous element here
digit = prev_element;
}
}
// Put it back in memory
std::cin.putback(digit);
// And return the result
return result;
}
// Which is generated here when end of input is reached
else
{
// If sorted all elements, break loop
if(index_of_element == index)
{
return false;
}
// Else, continue sorting
else
{
return true;
}
}
}
(A wall of code, but I didn't want to skip anything relevant), and it should be used as:
...
int index_of_element = 0;
while(sort(index_of_element++));
...
The display function is ready, and it works properly.
What I do know is that it gets stuck in an infinite loop and the values are lost.
What is going wrong?
And should I add the output (The post is already very long)?
The problem seems to be that you don't put the newline back into the stream, while your code assumes that it will be there.
That is, after your first pass, digit != '\n' is always true.
Put the newline back into the stream, or break when you've reached the true end-of-stream.
(There could also be problems with (ab)using std::cin like this, but I'm not sure, and that's another matter anyway.)
You can do it with only function objects, in a single pass.
#include <iostream>
#include <sstream>
#include <functional>
void print_unique_ints(std::istream & in, std::ostream & out, std::function<bool(int)> unseen) {
for (int i; in >> i;) {
if (unseen(i)) {
out << i << ' ';
print_unique_ints(in, out, [&](int j){ return (i != j) && unseen(j); });
return; // not actually needed, previous call only ends when input is exhausted
}
}
}
int main() {
print_unique_ints(std::cin, std::cout, [](int){ return true; });
}
See it live
Each call to print_unique_ints skips previously seen ints, prints the unseen int, and adds to the filter
Substituting values for variables; and function calls for expressions; in the first call
for (int i; in >> i;) { // i = 3
if (true) {
out << 3 << ' ';
print_unique_ints(...) // see below
}
}
The second
for (int i; in >> i;) { // i = 2
if ((3 != i) && true) {
out << 2 << ' ';
print_unique_ints(...) // see below
}
}
The third
for (int i; in >> i;) { // i = 3, 5
if ((2 != i) && (3 != i) && true) { // skips over the 3
out << 5 << ' ';
print_unique_ints(...) // see below
}
}
The forth
for (int i; in >> i;) { // i = 2
if ((5 != i) && (2 != i) && (3 != i) && true) { // skips the 2 and finds the end of input
}
}
Note that && true never changes the result in the if
A variation of bitset (or mask) implem...using the commutative property of multiplication
Take a function f which maps every digit to a unique prime p_i
0 1 2 3 4 5 6 7 8 9
2,3,5,7,9,11,13,17,19,23
If all numbers are found the total amount to N=2*3*5*7*9*11*13*17*19*23=2007835830
Consume cin as c, if f(c) divides N, print c and update N /= f(c)
#include <iostream>
#include <sstream>
int f(char c){
if(c=='0') return 2;
if(c=='1') return 3;
if(c=='2') return 5;
if(c=='3') return 7;
if(c=='4') return 9;
if(c=='5') return 11;
if(c=='6') return 13;
if(c=='7') return 17;
if(c=='8') return 19;
if(c=='9') return 23;
}
int main() {
std::istringstream in("2 2 2 3 5");
int N = 2007835830;
char c;
while(in >> c){
if(c=='\n') break;
int p_i = f(c);
if(N % p_i == 0){
N = N/p_i;
std::cout<<c<<" ";
}
}
}
I am sure that this phrase
Remove duplicates from input without use of any data structures
means that you shall not use any container like for example std::string or an ordinary array.
The assignment is not simple for a beginner.
Here are my five cents.
#include <iostream>
#include <type_traits>
template <typename T>
T remove_duplicates( T n )
{
static_assert ( std::is_integral<T>::value );
const T Base = 10;
T result = n % Base;
for ( T multiplier = 1; n /= Base; )
{
T digit = n % Base;
T tmp = result;
bool unique = true;
while ( ( unique = tmp % Base != digit ) && ( tmp /= Base ) );
if ( unique )
{
multiplier *= Base;
result = digit == 0 ? result * multiplier + digit
: digit * multiplier + result;
}
}
return result;
}
int main()
{
for ( int n : { 0, 1, 10, 101, 100, 10203, -1, -10, -101, -100, - 10203 } )
{
std::cout << n << ": " << remove_duplicates( n ) << '\n';
}
return 0;
}
The program output is
0: 0
1: 1
10: 10
101: 10
100: 10
10203: 1230
-1: -1
-10: -10
-101: -10
-100: -10
-10203: -1230
That is you are building a new number from the source number by checking whether the new number already contains a digit from the source number.
The function can work with any integer type signed or unsigned. It correctly processes digits equal to 0.
It was said not to use any arrays, vectors, stacks, queues etc and neither our own implementations of it. I simplified the condition.
Well I've got bad news for you; this is not possible.
Given an input of length N you will need to somehow remember the previous N - 1 values to decide whether to print the Nth value or not. This is not possible with constant space.
So you need some data structure.
Now ...
Since we are not allowed use of any data structure, we cannot store the inputs (I think?).
However, since it is already stored in memory on input, that is not a problem.
So let's assume the existence of a (mutable) array of length N, containing the input values. Now we can solve this without using additional storage / data structures:
Select some value as special value
Iterate over the numbers until you find a value which is not that special value. print that value. Write the special value to the array where you found the value you just printed. finish iterating over the numbers, overwritte each occurrence of the just printed value with the special value.
repeat (from 2) until the input consists only of special values.
You just need to think about a way to handle the case where the special value was present in the input from the start.

How do you check if content of string starts with the content of another string?

I'm trying to figure out if there is a way to compare if a content of a string is the start of another string. For example, I want to know the number of strings that start with the string "c", in an array whose content's is [cowboy, air, cow, cat]. Using the compare function from the string library works fine. The issue is when instead of trying with "c", I try with "b" I get the same number of answers. I don't know the reason why, Does anybody have a suggestion on how to fix the problem? Here are the two versions that I have.
#include <iostream>
#include <string>
using namespace std;
int main() {
// insert code here...
string A[4] = {"cowboy", "air", "c", "count"};
string b = "c";
int count = 0;
for(int i = 0; i < 4; i++)
{
if(b.compare(A[i]) == 0 || b.compare(A[i]) == -1)
count++;
}
cout << count << endl;
}
The output for this part is 3, which is right
#include <iostream>
#include <string>
using namespace std;
int main() {
// insert code here...
string A[4] = {"cowboy", "air", "c", "count"};
string b = "b";
int count = 0;
for(int i = 0; i < 4; i++)
{
if(b.compare(A[i]) == 0 || b.compare(A[i]) == -1)
count++;
}
cout << count << endl;
}
The output for this part is also 3, which is wrong.
Any help would be really appreciated!
There is an overload of the compare function which accepts position and a length, and compares only a part of the string to the other string. If you pass 0 for the position, and the size of the string you are searching for as the length, it will only compare that many characters at the start of the string, instead of comparing the whole thing.
if(A[i].compare(0, b.size(), b) == 0)
count++;
By the way, the only reason your first test appeared to be working, was that you were basically checking if "c" is lexicographically less than or equal to your target strings. And since that is the case for "cowboy", "c" and "count", but not "air", your result was 3. But if you added a string like, "direwolf", which comes lexicographically after "c", but does not start with "c", you would find that your results were not what you are expecting.
You can try using the find function:
string A[4] = {"cowboy", "air", "c", "count"};
string b = "b";
int count = 0;
for(int i = 0; i < 4; i++)
{
auto found = A[i].find(b);
if(found != string::npos && found == 0)
count++;
}
cout << count << endl;
What I do here is find b in A[i], if I get npos which means it wasn't found if I do find it, I check if its at the start by checking found == 0
Similarly to simplify if I only want to check for just a character match at the start I could simply A[i] == b[0]
Live Demo
Replace your if condition with the following. This compares the string b with A[i]'s 1st character.
if(b.compare(0, A[i].length(), A[i], 0, 1) == 0)
In your for loop when you pass in b = "c" the first conditions satisfies b.compare(A[i]) == 0 and for b="a" second condition satisfies. So in both cases you see 3.
You can do it easily by changing string b to character b and then checking if the first letter of each string in the array is equal to b or not and incrementing the count when they are equal.

Compare all values of a array with a value from another array with C++

I have to compare two arrays, i need to know if the same name of a value in the other array exists. My problem is that it always returns only one matched value but there are two with the same name.
One array is 9 length big the other 3.
Is there maybe an easier solution because mine looks a little bit too complex, am I right?
Thank you in advance
Here is my Code:
for (int i=0;i<9;i++ )
{
int counter = 0;
int j = 0;
if (stockTest[j].getTestTitle() == products[i].getTitle())
{
cout << stockTest[j].getTestTitle() << " is available ";
counter = counter + 1; // counter + 1 because it is available
}
if ((j == 0) && (counter == 0) && (i == 9)) // try everything till i is 9 if counter is still 0 display message.
{
cout << stockTest[j].getTestTitle() << " is not available ";
}
if ((j == 1) && (counter == 0) && (i == 9)) // compare everything from stockTest[1], till i is 9 if counter is still 0 display message.
{
cout << stockTest[j].getTestTitle() << " is not available ";
}
if ((j == 2) && (counter == 0) && (i == 9)) //compare everything from stockTest[2], till i is 9 if counter is still 0 display message.
{
cout << stockTest[j].getTestTitle() << " is not available ";
}
if ( i == 9)
{
j = j + 1; //there are three values to compare in the other array so I will increment like this till 2 (the next if statement will end the loop if j == 2)
i = 0; // i again 0 so that again all 9 values from the array will be compared
counter = 0; // counter = 0 so that if the value is not found the counter == 0 is true
}
if ((j == 2) && ( i = 9 ))
i = 9; //i is now 9 which means that loop should end now however I can delete this line of code and the program would still display only one value. I expected an infinte loop if i delete it?
}
If the arrays can be sorted on title, then one solution would be to use std::set_intersection.
Pre C++ 11 code:
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <string>
#include <ostream>
struct stockTest
{
std::string title;
std::string getTitle() const { return title; }
stockTest(const std::string s) : title(s) {}
friend std::ostream& operator << (std::ostream& os, const stockTest&);
};
// for output purposes
std::ostream& operator << (std::ostream& os, const stockTest& s)
{
os << s.getTitle();
return os;
}
// compares two stockTest items
bool Comparer(const stockTest& f1, const stockTest& f2)
{
return f1.getTitle() < f2.getTitle();
}
using namespace std;
int main()
{
stockTest s1[] = {stockTest("abc"), stockTest("123"), stockTest("456")};
stockTest s2[] = {stockTest("123"), stockTest("Joe"), stockTest("789"), stockTest("456")};
// first, we sort our arrays
std::sort(s1, s1 + 3, Comparer);
std::sort(s2, s2 + 4, Comparer);
// this vector will contain the similar items
std::vector<stockTest> v_intersection;
// use set_intersection to do the hard work
std::set_intersection(s1, s1 + 3, s2, s2 + 4, std::back_inserter(v_intersection), Comparer);
// output the results
cout << "The similar names are: " << endl;
copy(v_intersection.begin(), v_intersection.end(), ostream_iterator<stockTest>(cout, "\n"));
}
Note that at the end, we created a vector that contains the common names. Also note that we had to sort the arrays first, plus provide set_intersection to know how the items are sorted (according to the Comparer functor).
Live Example: http://ideone.com/GA8ey0
First, you reinitialize counter to 0 every iteration of the first loop which probably has something to do with it.
Second, i would do something like the following with two for loops:
int counter = 0;
for(int i = 0; i<3; i++)
{
for(int j=0; j<9; j++)
{
if(array1[i] == array2[j])
{
counter++;
}
}
}
It is difficult to follow your logic as im not sure what you're using counter for or why (but breaking it down to simplicity, it is just a counter that stores how many times an equivalent value has been matched. Lets not over complicate it).
So its just a simple outer and inner for loop where you iterate and compare all 9 values of the second array to each value of the first array (3 values). I hope this helps.