Checking if characters length in string is same or not - c++

I am trying to write a program that checks if characters of created word are in different length.
for example word:
PAABBBMMMM
it should print Yes, because P was printed 1 time, A was printed 2 times, B was printed 3 Times, m was printed 4 times.
If the word was for e.g PAABB it should print no, because AA and BB is same length.
What I am doing wrong?
#include <iostream>
using namespace std;
bool checkChars(string s)
{
int n = s.length();
for (int i = 1; i < n; i++)
if (s[i] != s[0])
return false;
return true;
}
// Driver code
int main()
{
string s = "PAABBBMMMM";
if (checkChars(s))
cout << "Yes";
else
cout << "No";
return 0;
}

With the condition if (s[i] != s[0]), you're just checking if each character is equal to the first character, which makes no sense.
You can use a std::map to count the frequency of each character, then use std::set to check the uniqueness of each frequency:
#include <iostream>
#include <string>
#include <map>
#include <set>
bool checkChars(std::string s)
{
int n = s.length(); std::map<int, char> freq;
for (int i = 0; i < n; i++)
freq[s[i]]++;
std::set<int> Unique;
for (auto it = freq.begin(); it!=freq.end(); it++)
Unique.insert(it->second);
if (Unique.size() != freq.size()) {return false;}
return true;
}
// Driver code
int main()
{
std::string s = "PAABBBMMMM";
if (checkChars(s))
std::cout << "Yes";
else
std::cout << "No";
return 0;
}
Result: Yes
Other example:
"AABB" -> No
"MABAAB" -> Yes
Also see Why is "using namespace std;" considered bad practice?

Related

Compare vector<string> and print yes or no using c++

I have two string vectors a and b with a[0]="hello",a[1]="world",b[0]="heyyy"and b[1]="namaste" and i have to decide whether the following a[0] and b[0] has anything matching and a[1] and b[1] has anything matching. If a[0] and b[0] has one or more characters matching then print "YES", else print "NO". Similarly if a[1] and b[1] has one or more characters matching then print "YES", else print "NO". For example from the above information, a[0] and b[0] have 'h' and 'e' as matching and a[1] and b[1] has no character matching. At the end, the expected output is
"YES"
"NO"
Based on the above information, being a beginner in C++ i developed a C++ program which is not even partially correct. It would be great if someone solve this. Thanks in advance.
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int main()
{
std::vector<string>a,b;
a={"hello", "world"};
b={"heyyy", "namaste"};
const char* acstr;
const char* bcstr;
acstr = a[0].c_str();
bcstr = b[0].c_str();
for(int i=0;i<sizeof(acstr);i++)
{
for(int j=0;j<sizeof(bcstr);j++)
{
if(acstr[i]==bcstr[j])
{
cout << "YES";
}
else{
continue;
}
}
}
return 0;
}
There is no need to convert an object of the type std::string to pointer like
acstr = a[0].c_str();
Also in this loop
for(int i=0;i<sizeof(acstr);i++)
the expression sizeof(acstr) does not give the length of the pointed string. It gives the size of the pointer itself that depending on the used system can be equal to 4 or 8 bytes independent on the length of the pointed string.
In general the vectors can have different number of elements. So you need to use the size of the smallest vector in a loop.
To determine whether a character is present in a string you can use method find of the class std::string.
Here is a demonstrative program.
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
int main()
{
std::vector<std::string> v1 = { "hello", "world" };
std::vector<std::string> v2 = { "heyyy", "namaste" };
std::vector<std::string>::size_type n = std::min( v1.size(), v2.size() );
for ( std::vector<std::string>::size_type i = 0; i < n; i++ )
{
std::string::size_type j = 0;
while ( j < v1[i].size() && v2[i].find( v1[i][j] ) == std::string::npos )
{
++j;
}
std::cout << ( j == v1[i].size() ? "NO" : "YES" ) << '\n';
}
return 0;
}
Its output is
YES
NO
Maybe you want like:
#include <bits/stdc++.h> // do not use this header
using namespace std;
int main()
{
std::vector<string>a, b;
a = { "hello", "world" };
b = { "heyyy", "namaste" };
for (int i = 0; i < (int)a.size(); i++)
{
bool bFound = false;
for (int j = 0; j < min(a[i].length(), b[i].length()); j++)
{
if (a[i][j] == b[i][j])
{
bFound = true;
}
}
cout << (bFound ? "YES" : "NO") << endl;
}
return 0;
}
Some advices:
You don't have to use c_str() to do character comparison.
sizeof(const char*) doesn't give you length of string. use strlen(const char*) if you want.
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int main()
{
int flag = 0;
std::vector<string>a,b;
a={"hello", "world"};
b={"heyyy", "namaste"};
for(int k=0;k<2;k++){ //You can find and put the length of a or b, instead of using 2
for(int i=0;i<a[k].length();i++)
{
for(int j=0;j<b[k].length();j++)
{
if(a[k][i]==b[k][j])
{
flag = 1;
}
}
}
if(flag == 1){
cout << "YES\n";
}else{
cout << "NO\n";
}
flag = 0;
}
return 0;
}

Displaying all prefixes of a word in C++

I am trying to do is display all the suffixes of a word as such:
word: house
print:
h
ho
hou
hous
house
What I did is:
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
char cuvant[100];
int i,k;
cin>>cuvant;
for(i=0;i<strlen(cuvant);i++)
{
for(k=0;k<i;k++)
{
if(k==0)
{
cout<<cuvant[k]<<endl;
}else
{
for(k=1;k<=i;k++){
if(k==i) cout<<endl;
cout<<cuvant[k];
}
}
}
}
}
What am I doing wrong?
You're over-complicating it. Here's a simpler way:
#include <iostream>
#include <string>
#include <string_view>
int main() {
std::string s;
std::cin >> s;
for (std::string::size_type i = 0, size = s.size(); i != size; ++i)
std::cout << std::string_view{s.c_str(), i + 1} << '\n';
}
If you don't have access to a C++17 compiler, you can use this one:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>
int main() {
std::string s;
std::cin >> s;
for (auto const& ch : s) {
std::copy(s.c_str(), (&ch + 1),
std::ostream_iterator<decltype(ch)>(std::cout));
std::cout << '\n';
}
}
Even so, I think it would be better for your learning progress to use a debugger to finger out the problem yourself. Here the problems with your code:
For the i=0 (the first iteration of your outer loop) the for(k=0;k<i;k++) will not be executed at all, as k<0 evaluates to false.
And having a running variable (k) that you change in two for loops that are nested, is most of the time also an indication that something is wrong.
So what you want to do: You want to create each possible prefix, so you want to create n strings with the length of 1 to n. So your first idea with the outer loop is correct. But you overcomplicate the inner part.
For the inner part, you want to print all chars from the index 0 up to i.
int main() {
char cuvant[100];
std::cin >> cuvant;
// loop over the length of the string
for (int i = 0, size = strlen(cuvant); i < size; i++) {
// print all chars from 0 upto to i (k<=0)
for (int k = 0; k <= i; k++) {
std::cout << cuvant[k];
}
// print a new line after that
std::cout << std::endl;
}
}
But instead of reinventing the wheel I would use the functions the std provides:
int main() {
std::string s;
std::cin >> s;
for (std::size_t i = 0, size = s.size(); i < size; i++) {
std::cout << s.substr(0, i + 1) << std::endl;
}
}
For this very simple string suffix task you can just use:
void main()
{
std::string s = "house";
std::string s2;
for(char c : s)
{
s2 += c;
cout << s2 << endl;
}
}
For more complicated problems you may be interested to read about Suffix Tree
Your code is wrong, the following code can fulfill your requirements
#include <iostream>
using namespace std;
int main()
{
char cuvant[100];
int i,k;
cin>>cuvant;
for(i=0;i<strlen(cuvant);i++)
{
for (k = 0; k <= i; ++k)
{
cout<<cuvant[k];
}
cout<<endl;
}
}

C++ How to find out most consecutive digits in an array?

Hi guys I'm trying to write a code where when i type a binary string I need to mind the most consecutive numbers of occurrence 1 has occurred. For example, if i type 00111001, it should be 3, 1100111011111, it should be 5 etc. This is my code so far.
int main () {
string s1;
cin >> s1;
int l1=s1.size()-1; // length-1 hence the for loop array doesnt go out of bounds
int max=0; // this tells us the max number of occurrence
int count=0;
for (int i=0;i<l1;i++) {
if (s1[i]=='1' && s1[i+1]=='1') { // if s[0] and s[1] are both 1, it adds 1
count++;}
if (count>0 && count>max)
{max=count; // storing the count value in max.
}
if (s1[i]=='0' || s1[i+1]=='0'){ //resetting count if it encounters 0
count=0;
}
}
max=max+1;
cout << max << '\n' << endl;
The issue is if I write 1111001 it runs (I get 4), but when i type 1100111001 I get 2. Don't get why there's ambiguity. Please let me know what I need to do
Thanks
I'd only increment the count in case of 1, and zero it when 0 is reached.
whenever count is bigger than max, assign count to max and that's it.
btw, I get 3 for the input 1100111001 with your program.
#include <iostream>
using namespace std;
int main() {
string s1;
cin >> s1;
int l1 = s1.size();
int max = 0;
int count = 0;
for (int i = 0; i < l1; i++)
{
if (s1[i] == '1')
{
count++;
}
else
{
count = 0;
}
if (count > max)
{
max = count;
}
}
cout << max << '\n' << endl;
}
Let's solve this using find, given string s1 which contains your input string you can just do:
auto max = 0;
for(auto start = find(cbegin(s1), cend(s1), '1'); start != cend(s1); start = find(start, cend(s1), '1')) {
const auto finish = find(start, cend(s1), '0');
const auto count = distance(start, finish);
if(count > max) {
max = count;
}
start = finish;
}
Live Example
I want to offer you such an option for calculating through tokens and sorting:
#include <string>
#include <vector>
#include <sstream>
#include <algorithm>
using namespace std;
int main()
{
string s1;
cin>>s1;
istringstream s(s1);
vector<string> result;
while (std::getline(s,s1,'0')) {
result.push_back(s1);
}
sort(result.begin(),result.end(),[](const string &a, const string &b){ return a.length()>b.length();});
cout << result.at(0).length() << endl;
return 0;
}

How to print frequency of each letter in a string in descending order c++?

#include <iostream>
#include <string>
using namespace std;
int main () {
int cnt[26] {};
char alpha[26];
string s = "abcdefffggghiii";
for (int i = 0; i < s.length(); i++) {
cnt[s[i] - 'a']++;
}
for (int i = 'a'; i <= 'z'; i++) {
alpha[i - 'a'] = i;
}
for (int i = 0; i < 26; i++) {
if (cnt[i]) {
cout << alpha[i] << " " << cnt[i] << endl;
}
}
return 0;
}
I wanted to print the frequencies of each letter in the string in descending order. I've thought to sort the cnt array and print from 25 to 0 but it will only print the frequencies with wrong letter. How can I fix it to print for example i 3 and so on in descending order?
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
// Create result container
auto x = vector<pair<char, int>>();
std::string s = "abcdefffggghiii";
for (auto& l : s) {
// Find the item that corresponds to letter
auto pLetter =
find_if(x.begin(), x.end(), [&l](pair<char, int> &arg) {
return arg.first == l;
});
if (pLetter != x.end())
pLetter->second++; // If item corresponding to letter is found, increment count
else {
x.push_back(make_pair(l, 1)); // Otherwise, create a new result entry
}
}
// Sort results by count in descending order
std::sort(x.begin(), x.end(),
[](auto &left, auto &right) { return left.second > right.second; });
for (auto i = x.begin(); i != x.end(); ++i)
std::cout << i->first << ':' << i->second << '\n';
}
Produces
f:3
g:3
i:3
a:1
b:1
c:1
d:1
e:1
h:1
You can run it here. This uses C++14 lambdas for the find_if and sort predicates. This solution is very similar to #Retired Ninja's, except that the result vector contains items only for those letters that have non-zero counts. This means that it is extendable to wstrings without the need for a large result vector.
Here's how I might do it. You just need to keep the letter and the count together.
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
struct LetterFreq
{
char letter;
int freq;
};
int main()
{
std::vector<LetterFreq> cnt(26);
for (size_t i = 0; i < cnt.size(); ++i)
{
cnt[i].freq = 0;
cnt[i].letter = static_cast<char>(i) + 'a';
}
std::string s = "abcdefffggghiii";
for (auto& l : s)
{
cnt[l - 'a'].freq++;
}
std::sort(cnt.begin(), cnt.end(), [](const LetterFreq& lhs, const LetterFreq& rhs)
{
return lhs.freq > rhs.freq;
});
for (auto& item : cnt)
{
if (item.freq == 0)
{
break;
}
std::cout << item.letter << " : " << item.freq << "\n";
}
return 0;
}
This is simple if all you have it lowercase ASCII letters. For more complicated input you can use the same idea of the letter and count in a struct, but you'd either want to increase the size of the vector to 256 to keep track of all possibilities, or use something like an unordered map to only store used symbols and then copy them out into a container you can sort to display them. You could also use parallel arrays and while sorting swap the letter positions at the same time you're swapping the counts. There are many ways to handle this.
You could use pairs, but it looks like you're doing this with more basic types. In that case you might have to use nested loops. Keep finding the highest frequency character, print it, and then set its frequency to -1 to indicate that you've processed it already.

Arranging a string in uppercase-first alphabetical order C++

I was trying to create a program in C++ that sorts a given string in alphabetical order in a way where the uppercase letters precede their lowercase equivalent.
Example:
DCBAdcba
Sorted string:
AaBbCcDd
Given below is the code.
#include <iostream>
#include <string>
#include <cctype>
struct char_ {
char c;
char diff;
char_();
char_(char x);
};
char_::char_() {
c = 0;
diff = 0;
}
char_::char_(char x) {
c = std::tolower(x);
diff = c - x;
}
void charswap(char_& x, char_& y) {
char_ temp;
temp = x;
x = y;
y = temp;
}
int main() {
std::string str;
getline(std::cin, str);
char_* str2 = new char_[str.length()];
for (int i = 0; i < str.length(); i++) {
str2[i] = char_(str[i]);
}
/*
for (int i = 0; i < str.length(); i++) {
std::cout << str2[i].c << std::endl;
}
*/
for (int i = 0; i < str.length(); i++) {
for (int j = i; j < str.length(); j++) {
if (str2[i].c > str2[j].c)
charswap(str2[i], str2[j]);
}
}
for (int k = 0; k < str.length(); k++) {
std::cout << str2[k].c << "\t" << (int)str2[k].diff << std::endl;
}
for (int i = 0; i < str.length(); i++) {
str2[i].c = str2[i].c - str2[i].diff;
}
for (int i = 0; i < str.length(); i++) std::cout << str2[i].c;
std::cout << "\n";
return 0;
}
A char_ struct is created to store the individual characters(converted to to lowercase) and their difference from the uppercase equivalent(0 or 32, depending if the original char was lowercase or uppercase, respectively). It then sorts the char_ characters on the basis of their lowercase values. And after the sort we add back the difference to the character to retrieve the uppercase form.
But when I try giving this string, it gives the following result.
DCBAdcba
AabBCcdD
I cannot understand what's happening here.
The problem is on this line:
if (str2[i].c > str2[j].c)
charswap(str2[i], str2[j]);
It compares characters in case-insensitive way, with no provision for tie breaking when lowercase characters are the same.
You need to modify this to swap characters when lowercase on the right is greater than lowercase on the left, or when lowercase representations are the same, but the right side original character is in upper case:
if ((str2[i].c > str2[j].c) || (str2[i].c == str2[j].c && str2[j].diff))
charswap(str2[i], str2[j]);
sorts a given string in alphabetical order in a way where the uppercase letters precede their lowercase equivalent.
You can just define a comparison functor reflecting your intention
#include <cctype>
#include <iostream>
#include <vector>
#include <algorithm>
struct case_cmp {
bool operator()(char lhs, char rhs) const {
return (std::isupper(lhs) && std::tolower(lhs) == rhs) || std::tolower(lhs) < std::tolower(rhs);
}
};
Then use std::sort:
int main() {
std::string s("DCBAdcba");
std::sort(std::begin(s), std::end(s), case_cmp());
// Outputs "AaBbCcDd"
std::cout << s << std::endl;
}
std::string can be considered as a container of chars, and as such you can apply STL's algorithms to its content, including std::sort() (just like you would apply an STL algorithm to e.g. std::vector).
You can specify your particular custom sorting criteria using a lambda, to be passed as the third parameter to std::sort(), e.g. (live on Ideone):
#include <algorithm> // for std::sort
#include <cctype> // for std::isupper, std::tolower
#include <iostream> // for std::cout
#include <string> // for std::string
using namespace std;
int main() {
string s{"DCBAdcba"};
sort( s.begin(), s.end(), [](char x, char y) {
// Custom sorting criteria.
// Return true if x precedes y.
// This may work, but requires more testing...
if (isupper(x)) {
if (tolower(x) == y) {
return true;
}
}
return tolower(x) < tolower(y);
});
cout << s << '\n';
}